精通以太坊-交易
六、以太坊交易
交易是从外部账户发出的经过签名的消息,经传播后记录在区块链上。
6.1 交易结构
以太坊客户端在收到交易后会把交易保存在内存中并使用应用内部的交易格式,其中添加了一些推导出的数据,不具有普适性,这里讨论的交易格式为以太坊网络上交易传输时的交易格式,包括以下内容:
- nonce:由构建交易的外部账户提供,防止重放攻击
- gas price:支付的gas
- gas limit:最大gas
- recipient:接收方以太坊地址
- value:以太币数量
- data:见下文
- v,r,s:椭圆曲线签名的三个部分
使用RLP编码标准,其中不包含字段标识符,由长度偏移量表示每个字段的长度。
应用添加的数据:外部地址、交易ID等等——为了节约空间,交易中并不包含外部用户的地址,vrs可计算出外部用户的公钥,由公钥可得出外部用户的地址,交易ID同理。
6.2 交易的随机数
黄皮书中的定义:一个数值,等于这个地址发出的交易数量,当这个地址与合约关联时,是这个地址所创建的合约数量。
nonce可以说是发送方地址的一个属性,用于确定发出的交易的顺序以及避免交易重复,不会显示保存而是由已确认的交易动态计算出的。
交易待确认时getTransactionCount无法返回正确值,可用parity_nextNonce()计算下一个nonce。
6.3 交易的gas
独立的虚拟货币,和以太币有汇率关系。
最低可到0,但存在交易无法确认的可能。
由于合约所消耗的gas可能不同,所以需要设置gas limit
6.4 交易的接收方
接收方在交易的to字段中指定,字段中包含了一个20字节的以太坊地址,该地址可以是外部账户,也可以是合约的地址。
以太坊不会验证地址的正确性。
6.5 交易中的以太币和数据
交易只有value无data:支付操作
交易只有data无value:调用合约
交易既没有value也没有data:没作用,但允许存在
目的地址
如果目的地址为外部账户or未注册为合约的地址,以太坊会在目的账户余额中增加转入的以太币。
如果目的地址为合约,EVM则会执行这个合约,并调用data中指定的函数;若data中为空,则执行合约的回退函数。此时data中有以下部分:函数选择器、函数参数
6.6 特殊交易:合约创建
合约创建交易的目的地址是一个特殊的地址——零地址,即to字段为0x0,该地址永远不能用来支付以太坊or触发交易。
向合约创建地址发送只有value无data的交易相当于转账,也有专门销毁以太币的地址。
合约创建交易中的data为代码编译后的字节码,value中可以包含以太币作为合约的初始余额。
奇思妙想
- 后面的nonce会被搁置,那可不可以先发后面的nonce来实现智能合约的操作?
疑惑
- 交易触发合约执行?
- 交易中的data有什么用?——普通交易中data经常为空,调用智能合约函数的交易中data为函数名和参数。
- 交易中的随机数真的随机吗?
- 为什么向没有私钥的地址发送以太币相当于销毁以太币?——没有已知的私钥,以致无法生成签名来使用。
- 账户是否就等于地址?——账户由私钥和公钥定义,外部账户的地址为公钥哈希值的后20位字节,合约账户的地址则为该合约在区块链中的位置。账户通过地址表示。
- 交易目的地址为合约时,该合约是新的,还是别人已经写好了的?——应该是已经写好了的。