CN112631656A - 一种基于源代码的智能合约优化方法及装置 - Google Patents
一种基于源代码的智能合约优化方法及装置 Download PDFInfo
- Publication number
- CN112631656A CN112631656A CN202110013879.3A CN202110013879A CN112631656A CN 112631656 A CN112631656 A CN 112631656A CN 202110013879 A CN202110013879 A CN 202110013879A CN 112631656 A CN112631656 A CN 112631656A
- Authority
- CN
- China
- Prior art keywords
- optimized
- source code
- intelligent contract
- mode
- state variable
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/74—Reverse engineering; Extracting design information from source code
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
本发明公开了一种基于源代码的智能合约优化方法及装置,其中,方法包括:读取预设的智能合约的源代码,并将所述源代码转换为抽象语法树;在所述抽象语法树中检测具有预设的待优化模式的待优化源代码;优化所述待优化源代码,生成优化源代码;基于所述优化源代码生成优化智能合约,并对所述优化智能合约进行验证,当验证通过时,输出所述优化源代码。从而解决了现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
Description
技术领域
本发明涉及智能合约优化技术领域,尤其涉及一种基于源代码的智能合约优化方法及装置。
背景技术
智能合约是在区块链上运行的、分布式的、防篡改的程序。由于智能合约可以灵活地嵌入到各种数字资产中,以帮助实现安全有效的信息交换和价值转移,它为供应链、智能家居、电子商务和资产管理等不同行业和领域提供了巨大的机会。以太坊是第一个支持智能合约的区块链系统,吸引了许多开发人员。在以太坊推出的五年内,人们已经在以太坊上部署了超过1600万个智能合约。
智能合约通常以高级语言(例如Solidity)编写,然后编译为字节码,可以在以太坊虚拟机(EVM)中执行。字节码作为一种汇编语言,由多个操作码组成,每个操作码在区块链上执行特定的动作。智能合约在运行时需要消耗机器的计算资源,为了避免过度消耗资源并确保程序运行结束,用户使用智能合约时需要支付费用。对于费用的计算方法,以太坊采用了gas机制,执行每个操作码都会消耗一定数量的gas,gas是测量存储和计算资源消耗的特殊单位。以太坊黄皮书规定了每个操作码消耗的gas。用户需要支付的交易费用等于所使用的gas乘以gas价格,并且gas价格通常只在很小的范围内波动。换句话说,智能合约使用的gas越多,合约用户向矿工支付的交易费用就越高。此外,由于Solidity编译器优化不足,以及开发人员对gas机制的理解不足,因此智能合约的优化空间很大。因此,对智能合约进行等效转换的优化是有意义的,以便在不改变合约运行效果的前提下,可以生成节约gas的智能合约。对以太坊而言,优化智能合约的gas使用量可以降低存储压力,有利于可持续发展。对于智能合约的用户而言,gas优化可以降低部署和调用合约的成本,从而可以提高用户使用合约的热情。
现有的gas优化方法基于可满足性模理论,可在字节码级别检测并消除低效率的gas消耗模式。通过尝试所有可能的操作码序列来查找需要较少资源并且在语义上等同于原始程序的操作码序列。然而,字节码到字节码的转换使优化方法变得不透明,因为用户无法直观地知道优化器对合约进行了哪些更改。而且不透明性使用户在使用优化后的智能合约时感到焦虑,因为智能合约控制着他们的资产,并且在gas优化器中已经出现了安全漏洞。而且,由于这些方法基于表达和时间上受限的可取模理论,只能处理小范围的操作码序列(不包含跳转指令的操作码序列)。
发明内容
本发明提供了一种基于源代码的智能合约优化方法及装置,用于解决现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
本发明提供的一种基于源代码的智能合约优化方法,包括:
读取预设的智能合约的源代码,并将所述源代码转换为抽象语法树;
在所述抽象语法树中检测具有预设的待优化模式的待优化源代码;
优化所述待优化源代码,生成优化源代码;
基于所述优化源代码生成优化智能合约,并对所述优化智能合约进行验证,当验证通过时,输出所述优化源代码。
可选地,所述待优化模式包括稀疏存储模式;所述优化源代码包括第一优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,包括:
当检测到所述稀疏存储模式对应的第一待优化源代码时,在所述第一待优化源代码中提取状态变量定义顺序;
调整所述状态变量定义顺序,生成调整顺序;
当所述调整顺序对应的插槽数小于所述状态变量定义顺序对应的插槽数时,基于所述调整顺序生成所述第一优化源代码。
可选地,所述待优化模式还包括小变量模式;所述优化源代码还包括第二优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述小变量模式对应的第二待优化源代码时,将所述第二待优化源代码的变量类型转化为预设类型,生成所述第二优化源代码。
可选地,所述待优化模式还包括重复赋值模式;所述优化源代码还包括第三优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述重复赋值模式对应的第三待优化源代码时,从第三待优化源代码中提取声明赋值状态变量列表和构造函数赋值状态变量列表;
对比所述声明赋值状态变量列表和所述构造函数赋值状态变量列表,确定重复赋值状态变量;
删除所述重复赋值状态变量的声明赋值,生成所述第三优化源代码。
可选地,所述待优化模式还包括频繁使用状态变量模式;所述优化源代码还包括第四优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述频繁使用状态变量模式对应的第四待优化源代码时,获取所述第四待优化源代码中的循环状态变量;
采用预设局部变量替换所述循环状态变量,生成所述第四优化源代码。
可选地,所述待优化模式还包括未考虑短路规则模式;所述优化源代码还包括第五优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述未考虑短路规则模式对应的第五待优化源代码时,获取所述第五待优化源代码对应的逻辑操作的左操作数和右操作数;
当所述左操作数对应的gas消耗量大于所述右操作数对应的gas消耗量时,替换所述左操作数与所述右操作数的位置,生成所述第五优化源代码。
可选地,所述待优化模式还包括不准确的函数可见性模式;所述优化源代码还包括第六优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述不准确的函数可见性模式对应的第六待优化源代码时,从所述第六待优化源代码中提取未调用的公有函数;
调整所述未调用的公有函数的可见性,生成所述第六优化源代码。
可选地,所述基于所述优化源代码生成优化智能合约,并对所述优化智能合约进行验证,当验证通过时,输出所述优化源代码的步骤,包括:
基于所述优化源代码生成优化智能合约,并验证所述优化智能合约的第一操作行为与所述智能合约的第二操作行为是否一致;
若一致,则判定验证通过,输出所述优化源代码。
本发明还提供了一种基于源代码的智能合约优化装置,包括:
转换模块,用于读取预设智能合约的源代码,并将所述源代码转换为抽象语法树;
检测模块,用于在所述抽象语法树中检测具有预设的待优化模式的待优化源代码;
优化模块,用于优化所述待优化源代码,生成优化源代码;
验证模块,用于对优化后的智能合约进行验证,当验证通过时,输出所述优化源代码。
本发明还提供了一种电子设备,所述设备包括处理器以及存储器:
所述存储器用于存储程序代码,并将所述程序代码传输给所述处理器;
所述处理器用于根据所述程序代码中的指令执行如上任一项所述的基于源代码的智能合约优化方法。
从以上技术方案可以看出,本发明具有以下优点:本发明通过读取预设智能合约的源代码,并将源代码转换为抽象语法树;在抽象语法树中检测具有预设的待优化模式的待优化源代码;优化待优化源代码,生成优化源代码;对优化后的智能合约进行验证,当验证通过时,输出优化源代码。从而解决了现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其它的附图。
图1为本发明实施例提供的一种基于源代码的智能合约优化方法的步骤流程图;
图2为本发明另一实施例提供的一种基于源代码的智能合约优化方法的步骤流程图;
图3为本发明实施例提供的一种基于源代码的智能合约优化装置的结构框图。
具体实施方式
现有的gas优化方法基于可满足性模理论,可在字节码级别检测并消除低效率的gas消耗模式。通过尝试所有可能的操作码序列来查找需要较少资源并且在语义上等同于原始程序的操作码序列。然而,字节码到字节码的转换使优化方法变得不透明,因为用户无法直观地知道优化器对合约进行了哪些更改。而且不透明性使用户在使用优化后的智能合约时感到焦虑,因为智能合约控制着他们的资产,并且在gas优化器中已经出现了安全漏洞。而且,由于这些方法基于表达和时间上受限的可取模理论,只能处理小范围的操作码序列(不包含跳转指令的操作码序列)。例如,对于操作码序列<PUSH 0SUB PUSH 3ADD>,这些方法可以将其优化为<PUSH 3SUB>,这相当于将3+(0-x)优化为3-x。但是,由于片段的操作码序列太长,有些低效率的gas消耗的智能合约片段无法通过现有的gas优化方法在字节码级别上进行优化。如表1所示,表1中低效率的gas消耗模式表示无法通过现有方法优化的智能合约片段。在低效率的gas消耗模式的版本中,合约声明了一个状态变量num,并为该变量显式赋值了0,这符合一般的良好编程原则。合约中还包含了一个构造函数,该函数将输入参数x的值分配给变量num。然而,根据以太坊黄皮书规定,在合约被部署到区块链,创建状态变量后,构造函数将立即执行。即,无论在声明时将什么值赋值给变量,该值都将无效,低效率的gas消耗模式的版本中的显式赋值是多余的,这会浪费gas。如表1所示,高效率的gas消耗模式版本和低效版本几乎相同,不同之处在于高效版本中在声明变量num时未显式赋值,相对于低效率的gas消耗模式的版本,其明显节约了gas。但现有方法无法将代码a优化为代码b。
表1
有鉴于此,本发明实施例提供了一种基于源代码的智能合约优化方法及装置,用于解决现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
为使得本发明的发明目的、特征、优点能够更加的明显和易懂,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,下面所描述的实施例仅仅是本发明一部分实施例,而非全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本发明保护的范围。
请参阅图1,图1为本发明实施例提供的一种基于源代码的智能合约优化方法的步骤流程图。
本发明提供的一种基于源代码的智能合约优化方法,包括:
步骤101,读取预设的智能合约的源代码,并将源代码转换为抽象语法树;
智能合约:是在区块链上运行的程序,需要在被调用之前部署在区块链中。具体来说,智能合约创建者使用Solidity编写合约,将合约编译为EVM字节码,将包含字节码和合约构造函数参数的交易发送到最近的以太坊节点。通过网络共识流程,将合约部署在每个区块链节点上,并将合约地址返回给用户。任何人都可以调用部署在区块链中的智能合约。具体来说,合约调用者将包含合约地址,被调用函数的签名和输入参数的交易发送到最近的以太坊节点。由于字节码由多个操作码组成,因此运行智能合约等效于执行合约的字节码(操作码序列)中的每个操作码。
抽象语法树:是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
步骤102,在抽象语法树中检测具有预设的待优化模式的待优化源代码;
本发明实施例将部分低效率的gas消耗模式定义为待优化模式,当检测到智能合约中存在上述待优化模式时,可以提取待优化模式的待优化源代码,以对待优化源代码进行优化,从而完成对智能合约的优化。
gas:为了避免过多的资源消耗并确保终止,以太坊采用了gas机制,向交易发送者收取执行费。交易费用由gas价格×gas使用量来计算,其中术语gas是衡量存储和计算资源消耗的特殊单位。gas价格通常只在很小的范围内波动,每个操作码消耗的gas由以太坊的核心协议规定。表2列出了各种操作码所需的gas。值得注意的是,需要更多存储和计算资源的操作会消耗更多的gas。例如,操作码SSTORE需要5000或20000gas,用于访问存储。当存储值从非零设置为零时,它将花费20000gas。否则,它需要花费5000gas。操作码ADD需要3gas,用于算术运算。
表2
步骤103,优化待优化源代码,生成优化源代码;
根据待优化源代码对应的模式,可以对待优化源代码进行相应的优化,得到优化源代码。当待优化源代码均已完成优化时,表征智能合约优化完成。
步骤104,基于优化源代码生成优化智能合约,并对优化智能合约进行验证,当验证通过时,输出优化源代码。
在完成对智能合约的优化后,可以对优化前后的智能合约的操作行为进行比较,当操作行为一致时,可以认为优化是等价且有效的,此时可以输出优化后的智能合约中的优化源代码。
本发明通过读取预设智能合约的源代码,并将源代码转换为抽象语法树;在抽象语法树中检测具有预设的待优化模式的待优化源代码;优化待优化源代码,生成优化源代码;对优化后的智能合约进行验证,当验证通过时,输出优化源代码。从而解决了现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
请参阅图2,图2为本发明另一实施例提供的一种基于源代码的智能合约优化方法的步骤流程图。该方法具体可以包括以下步骤:
步骤201,读取预设的智能合约的源代码,并将源代码转换为抽象语法树;
步骤202,在抽象语法树中检测具有预设的待优化模式的待优化源代码;
步骤203,优化待优化源代码,生成优化源代码;
在本发明实施例中,待优化模式包括稀疏存储模式;优化源代码包括第一优化源代码;优化待优化源代码,生成优化源代码的步骤,可以包括:
当检测到稀疏存储模式对应的第一待优化源代码时,获取第一待优化源代码的状态变量定义顺序;
调整状态变量定义顺序,生成调整顺序;
当调整顺序对应的插槽数小于状态变量定义顺序对应的插槽数时,基于调整顺序生成第一优化源代码。
在实际应用中,Solidity智能合约的存储是连续的32字节(256位)插槽。状态变量按定义顺序排列在插槽中。对于状态变量,如果当前插槽的剩余空间可以存储此变量,则该变量将存储在此插槽中。否则,变量将存储在新的(未使用的)插槽中。稀疏存储意味着智能合约中的变量可以存储在更少的插槽中。如果状态变量的定义被合理地重新排列,则可以使用更少的插槽来存储变量并降低使用智能合约的成本。众所周知,为了防止用户滥用资源,区块链的存储资源被设计为非常昂贵。智能合约使用的存储空间越多,消耗的gas就越多,成本也越高。因此,合理地安排状态变量(最小化浪费的空间)是有意义且有益的。
在具体实现中,对于稀疏存储模式的检测,可以通过直接执行本模式优化的步骤,如优化后的代码与优化前的代码不同,则证明存在稀疏存储模式。
在检测到智能合约中存在稀疏存储模式后,可以通过以下过程对其进行优化:
找到使第一待优化代码中使用最少的插槽数的状态变量的状态变量定义顺序。具体而言,首先构造一个有关变量类型大小的映射表。智能合约状态变量有两种类型:引用类型(例如struct,数组)和基本类型(例如uint,地址)。对于引用类型,将其大小设置为256位,因为根据以太坊黄皮书的规定,参考数据类型的大小始终始于新的存储插槽的大小。对于基本类型,将其大小与Solidity开发人员文档中描述的大小保持一致。然后,计算原始变量定义顺序中使用的插槽数。最后,使用启发式规则来调整变量的顺序,直到找到使用比原始插槽更少的插槽的顺序作为调整顺序,将此调整顺序应用于智能合约以实现优化。
在一个示例中,如表3所示,具有稀疏存储的低效率的gas消耗模式的代码段具有3个状态变量,分别称为decimals,totalSupply和owner。状态变量的变量类型为uint8,uint256和address,分别占据8位,256位和160位。根据合约中变量的定义顺序,合约使用3个插槽来存储变量。可以发现变量decimals和变量owner都不占据整个插槽,仅占据一部分插槽。如果变量decimals和变量owner可以放在一个插槽中,则该合约只需使用2个插槽来存储状态变量,而不需使用3个插槽,这样可以优化合约的gas使用量并节省资金。
表3
在本发明实施例中,待优化模式还包括小变量模式;优化源代码还包括第二优化源代码;优化待优化源代码,生成优化源代码的步骤,还包括:
当检测到小变量模式对应的第二待优化源代码时,将第二待优化源代码的变量类型转化为预设类型,生成第二优化源代码。
小变量是指小于256位的变量类型。
在实际应用中,如果变量不能与周围的变量一起打包和存储在同一插槽中,则该变量将单独存储在256位插槽中。对于小于256位的较小值,将首先由EVM转换为256位,然后将其存储在插槽中。与将256位变量单独存储在插槽中相比,将小于256位变量存储在插槽中会由于转换而产生额外的开销。
因此,本发明实施例定义了小变量模式,并对其进行优化,以减少额外开销。
在具体实现中,在扫描智能合约代码时,如果变量声明中出现了小于256位的变量类型,则表征智能合约中存在小变量模式。
针对于小变量模式对应的第二待优化源代码的优化,可以通过以下过程实现:
将未压缩且少于256位的变量的类型设置为与原始变量类型相对应的256位变量类型(即,将uint8更改为uint256,将int8更改为int256)。另外,对于与更改类型的变量交互的变量,还需要相应地更改变量类型。
在一个示例中,如表4所示,第二待优化源代码的第一个变量contractVersion的变量类型为uint32,其大小为32位。由于第二个变量的变量类型是字符串,大小为256位,并且不能与其他变量共享该插槽,因此变量contractVersion只能存储在一个插槽中。在将变量contractVersion存储在插槽中之前,EVM将会通过填充0把变量contractVersion扩展为256位。此操作会导致额外的gas消耗。而将第二待优化源代码优化为第二优化源代码后,变量contractVersion的变量类型更改为uint256,减少了gas消耗。
需要说明的是,由于没有把变量contractVersion的值赋给其他变量,因此无需对合约进行进一步更改。
表4
在本发明实施例中,待优化模式还包括重复赋值模式;优化源代码还包括第三优化源代码;优化待优化源代码,生成优化源代码的步骤,还包括:
当检测到重复赋值模式对应的第三待优化源代码时,从第三待优化源代码中提取声明赋值状态变量列表和构造函数赋值状态变量列表;
对比声明赋值状态变量列表和构造函数赋值状态变量列表,确定重复赋值状态变量;
删除重复赋值状态变量的声明赋值,生成第三优化源代码。
在实际应用中,根据Solidity开发人员文档,编译器将生成一些用于智能合约部署的指令。这些指令完成了3个任务:(1)将智能合约的字节码存储到区块链中。(2)将状态变量存储在相应合约的存储中。如果状态变量在声明时未初始化,则编译器将自动将其初始化为0。(3)执行智能合约的构造函数。但是,出于传统编程语言(如Java)的编程习惯,在声明变量后,凭借直觉,许多开发人员会立即为变量赋值。因此,在智能合约中经常发生重复向状态变量声明和构造函数中的变量赋值的现象。值得注意的是,此现象属于低效率的gas消耗模式,因为一些无意义的代码(在状态变量声明中实现赋值的代码)浪费了gas。在声明过程中为状态变量赋值之后,在读取或写入状态变量之前,该值就立即在构造函数中被修改了。
因此,本发明实施例定义了重复赋值模式,通过检测重复赋值模式,并对其代码进行优化,以节约gas资源。
在具体实现中,对重复赋值模式的检测,可以通过以下过程实现:
通过扫描智能合约代码,收集所有的状态变量。通过检测每个状态变量,在变量声明处和构造函数中是否同时对该变量进行了赋值操作来判断是否存在该重复赋值模式。
在检测到重复赋值模式后,对重复赋值模式对应的第三待优化源代码的优化,可以通过以下过程实现:
首先扫描合约并记录声明时赋值的状态变量和构造函数中赋值的状态变量,生成声明赋值状态变量列表和构造函数赋值状态变量列表。接着对比声明赋值状态变量列表和构造函数赋值状态变量列表,确定重复赋值状态变量。将重复赋值状态变量在声明中的赋值删除,得到第三优化源代码。
在一个示例中,如表5所示,智能合约ProofOfWeakFOMO具有状态变量owner,并在声明时将msg.sender(代表交易的发送者)赋值给变量。在构造函数中,变量所有者被再次赋值为msg.sender。显然,变量声明语句“address owner=msg.sender”中的赋值语句“=msg.sender”是毫无意义的合约片段,这导致浪费大量的gas。而在第三优化源代码中,删除了变量声明语句“address owner=msg.sender”中的赋值语句“=msg.sender”。
表5
在本发明实施例中,待优化模式还包括频繁使用状态变量模式;优化源代码还包括第四优化源代码;优化待优化源代码,生成优化源代码的步骤,还包括:
当检测到频繁使用状态变量模式对应的第四待优化源代码时,获取第四待优化源代码中的循环状态变量;
采用预设局部变量替换循环状态变量,生成第四优化源代码。
在实际应用中,根据以太坊黄皮书,可以知道与读写局部变量相比,读写状态变量非常昂贵,因为与其他操作码相比,它涉及操作码SLOAD和SSTORE,这两者消耗更多的gas。特别是,如果以循环方式执行状态变量的读取和写入操作,则合约所消耗的gas会随着循环次数的增加而增加。
因此,本发明实施例定义了频繁使用状态变量模式,通过检测频繁使用状态变量模式,并对其代码进行优化,以节约gas资源。
在具体实现中,对于频繁使用状态变量模式的检测,可以通过以下过程实现:
扫描智能合约代码,对于每个循环语句,检测循环内部是否访问了状态变量,若是,则判定存在频繁使用状态变量模式。
在检测到频繁使用状态变量模式后,对频繁使用状态变量模式对应的第四待优化源代码的优化,可以通过以下过程实现:
在实际应用中,尽管读写状态变量非常昂贵(执行每个SLOAD消耗200gas,执行每个SSTORE消耗20000/5000gas),但是读写局部变量仅涉及MLOAD和MSTORE操作码,消耗3gas。因此,本发明实施例可以通过使用局部变量来临时替换循环中的状态变量进行优化。具体而言,首先找出循环中使用的循环状态变量。然后,声明新的局部变量以保存状态变量的值,并在循环中使用局部变量替换循环状态变量。最后,将局部变量的值分配回状态变量。
在一个示例中,如表6所示,在第四待优化源代码中,智能合约ShareTokenSale在startSale函数的循环中频繁使用状态变量endTimes。状态变量endTimes在每个循环中读取和写入一次,这将导致EVM执行大量SLOAD和SSTORE操作码,合约的执行将消耗大量的资源。因此,基于本发明实施例,针对智能合约ShareTokenSale,可以创建一个新的局部变量temp0,并在执行循环之前将状态变量endTimes的值赋给局部变量temp0。然后,在循环中使用变量temp0替换变量endTimes,并在执行循环后将变量temp0的值赋给变量endTimes。从而得到第四优化源代码。即表6中的高效率的版本。尽管由于代码量的增加,此优化将增加部署合约的gas消耗,但随着合约调用次数的增加,优化效果将变得越来越明显。值得注意的是,合约仅部署一次,但将被多次调用。因此,这种优化仍然有意义。
表6
在本发明实施例中,待优化模式还包括未考虑短路规则模式;优化源代码还包括第五优化源代码;优化待优化源代码,生成优化源代码的步骤,还包括:
当检测到未考虑短路规则模式对应的第五待优化源代码时,获取第五待优化源代码对应的逻辑操作的左操作数和右操作数;
当左操作数对应的gas消耗量大于右操作数对应的gas消耗量时,替换左操作数与右操作数的位置,生成第五优化源代码。
在实际应用中,常见的短路规则适用于运算符||和&&,这意味着在表达式f(x)||g(y)时,如果f(x)的值为true,则g(y)即使有副作用也不会被执行。换句话说,逻辑运算符||和&&的左操作数(例如f(x))一定会执行,而右操作数(例如g(y))不一定会执行。因此,将更昂贵的操作设置为右操作数以尝试减少执行的昂贵操作的数量,将可以节省大量的gas。但是,许多开发人员在开发智能合约时并未考虑短路规则,这导致实现代码的gas消耗量更高。
因此,本发明实施例定义了未考虑短路规则模式,通过检测未考虑短路规则模式,并对其代码进行优化,以节约gas资源。
在具体实现中,对于未考虑短路规则模式的检测,可以通过以下过程实现:
扫描智能合约代码,对于每个逻辑操作,计算逻辑操作的左操作数和右操作数的gas消耗量,如果存在至少一个逻辑操作的左操作数的gas消耗量大于右操作数的gas消耗量,则判定存在未考虑短路规则模式。
在检测到频繁使用状态变量模式后,对未考虑短路规则模式对应的第五待优化源代码的优化,可以通过以下过程实现:
对于智能合约中的每个逻辑操作,首先计算逻辑操作的左操作数和右操作数的gas消耗量。如果左操作数的gas消耗量大于右操作数的gas消耗量,将交换两个操作数的位置。否则,保持不变。
在一个示例中,如表7所示,在第五待优化源代码中,代码段具有条件语句,其中包含逻辑运算符&&。逻辑运算符对余额比较结果(msg.value>=this.balance)和变量比较结果(frozen>=false)进行逻辑判断。由于操作符&&符合短路规则,因此,如果余额比较结果评估为false,则在条件语句中不会评估变量比较结果。余额比较涉及操作码BALANCE,其是相对昂贵的操作码,余额比较比变量比较昂贵。将余额比较操作设置为左操作数会浪费大量gas。而在优化后的高效版本中,即在第五优化源代码中,逻辑操作交换位置两侧的操作数,余额比较操作变为右操作数。
表7
在本发明实施例中,待优化模式还包括不准确的函数可见性模式;优化源代码还包括第六优化源代码;优化待优化源代码,生成优化源代码的步骤,还包括:
当检测到不准确的函数可见性模式对应的第六待优化源代码时,从第六待优化源代码中提取未调用的公有函数;
调整未调用的公有函数的可见性,生成第六优化源代码。
在实际应用中,Solidity中有三个数据位置(存储数据的位置),即内存,存储和调用数据。调用数据是一个只读的字节可寻址空间,其中保存交易或调用的data参数。内存是易失性的可读写字节寻址空间。其主要用于在执行期间存储数据,为了将参数传递给内部函数。存储是一个持久的可读写字寻址空间。每个合约都在这里存储其持久性信息。函数可见性有四种,即公有,外部,内部和私有。公有函数可以被所有人使用。外部函数不能在内部访问,这意味着只能通过交易访问。外部可见性是公有可见性的子集。如果未指定函数的可见性,则根据Solidity开发人员文档,它将默认为公有。而由于开发人员没有主动设置函数可见性并且不知道关键字external(在其他编程语言中不是通用关键字),因此许多函数的可见性本来可以设置为外部,但被设置为公有,这会导致额外的gas消耗。公有函数比外部函数消耗更多的gas,因为公有函数需要将所有函数输入参数从调用数据复制到内存中,以便合约内部可以调用公有函数。内存分配(即MSTORE)很昂贵。
因此,本发明实施例定义了不准确的函数可见性模式,通过检测不准确的函数可见性模式,并对其代码进行优化,以节约gas资源。
在具体实现中,对于不准确的函数可见性模式的检测,可以通过以下过程实现:
扫描智能合约代码,对于合约中的每个公有函数,如果存在至少一个公有函数,合约内部不存在对它的调用,则判定存在此模式。
在检测到不准确的函数可见性模式后,对不准确的函数可见性模式对应的第六待优化源代码的优化,可以通过以下过程实现:
从第六待优化源代码中提取未调用的公有函数,将内部未调用的公有函数的可见性设置为外部。
在一个示例中,如表8所示,在第六未优化源代码中,代码段中函数signupUserWhitelist的可见性是公有的,但合约中的其他函数未调用该函数。而在优化后的高版本中,即第六优化源代码中,函数signupUserWhitelist的可见性已更改为外部。
表8
步骤204,基于优化源代码生成优化智能合约,并验证优化智能合约的第一操作行为与智能合约的第二操作行为是否一致;
步骤205,若一致,则判定验证通过,输出优化源代码。
在完成对智能合约的优化后,可以对优化前后的智能合约的操作行为进行比较,当操作行为一致时,可以认为优化是等价且有效的,此时可以输出优化后的智能合约中的优化源代码。
本发明通过读取预设智能合约的源代码,并将源代码转换为抽象语法树;在抽象语法树中检测具有预设的待优化模式的待优化源代码;优化待优化源代码,生成优化源代码;对优化后的智能合约进行验证,当验证通过时,输出优化源代码。从而解决了现有的基于字节码的优化方法使得优化变得不透明,且只能处理小范围的操作码序列,导致无法优化长操作码序列的智能合约片段的技术问题。
请参阅图3,图3为本发明实施例提供的一种基于源代码的智能合约优化装置的结构框图。
本发明实施例提供了一种基于源代码的智能合约优化装置,包括:
转换模块301,用于读取预设智能合约的源代码,并将源代码转换为抽象语法树;
检测模块302,用于在抽象语法树中检测具有预设的待优化模式的待优化源代码;
优化模块303,用于优化待优化源代码,生成优化源代码;
验证模块304,用于对优化后的智能合约进行验证,当验证通过时,输出优化源代码。
在本发明实施例中,待优化模式包括稀疏存储模式;优化源代码包括第一优化源代码;优化模块303,包括:
状态变量定义顺序提取子模块,用于当检测到稀疏存储模式对应的第一待优化源代码时,在第一待优化源代码中提取状态变量定义顺序;
调整顺序生成子模块,用于调整状态变量定义顺序,生成调整顺序;
第一优化源代码生成子模块,用于当调整顺序对应的插槽数小于状态变量定义顺序对应的插槽数时,基于调整顺序生成第一优化源代码。
在本发明实施例中,待优化模式还包括小变量模式;优化源代码还包括第二优化源代码;优化模块303,还包括:
第二优化源代码生成子模块,用于当检测到小变量模式对应的第二待优化源代码时,将第二待优化源代码的变量类型转化为预设类型,生成第二优化源代码。
在本发明实施例中,待优化模式还包括重复赋值模式;优化源代码还包括第三优化源代码;优化模块303,还包括:
列表提取子模块,用于当检测到重复赋值模式对应的第三待优化源代码时,从第三待优化源代码中提取声明赋值状态变量列表和构造函数赋值状态变量列表;
重复赋值状态变量确定子模块,用于对比声明赋值状态变量列表和构造函数赋值状态变量列表,确定重复赋值状态变量;
第三优化源代码生成子模块,用于删除重复赋值状态变量的声明赋值,生成第三优化源代码。
在本发明实施例中,待优化模式还包括频繁使用状态变量模式;优化源代码还包括第四优化源代码;优化模块303,还包括:
循环状态变量获取子模块,用于当检测到频繁使用状态变量模式对应的第四待优化源代码时,获取第四待优化源代码中的循环状态变量;
第四优化源代码生成子模块,用于采用预设局部变量替换循环状态变量,生成第四优化源代码。
在本发明实施例中,待优化模式还包括未考虑短路规则模式;优化源代码还包括第五优化源代码;优化模块303,还包括:
操作数获取子模块,用于当检测到未考虑短路规则模式对应的第五待优化源代码时,获取第五待优化源代码对应的逻辑操作的左操作数和右操作数;
第五优化源代码生成子模块,用于当左操作数对应的gas消耗量大于右操作数对应的gas消耗量时,替换左操作数与右操作数的位置,生成第五优化源代码。
在本发明实施例中,待优化模式还包括不准确的函数可见性模式;优化源代码还包括第六优化源代码;优化模块303,还包括:
未调用的公有函数提取子模块,用于当检测到不准确的函数可见性模式对应的第六待优化源代码时,从第六待优化源代码中提取未调用的公有函数;
第六优化源代码生成子模块,用于调整未调用的公有函数的可见性,生成第六优化源代码。
在本发明实施例中,验证模块304,包括:
验证子模块,用于基于优化源代码生成优化智能合约,并验证优化智能合约的第一操作行为与智能合约的第二操作行为是否一致;
输出子模块,用于若一致,则判定验证通过,输出优化源代码。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。
本领域内的技术人员应明白,本发明实施例的实施例可提供为方法、装置、或计算机程序产品。因此,本发明实施例可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本发明实施例是参照根据本发明实施例的方法、终端设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理终端设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理终端设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理终端设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理终端设备上,使得在计算机或其他可编程终端设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程终端设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本发明实施例的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例做出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本发明实施例范围的所有变更和修改。
最后,还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者终端设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者终端设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者终端设备中还存在另外的相同要素。
以上所述,以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。
Claims (10)
1.一种基于源代码的智能合约优化方法,其特征在于,包括:
读取预设的智能合约的源代码,并将所述源代码转换为抽象语法树;
在所述抽象语法树中检测具有预设的待优化模式的待优化源代码;
优化所述待优化源代码,生成优化源代码;
基于所述优化源代码生成优化智能合约,并对所述优化智能合约进行验证,当验证通过时,输出所述优化源代码。
2.根据权利要求1所述的方法,其特征在于,所述待优化模式包括稀疏存储模式;所述优化源代码包括第一优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,包括:
当检测到所述稀疏存储模式对应的第一待优化源代码时,在所述第一待优化源代码中提取状态变量定义顺序;
调整所述状态变量定义顺序,生成调整顺序;
当所述调整顺序对应的插槽数小于所述状态变量定义顺序对应的插槽数时,基于所述调整顺序生成所述第一优化源代码。
3.根据权利要求2所述的方法,其特征在于,所述待优化模式还包括小变量模式;所述优化源代码还包括第二优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述小变量模式对应的第二待优化源代码时,将所述第二待优化源代码的变量类型转化为预设类型,生成所述第二优化源代码。
4.根据权利要求3所述的方法,其特征在于,所述待优化模式还包括重复赋值模式;所述优化源代码还包括第三优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述重复赋值模式对应的第三待优化源代码时,从第三待优化源代码中提取声明赋值状态变量列表和构造函数赋值状态变量列表;
对比所述声明赋值状态变量列表和所述构造函数赋值状态变量列表,确定重复赋值状态变量;
删除所述重复赋值状态变量的声明赋值,生成所述第三优化源代码。
5.根据权利要求4所述的方法,其特征在于,所述待优化模式还包括频繁使用状态变量模式;所述优化源代码还包括第四优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述频繁使用状态变量模式对应的第四待优化源代码时,获取所述第四待优化源代码中的循环状态变量;
采用预设局部变量替换所述循环状态变量,生成所述第四优化源代码。
6.根据权利要求5所述的方法,其特征在于,所述待优化模式还包括未考虑短路规则模式;所述优化源代码还包括第五优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述未考虑短路规则模式对应的第五待优化源代码时,获取所述第五待优化源代码对应的逻辑操作的左操作数和右操作数;
当所述左操作数对应的gas消耗量大于所述右操作数对应的gas消耗量时,替换所述左操作数与所述右操作数的位置,生成所述第五优化源代码。
7.根据权利要求6所述的方法,其特征在于,所述待优化模式还包括不准确的函数可见性模式;所述优化源代码还包括第六优化源代码;所述优化所述待优化源代码,生成优化源代码的步骤,还包括:
当检测到所述不准确的函数可见性模式对应的第六待优化源代码时,从所述第六待优化源代码中提取未调用的公有函数;
调整所述未调用的公有函数的可见性,生成所述第六优化源代码。
8.根据权利要求1所述的方法,其特征在于,所述基于所述优化源代码生成优化智能合约,并对所述优化智能合约进行验证,当验证通过时,输出所述优化源代码的步骤,包括:
基于所述优化源代码生成优化智能合约,并验证所述优化智能合约的第一操作行为与所述智能合约的第二操作行为是否一致;
若一致,则判定验证通过,输出所述优化源代码。
9.一种基于源代码的智能合约优化装置,其特征在于,包括:
转换模块,用于读取预设智能合约的源代码,并将所述源代码转换为抽象语法树;
检测模块,用于在所述抽象语法树中检测具有预设的待优化模式的待优化源代码;
优化模块,用于优化所述待优化源代码,生成优化源代码;
验证模块,用于对优化后的智能合约进行验证,当验证通过时,输出所述优化源代码。
10.一种电子设备,其特征在于,所述设备包括处理器以及存储器:
所述存储器用于存储程序代码,并将所述程序代码传输给所述处理器;
所述处理器用于根据所述程序代码中的指令执行权利要求1-8任一项所述的基于源代码的智能合约优化方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110013879.3A CN112631656A (zh) | 2021-01-06 | 2021-01-06 | 一种基于源代码的智能合约优化方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110013879.3A CN112631656A (zh) | 2021-01-06 | 2021-01-06 | 一种基于源代码的智能合约优化方法及装置 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN112631656A true CN112631656A (zh) | 2021-04-09 |
Family
ID=75291583
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110013879.3A Pending CN112631656A (zh) | 2021-01-06 | 2021-01-06 | 一种基于源代码的智能合约优化方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN112631656A (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN113127042A (zh) * | 2021-05-08 | 2021-07-16 | 中山大学 | 一种智能合约推荐方法、设备及存储介质 |
WO2024055437A1 (zh) * | 2022-09-14 | 2024-03-21 | 蚂蚁区块链科技(上海)有限公司 | 一种检测合约升级的兼容性的方法和装置 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108985073A (zh) * | 2018-07-18 | 2018-12-11 | 成都链安科技有限公司 | 一种高度自动化的智能合约形式化验证系统及方法 |
CN112070608A (zh) * | 2020-08-20 | 2020-12-11 | 财付通支付科技有限公司 | 信息处理方法、装置、介质及电子设备 |
US20200394175A1 (en) * | 2019-06-11 | 2020-12-17 | International Business Machines Corporation | Database world state performance improvement |
-
2021
- 2021-01-06 CN CN202110013879.3A patent/CN112631656A/zh active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108985073A (zh) * | 2018-07-18 | 2018-12-11 | 成都链安科技有限公司 | 一种高度自动化的智能合约形式化验证系统及方法 |
US20200394175A1 (en) * | 2019-06-11 | 2020-12-17 | International Business Machines Corporation | Database world state performance improvement |
CN112070608A (zh) * | 2020-08-20 | 2020-12-11 | 财付通支付科技有限公司 | 信息处理方法、装置、介质及电子设备 |
Non-Patent Citations (2)
Title |
---|
TINY熊: "Solidity优化-减少智能合约gas消耗的8种方法", 《HTTPS://WWW.CHAINNEWS.COM/ARTICLES/330156342168.HTM》 * |
链三丰: "怎样利用智能合约去优化以太坊gas的消耗", 《HTTP://M.ELECFANS.COM/ARTICLE/1162322.HTML》 * |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN113127042A (zh) * | 2021-05-08 | 2021-07-16 | 中山大学 | 一种智能合约推荐方法、设备及存储介质 |
WO2024055437A1 (zh) * | 2022-09-14 | 2024-03-21 | 蚂蚁区块链科技(上海)有限公司 | 一种检测合约升级的兼容性的方法和装置 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
Marchesi et al. | Design patterns for gas optimization in ethereum | |
US9047583B2 (en) | Ontology context logic at a key field level | |
VanRossum et al. | The python language reference | |
US7380242B2 (en) | Compiler and software product for compiling intermediate language bytecodes into Java bytecodes | |
Poletto et al. | C and tcc: a language and compiler for dynamic code generation | |
JP5851396B2 (ja) | 処理方法 | |
Dinkelaker et al. | A dynamic software product line approach using aspect models at runtime | |
US20080091409A1 (en) | Customizable mathematic expression parser and evaluator | |
US20070250825A1 (en) | Compiling Alternative Source Code Based on a Metafunction | |
Allen et al. | The experimental compiling system | |
US20160357533A1 (en) | Generating code in statically typed programming languages for dynamically typed array-based language | |
CN112631656A (zh) | 一种基于源代码的智能合约优化方法及装置 | |
Suhan et al. | LazyTensor: combining eager execution with domain-specific compilers | |
Järvi et al. | Concept-controlled polymorphism | |
Zafar et al. | Sol2js: translating solidity contracts into javascript for hyperledger fabric | |
Schultz et al. | Compiling java for low-end embedded systems | |
CN114174983B (zh) | 用于高级构造的优化的自动验证的方法和系统 | |
CN105393216B (zh) | 运行时内存调节 | |
Misse-Chanabier et al. | Illicium A modular transpilation toolchain from Pharo to C | |
Riddle et al. | Tools for software system construction | |
Diaconescu et al. | Automatic distribution of java byte-code based on dependence analysis | |
Stucki et al. | Virtual ADTs for portable metaprogramming | |
Naish et al. | Adtpp: lightweight efficient safe polymorphic algebraic data types for C | |
Bodzay et al. | AspectMatlab++: annotations, types, and aspects for scientists | |
CN112860279A (zh) | 生成应用安装包的方法、装置、设备和介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
RJ01 | Rejection of invention patent application after publication | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20210409 |