智能合约函数的输入数据在发送到以太坊网络之前是如何用十六进制字符串打包的



我想了解这一点。为了解析私有链事务中的数据并获得为特定事务发送的输入数据,我尝试了许多解码器,但在某些时候,它们失败了。这是我尝试使用remix 的简单智能合约

contract simple{
uint256 deliveryID;
string status;
function stringAndUint(string _status,uint256 _deliveryID){
status=_status;
deliveryID=_deliveryID;
}
} 

生成的输入数据:0x3c38b7fd000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000010000000000000000000000000000006737461747573000000000000000000000000

我可以从上面解释以下内容。

  • 函数签名:0x3c38b7fd
  • _状态值:737461747573
  • _deliveryID:0c,但我不知道为什么737461747573之前会有4个和额外的6个
  • 函数"stringAndUint"的输入为:"status",12有人能帮我理解输入数据是如何生成的吗

试着看看这里http://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#argument-编码和此处http://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#use-动态类型

将编码拆分为32字节块得到:

  • 3c38b7fd(函数签名(
  • 0000000000000000000000000000000000000000000040(第一个参数的数据部分的位置,从参数块开始以字节为单位测量(
  • 0000000000000000000000000000000000000000000000000000000000000 c(12(
  • 00000000000000000000000000000000000000000000000000000000000006("状态"的长度。前面的0..040指向此处(
  • 737461747573000000000000000000000000000000000000000000000000000000000000000000("状态"然后将零填充到下一个32字节的倍数(

使用的编码是什么

Solidity使用"Contract ABI"规范进行编码。

额外的(十六进制(40和6是怎么回事

@Brendan关于这些值的回答比我的好,所以我将删除这一部分。我会把答案贴出来,因为下面的部分仍然有用

以程序方式再现

python中有一个ABI解码工具,名为eth-abi,您可以像这样使用:

from eth_utils import to_bytes
encoded = to_bytes(hexstr="0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000067374617475730000000000000000000000000000000000000000000000000000")
from eth_abi import decode_abi
decoded = decode_abi(['string', 'uint256'], encoded)
assert decoded == (b'status', 12)

最新更新