主页 > imtoken冷钱包app > 深入解读以太坊的nonce

深入解读以太坊的nonce

imtoken冷钱包app 2023-02-10 05:30:38

1. 什么是随机数?一个标量值,等于从该地址发送的交易数量,或者在具有关联代码的账户的情况下,该账户创建的合约数量。 -- 以太坊黄皮书

所有以太坊所有交易都是基于账户的,这与基于utxo的比特币不同,所以每笔交易都需要按顺序记录,nonce值就是这个顺序,nonce是原始地址的一个属性交易。它不存储在以太坊区块链上,而是通过计算从某个地址发送的交易数量来计算的。

随机数+1

每发起一笔交易,nonce 就会增加一。启蒙说明:

1.发送的每笔交易的外部账户 (EOA);

2.每个创建的合约的合约钱包

转账交易、合约调用其他合约等都是内部调用,所以nonce值保持不变。

操作 1:事务排序

eth以太坊

假设你想发送两笔交易,价值分别为 1 和 4 ETH,并希望它们被顺序打包。发送一笔交易后,您继续发送第二笔交易。

现在没有随机数,矿工不可能知道你维护交易顺序的意图。

如果您的第一笔交易(1 ETH)的 nonce 为 0(假设是新账户),那么 4 ETH 的交易的 nonce 为 1。矿工可以按照 nonce 的顺序打包交易。

功能2:防止重放攻击

如果传输过程中没有nonce,参数如下

{ 
    "gasPrice":"10000000000", 
    "to":"0xf40629b5F96567270794F0F29E55Ac9daDE14fFd,
    " value":" 10000000000000000000“, // 10 ETH
    " data":"",
    " v,r,s":"您的ECDSA签名的某些字节"
}

Transaction 被序列化后,例如:

eth以太坊

25de0d5a1693d4e45ce0305d42774b5bf73cbd9e14230194c35545e0f01ee45ce0305d42774b5bf73cbd9e0d5a1693d4e45ce0305d427

交易打包后,对方会收到 10 ETH,但任何人都可以看到交易,然后复制粘贴,反复提交到以太坊网络,耗尽你的余额,即所谓的重放攻击。

如果一个交易包含一个nonce,那么具有相同nonce的交易只能被打包一次。

2.如何使用nonce?

下图是交易被打包的过程,

image.png

以太坊中有一个 txpool,是一个存储交易的池。钱包或节点产生的交易将被添加到交易池中。打包块时,将从该池中提取它们。区块生成后,共识区块和交易将上传到链上。所以交易会处于挂起状态,或者被交易池丢弃。

eth以太坊

发起转账或创建合约时,通过web3从以太坊网络查询当前nonce值,将该值作为当前交易的nonce值,发送到以太坊网络。

发送交易 eth_sendTransaction

如果数据字段包含代码,则创建新的消息调用交易或合同创建。

需要传递参数nonce,官方文档是对nonce的说明

nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

获取随机数 eth_getTransactionCount

参数:

eth以太坊

params: [
   address,
   QUANTITY  // latest, pending
]

演示

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xf40629b5F96567270794F0F29E55Ac9daDE14fFd","earliest"],"id":1}'  https://ropsten.infura.io/v3/404b78d3e9364b79921c39a8ea909b1c

结果:

{"jsonrpc":"2.0","id":1,"result":"0x5"}%

实际账户有5个转出Transaction,最后一笔交易的nonce是4。注意nonce计数从0开始,所以如果要继续发送交易,就用5作为下一笔交易的nonce。

如果有挂起的交易,即没有被矿工打包的交易,此时要读取nonce,需要将参数改为pending,否则无法获取正确的计数。没有区块确认的交易可以被“取消”或加速。

eth以太坊

如果交易被打包,即非待处理状态eth以太坊,则不可逆,无法取消!

3. 加速和取消以太坊交易 一个随机数的整数。这允许覆盖您自己的使用相同 nonce 的待处理事务

基于nonce特性,由于增加唯一性,可以加速重新初始化具有相同nonce的事务。

以太坊加速交易案例假设有一笔交易A:gas price = 5,nonce = 1,因为gas price太低,广播后交易一直处于pending状态。创建交易 B,将 gas 价格调整到更合理的水平,例如 10、20 ,nonce = 1 ,再次发出交易。矿工会选择价格更高的交易A进行打包。这时,在矿工的交易池端,B交易被打包,矿工会检查A交易,发现nonce已经存在。如果它认为 A 是一笔不合理的交易,它会自动丢弃该交易,并根据加速交易案例取消该交易。创建交易B,设置value=0,payee=sender,设置更高的gas价格,广播交易原来的交易被丢弃,新的交易会被矿工打包,不会损失任何资金。但是B交易还是需要支付矿工费4.异常处理

置换交易低价

原因账户有待处理的交易; new transactions 和 Pending transaction nonce 是一样的;新交易的 gas 价格较低,不能替代待处理的交易

image.png

5. nonce 使用的几个规则 当 nonce 太小(小于当前 nonce 值)时,会直接拒绝交易eth以太坊,nonce 太低的交易会立即被拒绝;当 nonce 太大,大于当前 nonce 时,事务会一直在队列中,nonce 过高的事务会被放入事务池队列中;当发送一个更大的 nonce 值,然后填充起始 nonce 和该值之间的 nonce 时,仍然可以执行事务。如果发送具有填充最后一个有效随机数和过高随机数之间的间隙的随机数的交易并且随机数序列完成,则序列中的所有交易都将得到处理和挖掘。交易队列最多只能保存同一个账户发送的64笔交易,也就是说,如果要批量转账,同一个节点发送的交易不能超过64笔。事务池队列最多只能容纳 64 个具有相同 From:address 且 nonce 乱序的事务。当某个节点的队列中还有事务,但此时停止geth客户端,队列中的事务将被清除,当geth实例关闭并重新启动时,事务池队列中的事务消失。当前nonce是合适的,但是当账户余额不足时,会被以太坊拒绝; 6.参考