以太坊中的nonce

2020-04-28  本文已影响0人  袁俊亮技术博客

以太坊中的nonce

为了防止交易重播,ETH(ETC)节点要求每笔交易必须有一个nonce数值。每一个账户从同一个节点发起交易时,这个nonce值从0开始计数,发送一笔nonce对应加1。当前面的nonce处理完成之后才会处理后面的nonce。注意这里的前提条件是相同的地址在相同的节点发送交易

以下是nonce使用的几条规则

获取nonce值

第一个思路就是由业务系统维护nonce值的递增。如果交易发送就出现问题,那么该地址下一笔交易继续使用这个nonce进行发送交易

第二个思路就是使用现有的api查询当前地址已经发送交易的nonce值,然后对其加1,再发送交易。对应的API接口为:eth_getTransactionCount,此方法由两个参数,第一个参数为需要查询nonce的地址,第二个参数为block的状态:latestearliestpending。一般情况使用pending就可以查询获得最新已使用的nonce

示例

async transfer () {
    try {
        let web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/"))
        let privateKey = Buffer.from("","hex")
        let from = "0xA25e7dCdfC50f1598Fc973C86A61179D74a012E2"

        let chainId = await web3.eth.getChainId()
        let txcount = await web3.eth.getTransactionCount(from)
        let nonce = web3.utils.numberToHex(txcount)
        
        let params = {
            from: from,
            to: "0x185A90160e604f8aAd4C9520660b9106A532A899",
            value: web3.utils.numberToHex(0.01 * 1e18),
            gasLimit: web3.utils.numberToHex(6721975),
            gasPrice: web3.utils.numberToHex(20000000000),
            nonce: nonce,
            chainId: chainId,
            data: "0x"
        }

        let tx = new Tx(params)
        tx.sign(privateKey)
        let serializedTx = tx.serialize();
        let result = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
        console.log(result)
    } catch (error) {
        console.log(error)
    }
}

Solidity中通过nonce防止重放攻击的示例

参考文章

上一篇 下一篇

猜你喜欢

热点阅读