Если у меня очень занятая учетная запись, скажем, я биржа и использую ретрансляционную учетную запись или что-то в этом роде / горячий кошелек, возможно, для обработки снятия средств, который обрабатывает и создает миллионы транзакций, будет ли проблема с постоянно увеличивающимся одноразовым номером транзакции ?
Существует ли какой-либо технический верхний предел для одноразовых номеров транзакций, например, в используемых базовых типах данных?
Из github — Go Ethereum — core/types/transaction.go, строки 46-54 :
type txdata struct {
AccountNonce uint64
Price, GasLimit *big.Int
Recipient *common.Address `rlp:"nil"` // nil means contract creation
Amount *big.Int
Payload []byte
V byte // signature
R, S *big.Int // signature
}
AccountNonce
представляет собой 64-битное целое число без знака с диапазоном от 0 до 2 ^ 64-1 (что составляет 18 446 744 073 709 551 616 из целых чисел без знака и со знаком ).
Судя по исходному коду Go Ethereum, не существует никаких других ограничений на диапазон одноразового номера.
Таким образом, вы можете безопасно создавать миллионы (x миллионов x миллионов) транзакций с одной и той же учетной записи.
И если вам интересно, вот вывод моих проверок операторов сравнения для переменной nonce.
user@Kumquat:~/EthereumSource/go-ethereum$ find . -type f -exec grep -H Nonce {} \; | grep "<"
./core/chain_pow.go:func verifyNoncesFromHeaders(checker pow.PoW, headers []*types.Header) (chan<- struct{}, <-chan nonceCheckResult) {
./core/chain_pow.go:func verifyNoncesFromBlocks(checker pow.PoW, blocks []*types.Block) (chan<- struct{}, <-chan nonceCheckResult) {
./core/chain_pow.go:func verifyNonces(checker pow.PoW, items []pow.Block) (chan<- struct{}, <-chan nonceCheckResult) {
./core/types/transaction_test.go: t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce())
./core/types/transaction.go:func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce }
./core/tx_pool.go: if pool.pendingState.GetNonce(addr) <= tx.Nonce() {
./core/tx_pool.go: if tx.Nonce() < trueNonce || balance.Cmp(tx.Cost()) < 0 {
./core/tx_pool.go: if past := state.GetNonce(sender) > tx.Nonce(); past || balance.Cmp(tx.Cost()) < 0 {
./core/tx_pool.go: if prev, ok := gaps[sender]; !ok || tx.Nonce() < prev {
./core/tx_pool.go:func (q txQueue) Less(i, j int) bool { return q[i].Nonce() < q[j].Nonce() }
user@Kumquat:~/EthereumSource/go-ethereum$ find . -type f -exec grep -H Nonce {} \; | grep ">"
./core/types/transaction_test.go: if fromi == fromj && txi.Nonce() > txj.Nonce() {
./core/types/transaction.go: if accTxs, ok := byNonce[acc]; ok && len(accTxs) > 0 {
./core/tx_pool.go: if currentState.GetNonce(from) > tx.Nonce() {
./core/tx_pool.go: if entry.Nonce() > guessedNonce {
./core/tx_pool.go: if past := state.GetNonce(sender) > tx.Nonce(); past || balance.Cmp(tx.Cost()) < 0 {
./core/tx_pool.go: if gap, ok := gaps[sender]; ok && tx.Nonce() >= gap {
Кажется, нет никаких проверок верхнего предела одноразового номера.