A scalar value equal to the number of transactions sent from this address or, in the case of accounts with associated code, the number of contract-creations made by this account. – 以太坊黄皮书
以太坊所有的交易都是基于 account ,不同于基于 utxo 的比特币,因此需要对每次交易都按顺序记录,nonce值就是这个顺序,nonce 是交易原始地址的属性。它不存储在以太坊区块链上,而是通过计算从一个地址发送的交易数量来计。
nonce +1
每发起一笔交易,nonce就会加一。对于发起的解释:
而转入交易、合约调用其他合约等属于内部调用,因此 nonce 值不变。
作用 1:交易顺序
假设您要发送两个值为 1 和 4 ETH 的交易,并希望它们被顺序打包。发送一笔交易后,你继续发送第二笔交易。
现在如果没有随机数,矿工将不可能知道您维护交易顺序的意图。
如果您的第一笔交易(1 ETH)的 nonce 为0(假设是新帐户),那么 4 ETH交易的 nonce 为 1。矿工即可按照 nonce 的顺序打包交易。
作用 2:防止重放攻击
假如转账时,没有 nonce,参数如下:
{
"gasPrice":"10000000000",
"to":"0xf4587a39edbb10b32952bcd656ba489f1a857450,
" value":" 10000000000000000000“, // 10 ETH
" data":"",
" v,r,s":"您的ECDSA签名的某些字节"
}
交易被序列化后(交易字符串转换为byte),例如:
25de0d5a1693d4e45ce0305d42774b5bf73cbd9e14230194c35545e0f01ee45ce0305d42774b5bf73cbd9e0d5a1693d4e45ce0305d427
该交易被打包后,对方将收到 10 ETH,但是任何人都可以看到这笔交易,然后复制粘贴,重复提交给以太坊的网络,耗尽你的余额,也就是所谓的重放攻击。
如果有交易中包含 nonce,则同一 nonce 的交易只能被打包一次。
下图为交易被打包的过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDRviZ3B-1624539141545)(https://z3.ax1x.com/2021/06/24/RQ3MUs.png)]
以太坊内部有 txpool,即存放交易的池子。钱包或节点发生的交易会被加入到交易池里,在打包区块的时候,就从这个池子里提取,区块产生之后,共识区块,交易上链。所以交易会有 pending 的状态,或者被交易池丢弃。
发起转账或者创建合约的时候,通过 web3 从以太坊网络查询当前的 nonce 值,使用此值作为当前交易的 nonce 值,发送到以太坊网络即可。
发送交易 eth_sendTransaction
Creates new message call transaction or a contract creation, if the data field contains code.
需要传参数 nonce,官方文档对于 nonce 的说明
nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
获取 nonce 获取 nonce
参数:
params: [
address,
QUANTITY // latest, pending
]
demo
//请求:
curl -s -H Content-Type:application/json -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xf4587a39edbb10b32952bcd656ba489f1a857450","pending"],"id":1}' http://127.0.0.1:8545
//返回:
{"jsonrpc":"2.0","id":1,"result":"0x351"}
//参数解释
第一个参数为需检查余额的地址
第二个参数为整数区块号,或者是字符串“latest","earliest"以及"pending"指代某个特殊的区块。
(latest:最新被挖矿的区块 earliest:最早区块 pending:挂起状态/交易 )
结果:
实际账户有 849 笔转出交易,最后一笔交易的 nonce 是 848。请注意 nonce 计数从 0 开始,所以如果你想继续发送交易,则直接使用 5 作为下一笔交易的 nonce 。
如果有处于 pending 状态的交易,即矿工未打包的交易,此时去读取 nonce,需要更换参数为 pending,否则将不能获得正确计数。没有区块确认数的交易可以被 ‘取消’ 或者被加速。
如果交易被打包,即非 pending 状态,则是不可逆的,就无法取消啦!
Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce
基于 nonce 的特性,自增和唯一性,使用相同的 nonce 重新发起交易即可实现加速。
加速以太坊交易案例
取消交易
具体加速和取消以太坊交易的处理方式可参考:https://blog.csdn.net/cljdsc/article/details/116275499
replacement transaction underpriced
原因