8BTCCI: 13737.28 8BTCVI: 9536.84 24H成交额: ¥5557.21亿 总市值: ¥17302.19亿
为什么我们需要交易数据?

为什么我们需要交易数据?

财经网链上财经 发布在 区块链 海盗号 58660

你或许已经注意到,当在智能合约上进行交易时,交易会自动包含输入数据。在MyCrypto里被标记为“数据”,那么它的作用是什么呢?在本文中,我将从技术层面解释交易输入数据是什么,以及它怎么操作 。

什么是输入数据?

先来看一笔Token交易。某人将零个ETH发送到0xd26114cd6ee289accf82350c8d8487fedb8a0c07(OmiseGO合同地址),而Etherscan显示的是约为0.19 OMG Token发送到该地址 。那么EVM(以太坊虚拟机)是如何知道这个用户想要将0.19个Token转移到另一个地址的呢?

如果再次查看Etherscan,用户将看到这笔交易包含输入数据,这个数据可以被附加到交易的额外数据。这个数据可以是常规文本或数字(格式化为十六进制),但在这种情况下,使用输入数据来告诉合约运行特定的函数。合约是由一组函数构建的。例如,ERC-20 Token使用等函数将Token从A转移到B并分别获取地址的余额。对于上述交易,用户可以在Etherscan上看到函数被调用。

上述交易的原始输入数据为

用户可将这组十六进制值分成几个较小的组。开头的0x表示这是一个十六进制值,后面的8个字节(a9059cbb)是函数标识符。后面的32个字节是组中的函数参数(在这种情况下为64个十六进制字符)。因此,第一组是,第二组是

Etherscan中的格式化输入数据(默认):

十六进制是什么?

十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制。一般用数字0到9和字母A到F(或a~f)表示,其中:A~F表示10~15,这些称作十六进制数字

十六进制中的最大值为15,即4个位元(Bit)。将多个十六进制放在一起时,可以将每个十六进制采用二进制形式表示,再合并为十进制数。例如,可写为(=)和(=)。合并后为,它是92的二进制数。因此十六进制值写作92。

大多数编程语言使用前缀作为十六进制的标识符,将其与其他标识符区别开来(如常规小数,二进制数等)。

输入数据和智能合约

输入数据的主要用于与智能合约进行交互。大多数合约使用Contract ABI范式,诸如Etherscan的网站可以自动解码输入数据并显示确切的操作。在上述事例中,这笔交易使用ERC-20标准。这意味着所有可能的函数及签名可查。例如,函数的所有签名在ERC-20合约中通常表达为这意味着它将地址作为第一个函数调用时的实际参数,将未签名的256位元的数作为第二个函数调用时的实际参数(来自0到2²⁵⁶ -  1的数)。

函数签名

据我们了解,的函数签名是。每个ERC-20合约的签名都是相同的。如果合约对函数使用不同的调用时的实际参数,例如地址和(未签名的128位元的整数),则合约不符合ERC-20。

要获取函数的十六进制签名,我们必须从此函数的SHA-3(或Keccak-256)哈希值中获取前4个字节(8个十六进制字符)。要获得=Keccak-256哈希值,可以使用JavaScript库或诸如此类的在线工具。如果在此工具中填写,输出为。如果我们取前8个字符(忽略),将得到,与上述交易中的匹配。

另一个示例:ERC-20函数的函数签名为。如果采用这个函数的SHA-3哈希值,将得到

,前8个字符是。因此,的输入数据将以开头。  

地址和金额

每个实参(列表/数组和字符串除外)的长度为32个字节,或64个十六进制字符,但以太坊地址长度仅为40个字符(不含)。为了解释这一点,地址用零填充。在一个十六进制值中,相同。因此,(地址)在交易中与相同。

相同。为什么要是用这么多零?

正如我们之前所了解的,Solidity合约中的最大数是2²⁵⁶ -  1,恰好是32个字节。使用固定长度可以使EVM和其他应用程序更容易解码数据。

数组和字符串?

如上所述,数组和字符串的输入数据的工作方式略有不同。数组可以视为一个元素列表。例如,在大多数编程语言中,1,2和3的列表写作。在交易中发送此数据,列表中的每个项目都将作为32字字节组发送,并列在输入数据的末尾。指向数组长度的指针用作实参。

例如,假设名为的函数,它的地址和数组表示为()。该函数的函数签名是。使用的地址与上述地址相同。因为数组包含3个元素,所以数组的长度为十六进制写作0x3。我们知道每个参数只占用32个字节的空间,并且数组放在其他参数之后,因此数组从32 + 32 = 64个字节开始。

此交易的输入数据将是:

因为字符串的长度可以是任意的(长度超过32个字节),所以它们被分成32个字节的组,并且与输入数据中的数组相同。

诸如Etherscan的网站如何解码输入数据?

哈希是单向函数,因此如果有函数签名哈希,就不可能从该哈希中获取函数签名(除非进行强制处理)。合同所有者可以将合约ABI上传为JSON,用来获取函数签名哈希值。

即使合约所有者没有上传合约ABI,也可以解码许多合约的输入数据。由于ERC-20合约函数的签名始终相同,因此,诸如Etherscan这样的网站可以简单地为这些合约使用预定义的合同ABI。例如,ERC-20合约的函数的合约ABI如下所示:

如果输入数据签名与预定义函数之一匹配,则Etherscan可以解码输入数据。

输入数据是否有限制?

以太坊对输入数据的长度没有固定限制,但输入数据确实消耗了gas。单个区块中的最大gas的数量波动,但在撰写本文时约为800万。每个0字节()消耗4个gas,每个非0字节消耗68个gas。标准交易的gas成本为21,000个gas,因此不考虑执行任何合约,现在输入数据的最大长度约为2兆字节,或仅非零的约0.12兆字节。由于输入数据不太可能只有零或非零,因此实际限制介于两者之间并取决于输入数据。

 

 

作者:Maarten Zuidhoorn

编译:LornaQ

原文链接:https://medium.com/mycrypto/why-do-we-need-transaction-data-39c922930e92

评论
登录 账号发表你的看法,还没有账号?立即免费 注册