- 十进制数字与对应的十六进制字符 - 单个十六进制字符所能表示的最大数值是 15,长度是 4 个比特(bit)。多个十六进制字符相连时,你要把每个字符的二进制表示前后拼接在一起,才能得到其十进制数值。举个例子,0x5C,可以写成 0101 (=5) 和 1100 (=C),前后拼接就是 01011100,这就是二进制形式的 92,所以十六进制数 0x5C 的数值就是 92。 大多数编程语言都使用前缀 0x 作为绝对标识符(arbitrary identifier),将十六进制数与其他的计数类型(比如普通的十进制、二进制等)区别开来。这个前缀本身没有任何意义,只是为了清晰。我们这篇文章也会采取一样的做法,十六进制数都用 0x 开头。 讲完这些,我们继续。如果你还是没能理解十六进制,也不用担心 —— 对于理解 input data 来说不是必需的。 Input Data 与智能合约 Input Data 的首要用途就是与智能合约交互。大部分智能合约都使用 合约 ABI 规范,使得 Etherscan 这样的网站能自动解码 input data 并显示事务所调用的具体操作。在我们上面那个例子中,这是一笔有关代币合约的事务,而且代币合约遵循 ERC-20 标准。这也就意味着,我们都知晓所有可能调用的函数,以及它们的 签名。举例,用于 ERC-20 合约的 transfer(转账)函数的完整签名总是 transfer(address, uint256),意味着这个函数需要两个参数,所传入的第一个参数会被解读为一个地址,第二个参数会被解读为一个未签名的 256 位的数字(大小上限为 2256-1)。 Solidity 语言有多种参数类型。如果你有兴趣学习 Solidity 语言和智能合约,你可以在Solidity 文档页面了解更多。 函数签名 如你所见,transfer 函数的签名是 transfer(address, uint256),这个对所有 ERC-20 合约都是一样的。如果某个合约给转账函数安排不一样的参数类型,比如一个地址和一个 uint128(未签名的 128 位整数),这个合约就不是 “ERC-20 兼容” 的。 要获得一个函数的签名的十六进制形式,我们先要获得这个函数的 SHA-3(或者说 Keccak-256)哈希值的前面 4 个字节(也就是 8 个十六进制字符)。而要想知道一个数据的 Keccak-256 哈希值,你可以使用 JavaSceript 语言的 web3 库,或者求助于这样的在线工具。在这个工具页面填入 transfer(address,uint256),它会显示 0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b 作为结果。取前 8 个字符(忽略掉 0x),就是 a9059cbb,恰好跟上述事务的 MethodID 一致。 另一个例子:ERC-20 标准合约的 approve(许可)函数的函数签名是 approve(address,uint256),其 SHA-3 哈希值是 0x095ea7b334ae44009aa867bfb386f5c3b4b443ac6f0ee573fa91c4608fbadfba,首 8 个字符是 095ea7b3,因此,调用许可函数的 input data 开头就会是 0x095ea7b3。这笔发往 DAI token 合约的事务就是如此。 (责任编辑:admin) |