基于变长编码的智能合约执行方法和装置
技术领域
本说明书实施例涉及区块链技术领域,更具体地,涉及一种智能合约执行方法和装置。
背景技术
目前,越来越多的区块链平台拥有智能合约功能,例如以太坊区块链。在以太坊中,每个节点都运行有以太坊虚拟机(EVM),用户在以太坊网络中发布或者调用“智能合约”都是运行在EVM上。在调用一个智能合约时,只需要发起一个指向合约地址的交易,并将合约需要的参数作为“数据(data)”字段保存在交易中即可。为了方便合约的调用和参数的传递,以太坊中制定了交互的标准。使用Solidity语言编写的智能合约在编译时会自动生成一个ABI(程序二进制接口)。ABI是固定格式的二进制字符串,包含了合约中各函数或事件的名称、参数数目和类型、以及返回值数目和类型等。作为服务提供者,合约创建者需要向其他用户提供合约的ABI和合约地址,以供用户调用该智能合约、执行该智能合约并获取合约返回值。用户在调用智能合约时,通过输入合约地址及调用程序名称,及其中的参数的类型和取值,从而在本节点EVM中基于程序名称和参数的类型和取值编码,从而获取输入ABI编码数据,并将包括该编码数据和智能合约地址的交易发送到区块链中。区块链中的节点(例如记账节点)在获取该交易后,可在本地EVM中对所述编码数据解码从而获取参数的取值,并基于智能合约地址获取该智能合约,并运行相应的程序,从而获取程序输出值,该输出值可以通过同样的ABI编码规范进行编码并从该EVM中输出,从而在该节点可通过对输出的编码数据进行解码,获取程序输出值。在所述ABI规范中,参数的最小存储单位是32字节,对于小于32字节的参数,则通过补零等转换方式将该参数转换至32字节。
因此,需要一种更有效的智能合约执行方案。
发明内容
本说明书实施例旨在提供一种更有效的智能合约执行方案,以解决现有技术中的不足。
为实现上述目的,本说明书一个方面提供一种智能合约执行方法,所述方法在区块链中第一节点执行,所述方法包括:
从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,其中,N为自然数,所述输入编码数据包括至少N+2个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,第2个字段为具有第二预定字节数的编码指示字段,所述编码指示字段中的前至少N位与所述输入编码数据中的从第3个字段开始的至少N个字段分别一一对应,每一位用于指示相应字段是否为变长编码,其中,所述至少N个字段中的每个字段对应于所述N个输入参数中的一个参数,所述变长编码包括第一部分和第二部分,所述第一部分具有第三预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
基于所述智能合约地址获取所述智能合约;
对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述N个输入参数中包括第一参数,所述第一参数为值类型参数,所述第一参数对应的字段为变长编码,且该变长编码中的第二部分为所述第一参数的取值。
在一个实施例中,所述N个输入参数中包括第二参数,所述第二参数为引用类型参数,所述至少N个字段的前N个字段与所述N个参数分别一一对应,所述第二参数与所述输入编码数据中的至少三个字段对应,所述至少三个字段中的位于前N个字段中的字段为变长编码,该变长编码中的第二部分为第二参数在所述输入编码数据中的编码位置。
在一个实施例中,所述第二参数为不定长数组,所述第二参数与所述编码数据中的至少四个字段对应,所述至少四个字段中位于前N个字段之后的至少三个字段中包括第一字段和第二字段,所述第一字段和第二字段都为变长编码,其中,所述第一字段的第二部分与所述不定长数组的元素个数相关,所述第二字段的第二部分为所述不定长数组的任一元素的元素值。
在一个实施例中,所述待调用程序为函数或事件。
在一个实施例中,所述待调用程序为函数,所述方法还包括,在获取执行结果之后,将包括所述执行结果的区块发送到所述区块链中,以更新所述区块链中的区块。
在一个实施例中,所述待调用程序包括M个返回参数,M为自然数,其中,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果包括:
在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M+1个字段,其中,第1个字段为具有第四预定字节数的编码指示字段,所述编码指示字段中的前至少M位与所述输出编码数据中的从第2个字段开始的至少M个字段分别一一对应,每一位用于指示相应字段是否为所述变长编码,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数;以及
通过对所述输出编码数据解码,获取所述M个返回参数各自的取值。
本说明书另一方面提供一种智能合约执行方法,所述方法在区块链中第一节点执行,所述方法包括:
从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,所述输入编码数据包括至少N+1个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,从第2个字段开始的至少N个字段的每个字段对应于所述N个参数中的一个参数,其中,所述至少N个字段的每个字段都为变长编码,所述变长编码包括第一部分和第二部分,所述第一部分具有第二预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
基于所述智能合约地址获取所述智能合约;
对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述待调用程序包括M个返回参数,其中,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果包括:
在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M个字段,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数,其中,所述每个字段都为所述变长编码;以及
通过对所述输出编码数据解码,获取所述M个返回参数的取值。
本说明书另一方面提供一种智能合约执行装置,所述装置部署在区块链中第一节点,所述装置包括:
第一获取单元,配置为,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,其中,N为自然数,所述输入编码数据包括至少N+2个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,第2个字段为具有第二预定字节数的编码指示字段,所述编码指示字段中的前至少N位与所述输入编码数据中的从第3个字段开始的至少N个字段分别一一对应,每一位用于指示相应字段是否为变长编码,其中,所述至少N个字段中的每个字段对应于所述N个输入参数中的一个参数,所述变长编码包括第一部分和第二部分,所述第一部分具有第三预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
第二获取单元,配置为,基于所述智能合约地址获取所述智能合约;
解码单元,配置为,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
执行单元,配置为,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述待调用程序为函数,所述装置还包括,更新单元,配置为,在获取执行结果之后,将包括所述执行结果的区块发送到所述区块链中,以更新所述区块链中的区块。
在一个实施例中,所述待调用程序包括M个返回参数,M为自然数,其中,所述执行单元包括:
执行子单元,配置为,在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
编码子单元,配置为,基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M+1个字段,其中,第1个字段为具有第四预定字节数的编码指示字段,所述编码指示字段中的前至少M位与所述输出编码数据中的从第2个字段开始的至少M个字段分别一一对应,每一位用于指示相应字段是否为所述变长编码,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数;以及
解码子单元,配置为,通过对所述输出编码数据解码,获取所述M个返回参数各自的取值。
本说明书另一方面提供一种智能合约执行装置,所述装置部署在区块链中第一节点,所述装置包括:
第一获取单元,配置为,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,所述输入编码数据包括至少N+1个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,从第2个字段开始的至少N个字段的每个字段对应于所述N个参数中的一个参数,其中,所述至少N个字段的每个字段都为变长编码,所述变长编码包括第一部分和第二部分,所述第一部分具有第二预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
第二获取单元,配置为,基于所述智能合约地址获取所述智能合约;
解码单元,配置为,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
执行单元,配置为,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述待调用程序包括M个返回参数,其中,所述执行单元包括:
执行子单元,配置为,在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
编码子单元,配置为,基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M个字段,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数,其中,所述每个字段都为所述变长编码;以及
解码子单元,配置为,通过对所述输出编码数据解码,获取所述M个返回参数的取值。
本说明书另一方面提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行上述任一项方法。
本说明书另一方面提供一种计算设备,包括存储器和处理器,其特征在于,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现上述任一项方法。
通过根据本说明书实施例的智能合约执行方案,通过变长编码对智能合约的输入数据和输出数据进行压缩编码,大大减少了数据量,降低了对带宽的依赖,实现了高效率的合约交互。
附图说明
通过结合附图描述本说明书实施例,可以使得本说明书实施例更加清楚:
图1示出根据本说明书实施例的调用及执行智能合约的过程示意图;
图2示出根据本说明书实施例的一种智能合约执行方法;
图3示出现有的接口编码规范;
图4示出根据本说明书实施例的输入编码规范;
图5示出根据本说明书实施例的一种智能合约执行方法;
图6示出了根据该实施例的输入编码数据的编码规范;
图7示出根据本说明书实施例的一种智能合约执行装置700;
图8示出根据本说明书实施例的一种智能合约执行装置800。
具体实施方式
下面将结合附图描述本说明书实施例。
图1示出根据本说明书实施例的调用及执行智能合约的过程示意图。如图1中所示,其中包括区块链100,区块链中包括多个节点,例如包括节点11和节点12。所示节点11例如为用户Bob的节点,用户Bob在节点11通过发送交易Tx的方式调用智能合约。图中示出了交易Tx的示例形式,如图中所示,该交易是从Bob账户(0xf5e…)发送至智能合约SimpleStorage的账户(0x6f8…),该交易的数据(Data)为将要调用的函数名称“set(strings)”,及该函数的输入参数“Hello”,其中“strings”为该参数的类型,另外,该交易Tx底部包括用户Bob基于其私钥对该交易数据的数字签名(0x93a…)。在该第一节点发送该交易之前,通过根据本说明书实施例的预定编码方法对该交易数据进行编码,并将包括编码数据的交易Tx发送到区块链中。在节点11发送交易Tx之后,节点11的直接或间接连接的节点将陆续获取到该交易Tx。例如用户Alice的节点12为区块链中通过共识机制确定的记账节点,其在获取交易Tx之后,通过节点12中的EVM对所述编码数据解码,从而确定智能合约中的调用函数,并获取该函数各个参数的二进制取值,通过所述智能合约地址获取智能合约(SimpleStorage),从而执行所述调用函数,并获取执行结果。节点12中的EVM在获取执行结果之后用同样的编码规范对该执行结果编码并输出,从而,节点12可通过解码所述输出的编码数据获取函数的执行结果,并将该执行结果打包到区块中并发送到区块链中,从而通过其他共识节点的共识将该区块存储到区块链中。
下面详细描述上述智能合约的执行过程。
图2示出根据本说明书实施例的一种智能合约执行方法,所述方法在区块链中第一节点执行,所述方法包括:
在步骤S202,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,其中N为自然数,所述输入编码数据包括至少N+2个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,第2个字段为具有第二预定字节数的编码指示字段,所述编码指示字段中的前至少N位与所述输入编码数据中的从第3个字段开始的至少N个字段分别一一对应,每一位用于指示相应字段是否为变长编码,其中,所述至少N个字段中的每个字段对应于所述N个参数中的一个参数,所述变长编码包括第一部分和第二部分,所述第一部分具有第三预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
在步骤S204,基于所述智能合约地址获取所述智能合约;
在步骤S206,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
在步骤S208,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
首先,在步骤S202,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,其中,N为自然数,所述输入编码数据包括至少N+2个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,第2个字段为具有第二预定字节数的编码指示字段,所述编码指示字段中的前至少N位与所述输入编码数据中的从第3个字段开始的至少N个字段分别一一对应,每一位用于指示相应字段是否为变长编码,其中,所述至少N个字段中的每个字段对应于所述N个参数中的一个参数,所述变长编码包括第一部分和第二部分,所述第一部分具有第三预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值。
所述区块链可使用已有的区块链产品,如以太坊等,也可以自行搭建。
如上文所述,当区块链中的一个节点(例如图1中的Bob节点)希望调用特定智能合约时,将通过向区块链中发送交易的形式来进行调用。具体是,在Bob节点中,首先,获取智能合约地址,及智能合约中待调用程序的程序标识和所述待调用程序中N个参数各自的类型和取值,其中,所述取值为二进制字符串;然后,基于所述程序标识和所述各个参数的类型和取值生成输入编码数据;以及将包括所述智能合约地址和所述输入编码数据的交易发送到区块链中,以调用所述智能合约。
区块链中的节点执行该交易中的智能合约得到合约的执行结果。
由于在节点EVM中执行经编译的字节码形式的智能合约,所述输入编码数据需要符合该智能合约的接口编码规范。图3示出现有的接口编码规范。如图中所示,在该传统的接口编码规范中,第一个字段是4字节的程序指示字段,第二个至最后一个字段都是采用定长32字节的参数编码。这对于取值远远小于32字节的参数来说,是一种存储空间的浪费。
因此,在本说明书实施例中,针对取值较小的参数,采用变长的编码方案,使其存储后的数据小于32字节,从而大大减少了数据的存储空间。
图4示出根据本说明书实施例的输入编码规范。如图中所示,在该编码规范中,第一个字段与上述图3中相同是预定字节数(例如4字节)的程序指示字段,所述程序例如为函数或事件。该字段为基于程序标识生成的编码数据。例如,对于图1中的将要调用的函数“set()”,对该函数的签名字符串进行sha3(keccak256)哈希运算之后,获取前4个字节作为输入编码数据中的第一个字段。可以理解,函数对应的程序标识不限于为函数签名,只要其可用于标识智能合约中相应的程序即可,例如所述程序标识可以为函数名称、函数代码等。另外,对程序标识的编码方法不限于上述哈希计算方法,而可以为任何预定编码方法。
第二个字段是预定字节数(例如32字节)的参数编码指示字段。参数编码指示字段的每一位都用于指示后面的字段是否采用变长的压缩编码。这里的位是二进制位,例如,对于其中一位,可在其等于1时,表示相应的字段是变长编码,在其等于0时,表示相应的字段是定长编码。例如,指示字段的第1位用于指示该字段后的第一个字段是否为变长编码,第2位用于指示该字段后的第二个字段是否为变长编码,依次类推。可以理解,指示字段中的多个位与其后各字段的对应关系不限于上述顺序对应的关系,只要其可以一一对应即可。
图4中的第三个字段至最后一个字段中的每个字段对应于待调用程序的多个输入参数中的一个输入参数。例如,待调用函数包括N个输入参数,则所述第三个字段至最后一个字段的数目至少为N个。其中,当所述数目为N个时,该N个字段与N个输入参数为一一对应的关系。当所述数目大于N个时,该大于N个的字段与N个输入参数为多对一的关系。与传统ABI编码类似地,可使得该大于N个字段中的前N个字段与所述N个输入参数一一对应,例如,当输入参数为值类型参数(例如bool型、unit32型等)时,所述大于N个字段中有一个字段与该参数对应,并且该字段对应于参数的取值。当输入参数为引用类型参数(例如bytes型、unit32[]型等),所述大于N个字段中有至少三个字段与该参数对应,其中,第一个字段在前N个字段中,用于指示该参数在编码数据中的位置,对于在前N个字段之后的至少两个字段,例如,在参数为数组的情况中,其或者对应于参数的取值,或者对应于数组的长度(即数组元素的个数、数组各维度数等)。也就是说,一个输入参数可对应于多个字段,而一个字段只能对应于一个参数,每个字段都只有一个相对应的参数。可以理解,在该编码规范中,所述至少N个字段与所述N个输入参数的对应关系不限于上述对应关系,即,不限于前N个字段与N个输入参数一一对应,而是可以采用其它对应关系,例如,可将各参数(包括引用类型参数)的取值顺序排列,从而不需要在前N个字段中指示引用类型参数的取值的位置。
如图4中所示,假设将参数编码指示字段后的第一个字段设置为变长编码,将最后的与参数编码n对应的字段设置为定长编码,相应地,所述参数编码指示字段的第1位为1,与最后一个字段对应的位为0。如图中对第一个字段的示出,所述变长编码包括第一部分和第二部分,所述第一部分具有预定字节数(例如1字节),用于指示第二部分的字节数(长度),所述第二部分为与相应参数对应的值。
在一个实施例中,可基于字段对应的值的字节数,确定是否将该字段编码为变长编码,例如,在字段对应的值远小于32字节的情况中,将该字段编码为变长编码,当字段对应的值接近32字节或大于预定字节数的情况中,将该字段编码为32字节的定长编码。所述字段对应的值可以为该字段相应的参数的取值,或者可以为该字段相应的参数在编码数据中的编码位置、或者可以为相应参数的长度、元素数目等等。
例如,在所述待调用程序为函数的情况中,假设待调用函数中共包括3个参数name(bytes)、z(bool)和data(uint[]),其中,括号内为相应参数的类型。参数编码指示字段中第1位至第3位与该3个参数分别对应,且分别为1、1、1,即表示对输入编码数据中的第三-第五个字段采用变长编码。所述第三至第五字段与该3个参数一一对应。其中,由于参数name和参数data为引用类型参数,参数z为值类型参数,因此,第三个字段和第五个字段分别指示参数name和参数data的编码位置,第四个字段为参数z的取值。从第六个字段开始为参数name的编码信息。假设参数name(bytes)、z(bool)和data(uint[])的输入分别为“dave”、“true”和“[m,n,q](m、n、q为任意整数)”,其中,对“dave”进行utf8编码获取其16进制取值为“64617665”,“true”对应于16进制值“1”,这里为了便于表示,这里及下文对参数的取值都采用16进制表示,可以理解,在实际操作中采用与其相应的2进制数表示,通过将每个16进制位转换为四位二进制位,可获取相应的二进制数。
具体地,对于第三个字段,参数1的编码位置为4+32+2*3=42,即,参数1从整个编码数据的第43个字节开始编码,其中4为第一个字段(程序指示字段)的字节数,32为第二个字段(参数编码指示字段)的字节数,第三个字段的第一部分为1字节,指示该字段第二部分所占字节的字节数,第二部分为参数name的编码位置,因此应为1字节,第四个字段的第一部分为1字节,第二部分为参数z的取值“01”(即1字节),第五个字段的第一部分为1字节,第二部分为参数unit[]的编码位置,也同样为1字节,因此第三-第五字段的字节数为2*3=6。因此,第三个字段的第二部分的16进制值为“2a”,第三个字段的完整编码为“01 2a”。这里,对编码位置的计算不限于上述计算方法,例如,可以第三个字段为首字段计算编码位置。
对于第四个字段,第二部分对应于参数z的取值“01”,第四个字段的完整编码为“01 01”。
对于第五个字段,第二部分对应于参数data的编码位置,该参数data的编码位置在参数name的编码位置之后,参数name为bytes型,如下文所述,其将占用两个字段共7个字节,因此,参数data的编码位置为42+7=49,该数值对应的16进制值为“31”,因此,第五个字段的完整编码为“01 31”。
从第六个字段开始对参数name进行编码,第六个字段指示参数name的长度,即“4”,由于该数值较小,因此,参数编码指示字段中第4位可为“1”,即指示对第六个字段采用变长编码,因此,该第六个字段的完整编码为“0104”。
第七个字段对应于参数name的取值,即上述“64617665”,该值占用4个字节,可采用变长编码,因此,第七个字段的完整编码为“04 64617665”。
第八个字段对应于参数data的元素个数,可同样地采用变长编码与上文类似地进行编码。
第九-十一字段对应于参数data的各个元素的取值m、n、q,当m、n、q取值较小时,可同样地采用变长编码,而当m、n、q取值较大时,则可以对其采用32字节的定长编码,即在参数编码指示字段中的第7-9位取值为“0”,在该情况中,与例如m的取值对应的编码长度为32字节,其中的编码值通过现有技术中相同的编码方法获取,在此不再赘述。
通过如上所述采用变长编码对取值较小的参数采用变长编码进行编码,大大减少了最终编码数据的字节数,例如,与参数z对应的编码为“01 01”,仅占两个字节,而如果通过定长编码进行编码,参数z将占用32字节。
在一个实施例中,可基于字段对应参数的类型确定是否将该字段编码为变长编码,例如,可将值类型的参数编码为变长编码,将引用类型的参数(如数组、字符串)等编码为定长编码。例如,在上述实例中,可对bool型的参数z采用变长编码,对bytes型的参数name和数组型的参数data采用定长编码,从而减少最终编码的字节数。
在区块链中的任一节点(例如所述第一节点)获取调用智能合约的交易之后,由节点中的EVM从该交易读取该智能合约的地址和上述输入编码数据,以用于后续的对智能合约的执行。在一个实施例中,可在交易中包括智能合约地址和智能合约输入参数的取值,并在该第一节点中通过对输入参数的取值进行编码,从而获取相应的输入编码数据,并由EVM进行读取。
在步骤S204,基于所述智能合约地址获取所述智能合约。所述智能合约即为EVM可执行程序,以面向对象的编程作类比,部署在区块链中的智能合约相当于该智能合约类的一个对象,合约地址相当于该合约对象的指针。EVM在获取合约地址之后,会根据合约地址找到合约的具体可执行程序。
在步骤S206,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值。
对所述输入编码数据的解码与上述获取输入编码数据的编码过程是相对应的,在此不再赘述。如上文所述,在所述输入编码数据中,包括程序指示字段和与各个参数对应的字段,从而基于所述输入编码数据,可确定所述智能合约中的待调用程序及其中的输入参数的取值。其中,可以通过同样的编码方法获取智能合约中各个程序的标识编码,并将各个标识编码与输入编码数据中程序指示字段中的编码相匹配,匹配一致的标识编码对应的程序即为待调用程序,该待调用程序可以为函数或者事件。
在步骤S208,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在确定待调用程序及其中N个参数各自的取值之后,在EVM中可执行该程序。在该待调用程序为函数的情况中,该函数可包括返回参数,则执行结果为返回参数的取值,或者该函数可能不包括返回参数,例如执行从图1中的Bob账户到Alice账户的转账,则执行结果为Bob账户和Alice账户的账户余额变化。在该待调用程序为事件的情况中,则所述执行结果为根据相应事件和参数生成相应的日志。
在所述第一节点为记账节点、且所述待调用程序为函数的情况中,在获取函数执行结果之后,记账节点将该执行结果打包到区块中,并将该区块发送到区块链中。可以理解,所述第一节点不限于为记账节点,根据区块链的结构、配置的不同,所述第一节点可以为其它形式的节点,例如,其可以为区块链中的任一节点。
在EVM执行所述待调用程序并输出程序返回值的情况中,所述输出同样为具有上述图4所示编码规范的编码数据。例如,所述待调用程序包括M个返回参数,M为自然数,其中,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果包括:在节点EVM中基于所述N个参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值,其中,所述M个返回参数各自的取值为二进制字符串;基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M+1个字段,其中,第1个字段为具有第四预定字节数的编码指示字段,所述编码指示字段中的前至少M位与所述输出编码数据中的从第2个字段开始的至少M个字段分别一一对应,每一位用于指示相应字段是否为所述变长编码,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数;以及通过对所述输出编码数据解码,获取所述M个返回参数各自的取值。其中,所述第四预定字节数可根据输出数值的取值范围确定,例如,其可以设置为32字节。
图5示出根据本说明书实施例的一种智能合约执行方法,所述方法在区块链中第一节点执行,所述方法包括:
在步骤S502,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,所述输入编码数据包括至少N+1个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,从第2个字段开始的至少N个字段的每个字段对应于所述N个参数中的一个参数,其中,所述至少N个字段的每个字段都为变长编码,所述变长编码包括第一部分和第二部分,所述第一部分具有第二预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
在步骤S504,基于所述智能合约地址获取所述智能合约;
在步骤S506,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
在步骤S508,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
该方法与图2所示方法不同在于,对于EVM执行合约时的输入数据和输出数据的编码规范进行了变化。图6示出了根据该实施例的输入编码数据的编码规范,如图6中所示,在该编码中,第一个字段与图4所示相同为程序指示字段,第二个字段至最后一个字段的每个字段分别对应于待调用程序的一个输入参数,且都是变长编码。由于从第二个字段至最后一个字段都采用了变长编码,因此在该编码规范中不包括图4中的参数编码指示字段。
相应地,在该方法中,在所述待调用程序包括M个返回参数的情况中,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果包括:在节点虚拟机中执行所述待调用程序,并返回输出编码数据,所述输出编码数据包括至少M个字段,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数,其中,所述每个字段都为变长编码,所述变长编码包括第一部分和第二部分,所述第一部分具有所述第二预定字节数,用于指示第二部分的字节数,所述第二部分为与相应返回参数对应的值;以及通过对所述输出编码数据解码,获取所述M个返回参数的取值。也就是说,该待调用程序的输出编码数据中的每个字段都与一个返回参数相对应且都为变长编码,其中也不包括参数编码指示字段。
图7示出根据本说明书实施例的一种智能合约执行装置700,所述装置部署在区块链中第一节点,所述装置包括:
第一获取单元71,配置为,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,其中,N为自然数,所述输入编码数据包括至少N+2个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,第2个字段为具有第二预定字节数的编码指示字段,所述编码指示字段中的前至少N位与所述输入编码数据中的从第3个字段开始的至少N个字段分别一一对应,每一位用于指示相应字段是否为变长编码,其中,所述至少N个字段中的每个字段对应于所述N个输入参数中的一个参数,所述变长编码包括第一部分和第二部分,所述第一部分具有第三预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
第二获取单元72,配置为,基于所述智能合约地址获取所述智能合约;
解码单元73,配置为,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
执行单元74,配置为,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述待调用程序为函数,所述装置还包括,更新单元75,配置为,在获取执行结果之后,将包括所述执行结果的区块发送到所述区块链中,以更新所述区块链中的区块。
在一个实施例中,所述待调用程序包括M个返回参数,M为自然数,其中,所述执行单元74包括:
执行子单元741,配置为,在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
编码子单元742,配置为,基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M+1个字段,其中,第1个字段为具有第四预定字节数的编码指示字段,所述编码指示字段中的前至少M位与所述输出编码数据中的从第2个字段开始的至少M个字段分别一一对应,每一位用于指示相应字段是否为所述变长编码,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数;以及
解码子单元743,配置为,通过对所述输出编码数据解码,获取所述M个返回参数各自的取值。
图8示出根据本说明书实施例的一种智能合约执行装置800,所述装置部署在区块链中第一节点,所述装置包括:
第一获取单元81,配置为,从区块链中获取调用智能合约的交易,以基于所述交易获取所述智能合约的合约地址及用于所述智能合约中待调用程序的输入编码数据,其中,所述待调用程序包括N个输入参数,所述输入编码数据包括至少N+1个字段,其中,第1个字段为具有第一预定字节数的基于所述待调用程序的程序标识生成的编码数据,从第2个字段开始的至少N个字段的每个字段对应于所述N个参数中的一个参数,其中,所述至少N个字段的每个字段都为变长编码,所述变长编码包括第一部分和第二部分,所述第一部分具有第二预定字节数,用于指示第二部分的字节数,所述第二部分为与相应参数对应的值;
第二获取单元82,配置为,基于所述智能合约地址获取所述智能合约;
解码单元83,配置为,对所述输入编码数据解码,以确定所述智能合约中的待调用程序,并获取所述N个输入参数各自的取值;以及
执行单元84,配置为,基于所述N个输入参数各自的取值执行所述待调用程序,以获取执行结果。
在一个实施例中,所述待调用程序包括M个返回参数,其中,所述执行单元84包括:
执行子单元841,配置为,在节点虚拟机中基于所述N个输入参数各自的取值执行所述待调用程序,以获取所述M个返回参数各自的取值;
编码子单元842,配置为,基于所述M个返回参数各自的取值、及预定的所述M个返回参数各自的类型,生成输出编码数据并从所述节点虚拟机输出,所述输出编码数据包括至少M个字段,其中,所述至少M个字段中的每个字段对应于所述M个返回参数中的一个参数,其中,所述每个字段都为所述变长编码;以及
解码子单元843,配置为,通过对所述输出编码数据解码,获取所述M个返回参数的取值。
本说明书另一方面提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行上述任一项方法。
本说明书另一方面提供一种计算设备,包括存储器和处理器,其特征在于,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现上述任一项方法。
通过根据本说明书实施例的智能合约执行方案,通过变长编码对智能合约的输入数据和输出数据进行压缩编码,大大减少了数据量,降低了对带宽的依赖,实现了高效率的合约交互。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于***实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
上述对本说明书特定实施例进行了描述。其它实施例在所附权利要求书的范围内。在一些情况下,在权利要求书中记载的动作或步骤可以按照不同于实施例中的顺序来执行并且仍然可以实现期望的结果。另外,在附图中描绘的过程不一定要求示出的特定顺序或者连续顺序才能实现期望的结果。在某些实施方式中,多任务处理和并行处理也是可以的或者可能是有利的。
本领域普通技术人员应该还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执轨道,取决于技术方案的特定应用和设计约束条件。本领域普通技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
结合本文中所公开的实施例描述的方法或算法的步骤可以用硬件、处理器执轨道的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(RAM)、内存、只读存储器(ROM)、电可编程ROM、电可擦除可编程ROM、寄存器、硬盘、可移动磁盘、CD-ROM、或技术领域内所公知的任意其它形式的存储介质中。
以上所述的具体实施方式,对本发明的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明的具体实施方式而已,并不用于限定本发明的保护范围,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。