以太坊中的两个nonce
第一个nonce:每一个区块有一个nonce
// Block represents an entire block in the Ethereum blockchain.
type Block struct {
header *Header
uncles []*Header
transactions Transactions
// caches
hash atomic.Value
size atomic.Value
// Td is used by package core to store the total difficulty
// of the chain up to and including the block.
td *big.Int
// These fields are used by package eth to track
// inter-peer block relay.
ReceivedAt time.Time
ReceivedFrom interface{
}
}
// Header represents a block header in the Ethereum blockchain.
type Header struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Number *big.Int `json:"number" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Time *big.Int `json:"timestamp" gencodec:"required"`
Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"`
}
【Block】中有个【Header】,【Header】最后一行的nonce,就是挖矿的随机数。
区块上的nonce是一个无意义的随机数,用于工作量证明,与挖矿的难度有关。
矿工要想成功挖出一个区块,必须不停的穷举随机数nonce,直到通过哈希算法得到的区块hash值小于或等于目标值target,目标值越低,发现随机数需要的时间越多,难度值越高。
第二个nonce,每一个账户的每笔交易有一个nonce
// Block represents an entire block in the Ethereum blockchain.
type Block struct {
header *Header
uncles []*Header
transactions Transactions
// caches
hash atomic.Value
size atomic.Value
// Td is used by package core to store the total difficulty
// of the chain up to and including the block.
td *big.Int
// These fields are used by package eth to track
// inter-peer block relay.
ReceivedAt time.Time
ReceivedFrom interface{
}
}
// Transactions is a Transaction slice type for basic sorting.
type Transactions []*Transaction
type Transaction struct {
data txdata
// caches
hash atomic.Value
size atomic.Value
from atomic.Value
}
type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit uint64 `json:"gas" gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" gencodec:"required"`
// Signature values
V *big.Int `json:"v" gencodec:"required"`
R *big.Int `json:"r" gencodec:"required"`
S *big.Int `json:"s" gencodec:"required"`
// This is only used when marshaling to JSON.
Hash *common.Hash `json:"hash" rlp:"-"`
}
每一个【Block】中都有很多个【Transaction】,而【Transaction】中的【txdata】就是每一笔交易,每一笔交易都有一个【AccountNonce】,用于解决双花问题,即防止多重交易。
为了防止多重交易,以太坊节点要求每笔交易必须有一个nonce数值。每一个账户从同一个节点发起交易时,这个nonce值从0开始计数,每发送一笔交易nonce值加1。只有当前面nonce值较小的交易处理完成之后才会处理后面nonce值较大的交易。
注意【相同的地址在相同的节点发送交易】。
nonce使用的规则
- 当nonce太小(小于之前已有交易的nonce值),交易会被直接拒绝。
- 当nonce太大,交易会一直处于队列之中,长久得不到执行。
- 当发送一个比较大的nonce值,然后补齐开始的nonce到那个nonce之间的nonce,那么交易依旧可以被执行。
- 当交易处于队列中时,停止geth客户端,那么交易队列中的交易会被清除。
- 当有一笔处于pending状态的交易,新的一笔交易与其拥有相同的nonce值,如果新交易的gas price太小,无法覆盖pending状态的交易,如果新交易的gas price高于原交易的110%,则原交易会被覆盖掉。
- 交易队列只保存最多64个从同一个账户发出的交易,The transaction pool queue will only hold a maximum of 64 transactions with the same From:address with nonces out of sequence. 也就是说,如果要批量转账,同一节点不要发出超过64笔交易。
- 当前nonce合适,但是账户余额不足时,会被以太坊拒绝;
- 如果发起一笔交易,但是因为gwei比较低或者网络比较忙的时候,该交易还没矿工挖出,可以通过使用相同的nonce和较高的gas费用,从而“覆盖”前一笔交易。
在以太坊客户端geth中连续转账两笔,查看nonce
> eth.getTransaction("0xd6f23949a9cf1a7589bb7eb7b02b16f78b8a29ddbdddf0e3722c147bbfbd9301")
{
blockHash: "0x5264afd8c81cb239cdf3f776371b00e79b688c7c00ce38cfb95664674179cc38",
blockNumber: 4443,
from: "0x59d2ee00982934e28ee74e292e2fc4da4a8a5bd1",
gas: 90000,
gasPrice: 18000000000,
hash: "0xd6f23949a9cf1a7589bb7eb7b02b16f78b8a29ddbdddf0e3722c147bbfbd9301",
input: "0x",
nonce: 0,
r: "0xcf8825845603f51c42e928243ed8174e86472046d55e94a3f3a6e65e1bb33007",
s: "0x4abe05a3d869c0f67c9c1f0fa35d860c7c75c61f6388fa1a44b37e8f7f8a49af",
to: "0xa0ba1d045f45eccfc1989615d22727d2124299e9",
transactionIndex: 0,
v: "0x38",
value: 12345000
}
> eth.getTransaction("0x4a7d0a5075939db5d3e9c4539a206d22e63adaf1993521f3cdcca0dc287b39ff")
{
blockHash: "0x186269bafa7ef5918a81dbbf731ad7e4609798bd3d9b34be4b329aa57ec7e279",
blockNumber: 4455,
from: "0x59d2ee00982934e28ee74e292e2fc4da4a8a5bd1",
gas: 90000,
gasPrice: 18000000000,
hash: "0x4a7d0a5075939db5d3e9c4539a206d22e63adaf1993521f3cdcca0dc287b39ff",
input: "0x",
nonce: 1,
r: "0x2018b43c281a895c34d2c99081e7ec1137625fdf01f9c396515a36469f2079bb",
s: "0x45a27df14d531ca421529702cf76066e47e0d350209e8603337f3b56de2ac21a",
to: "0xa0ba1d045f45eccfc1989615d22727d2124299e9",
transactionIndex: 0,
v: "0x38",
value: 15000000000000000000
}
>
根据交易id,即交易hash查看交易eth.getTransaction
,会看到第一笔转账的nonce
是0,第二笔是1。
参考文章
以太坊实战之《如何正确处理nonce》
以太坊实战|再谈nonce使用陷阱
以太坊nonce详解
以太坊rpc接口调用之nonce
转账以太币ETH
区块hash,随机数nonce,目标值target,难度值difficulty
以太坊入门(一)账户和nonce的关系
精通以太坊之nonce值,真的能避免51%攻击吗||技术贴
[以太坊源码]3.Block结构
关于nonce你应该知道的一些事
以太坊nonce值问题分析
今天的文章以太坊中的两个nonce值分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/29637.html