主页 > imtoken 官网 > 智能合约_以太坊的nonce简单来说

智能合约_以太坊的nonce简单来说

imtoken 官网 2023-11-03 05:13:46

1. 什么是随机数?

一个标量值,等于从此地址发送的交易数量,或者对于具有关联代码的帐户,等于该帐户创建的合约数量。 -- 以太坊黄皮书

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

随机数+1

每次发起交易时,nonce 都会加 1。 启动说明:

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

2.合约钱包每次创建合约

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

功能一:交易订单

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

比特币合约多空比_比特币智能合约_比特币合约交易中心

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

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

作用二:防止重放攻击

如果转账时没有nonce,参数如下

{ 
    "gasPrice":"10000000000", 
    "to":"0xf40629b5F96567270794F0F29E55Ac9daDE14fFd,
    " value":" 10000000000000000000“, // 10 ETH
    " data":"",

比特币智能合约_比特币合约交易中心_比特币合约多空比

" v,r,s":"您的ECDSA签名的某些字节" }

事务序列化后,例如:

25de0d5a1693d4e45ce0305d42774b5bf73cbd9e14230194c35545e0f01ee45ce0305d42774b5bf73cbd9e0d5a1693d4e45ce0305d427

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

如果一笔交易中包含一个nonce,则具有相同nonce的交易只能打包一次。

2.如何使用nonce?

下图展示了交易被打包的过程。

比特币智能合约_比特币合约多空比_比特币合约交易中心

比特币合约交易中心_比特币合约多空比_比特币智能合约

以太坊内部有一个txpool,是一个存储交易的池子。 来自钱包或节点的交易将被添加到交易池中。 当块被打包时,它将从这个池中提取。 区块生成后,共识区块将在链上进行交易。 因此交易将处于待处理状态,或者被交易池丢弃。

在发起转账或创建合约时,通过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.

获取 nonceeth_getTransactionCount

范围:

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笔转出交易,最后一笔交易的nonce为4。注意nonce计数从0开始,所以如果要继续发送交易,只需将5作为下一笔交易的nonce即可。

比特币合约交易中心_比特币合约多空比_比特币智能合约

如果有pending状态的交易,也就是没有被矿工打包的交易,此时要读取nonce,需要将参数改为pending,否则得不到正确的count。 没有区块确认的交易可以被“取消”或加速。

如果交易被打包,即没有pending,则不可逆,不可撤销!

3. 以太坊交易的加速和取消

随机数的整数。 这允许覆盖您自己使用相同随机数的未决交易

基于nonce、自增、唯一的特点,用相同的nonce重新发起交易,可以实现加速。

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

置换交易定价过低

原因 账户中有待处理的待处理交易; 新交易的nonce与待处理交易的nonce相同; 新交易的 gas price 较低,不能替代未决交易

比特币合约交易中心_比特币智能合约_比特币合约多空比

5. nonce使用的几个规则 当nonce太小(小于当前nonce值)时,交易会直接被拒绝,nonce太小的交易会被立即拒绝; 当nonce过大,大于当前nonce时,交易会一直在队列中,nonce过大的交易会被放入交易池队列; 当发送一个比较大的nonce值,然后填充start nonce和那个值之间的nonce,那么交易仍然可以执行,如果交易的nonce填补了最后一个有效的nonce和过高的nonce之间的空隙并且 nonce 序列是完整的,序列中的所有交易都将得到处理和挖掘。 交易队列最多只保存同一账户发送的64笔交易,换句话说,如果要批量转账,同一节点发送的交易不要超过64笔。 交易池队列最多只能容纳 64 个具有相同 From:address 且 nonce 乱序的交易。 当一个节点队列中还有交易比特币智能合约,但是此时geth客户端已经停止,队列中的交易就会被清空。 当 geth 实例关闭并重新启动时,交易池队列中的交易就会消失。 当前nonce是合适的,但是当账户余额不足时,会被以太坊拒绝;