Tóm lại
Hãy tưởng tượng bạn là một nhà giao dịch với nhiều cơ hội giao dịch chênh lệch giá. Bạn phát hiện ra ba cơ hội giao dịch chênh lệch giá cùng lúc, nhưng bạn chỉ có thể gửi từng giao dịch một. Khi giao dịch thứ ba của bạn được xử lý, cơ hội đó đã biến mất. Đây chính là vấn đề về tính tuần tự. Chúng tôi đề xuất một giải pháp mới, Nonce Bitmap, để cho phép gửi giao dịch song song trong các hệ thống blockchain mà vẫn duy trì tính bảo mật và khả năng tương thích với các ví hiện có.
- Tính song song . Nonce Bitmap giới thiệu phương pháp dựa trên bitmap cho phép người dùng gửi tối đa 256 giao dịch song song bằng cách sử dụng các bit ít được sử dụng trong trường nonce truyền thống.
- Chi phí lưu trữ tối thiểu . Nonce Bitmap yêu cầu chi phí lưu trữ tối thiểu (32 byte cho mỗi địa chỉ) so với các phương pháp thay thế.
- Khả năng tương thích ngược . Ví cũ và người dùng thông thường không thấy có thay đổi gì về hành vi.
- Bảo vệ chống phát lại . Bitmap Nonce bảo vệ các đảm bảo an ninh chống lại các cuộc tấn công phát lại đồng thời loại bỏ các nút thắt tuần tự.
- UX/DX tốt hơn . Nonce Bitmap đặc biệt có giá trị đối với những người dùng thường xuyên như nhà giao dịch, người tìm kiếm MEV và các giao thức cần gửi giao dịch đồng thời.
Cơ chế Nonce truyền thống
EVM Nonce: Hơn cả một công cụ đếm
Về cơ bản, nonce được liên kết với mỗi Tài khoản Sở hữu Bên ngoài (EOA) để biểu thị số lượng giao dịch đã được gửi từ tài khoản đó. Mỗi StateAccount duy trì một trường nonce tối đa 8 byte.
// StateAccount is the Ethereum consensus representation of accounts. // These objects are stored in the main account trie. type StateAccount struct {Nonce uint64 Balance *uint256.IntRoot common.Hash // merkle root of the storage trie CodeHash [] byte }Đối với một tài khoản mới, nonce bắt đầu từ số 0 và tăng lên một mỗi khi một giao dịch bắt nguồn từ tài khoản đó được đưa vào một khối. Mặc dù có vẻ đơn giản, bộ đếm này thực hiện các chức năng quan trọng cần thiết cho tính toàn vẹn và hoạt động xác định của EVM.
Bảo mật . Nonce được sử dụng để ngăn chặn các cuộc tấn công lặp lại bằng cách yêu cầu mỗi giao dịch bắt nguồn từ một địa chỉ phải sử dụng một nonce duy nhất. Do đó, bất kỳ nỗ lực nào gửi lại cùng một giao dịch hai lần sẽ thất bại vì mạng đã xác nhận việc sử dụng nonce này. Đảm bảo bảo mật này là nền tảng cho sự an toàn của tài sản và tương tác của người dùng trên blockchain.
Sắp xếp . Số nonce trong Ethereum đang tăng dần. Nghĩa là, mỗi giao dịch phải có số nonce lớn hơn số nonce của giao dịch trước đó một đơn vị.
next := opts.State.GetNonce(from) if next > tx.Nonce() { return fmt.Errorf( "%w: next nonce %v, tx nonce %v" , core.ErrNonceTooLow, next, tx.Nonce())} // Ensure the transaction doesn't produce a nonce gap in pools that do not // support arbitrary orderings if opts.FirstNonceGap != nil { if gap := opts.FirstNonceGap(from); gap < tx.Nonce() { return fmt.Errorf( "%w: tx nonce %v, gapped nonce %v" , core.ErrNonceTooHigh, tx.Nonce(), gap)}}Đếm giao dịch . Mặc dù định nghĩa về nonce được nêu trong Sách vàng của Ethereum , nhưng đây chỉ là hàm ý của thiết kế nonce hiện tại.
Nonce . Giá trị vô hướng bằng với số lượng giao dịch được gửi từ địa chỉ này hoặc, trong trường hợp tài khoản có mã liên kết, bằng số lượng hợp đồng được tạo bởi tài khoản này.
Với thiết kế hiện tại, việc đếm giao dịch (
eth_getTransactionCount) cho một địa chỉ nhất định được thực hiện bằng cách chỉ cần trả về nonce của tài khoản hiện tại.// GetTransactionCount returns the number of transactions the given address has sent for the given block number func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error ) { // Ask transaction pool for the nonce which includes pending transactions if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber {nonce, err := sbGetPoolNonce(ctx, address) if err != nil { return nil , err} return (*hexutil.Uint64)(&nonce), nil } // Resolve block number and use its state to ask for the nonce state, _, err := sbStateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil , err}nonce := state.GetNonce(address) return (*hexutil.Uint64)(&nonce), state.Error()}
Nhìn chung, thiết kế này cung cấp một cách đơn giản nhưng hiệu quả để giải quyết các cuộc tấn công phát lại, cho phép xác thực giao dịch hiệu quả và giảm dung lượng lưu trữ.
Thắt nút tuần tự
Thiết kế nonce hiện tại tạo ra tính tuần tự không thể tránh khỏi ở cấp độ tài khoản. Nghĩa là, ngay cả khi các giao dịch n+1 n + 1 và n n không liên quan (và có thể được thực hiện song song), giao dịch n+1 n + 1 vẫn phải chờ giao dịch n n vì các giao dịch của cùng một người gửi được xử lý theo thứ tự nonce.
Giao dịch bị kẹt là một vấn đề khác. Nếu người dùng gửi một giao dịch n n với giá gas quá thấp để được đưa vào khối, giao dịch này sẽ vẫn nằm chờ trong mempool cho đến khi được đưa vào, loại bỏ hoặc thay thế. Trong thời gian này, mọi nỗ lực gửi giao dịch tiếp theo từ người dùng này sẽ thất bại, bất kể giá gas. Điều này là không mong muốn và tạo ra trải nghiệm không tốt cho người dùng.
- Ví dụ, người dùng có thể có một giao dịch chuyển ETH đang chờ xử lý với mức phí tương đối thấp nhưng sau đó cần gấp một vị thế DeFi sắp bị thanh lý. Với thiết kế nonce hiện tại, người dùng phải chờ giao dịch bị kẹt hoặc phải thay thế giao dịch bị kẹt bằng một giao dịch khác sử dụng cùng nonce với mức phí gas cao hơn. Dù bằng cách nào, điều này cũng làm tăng thêm rất nhiều phức tạp mà người dùng thông thường có thể không xử lý được.
Bên cạnh đó, người dùng nâng cao (ví dụ: nhà giao dịch HFT) thường cần gửi giao dịch song song. Để làm được điều này, họ thường phải quản lý nonce cẩn thận ngoài chuỗi. Tuy nhiên, đây không phải lúc nào cũng là một nhiệm vụ dễ dàng . Ngay cả với quản lý ngoài chuỗi, người ta phải truy vấn 1) nonce hiện tại hoặc 2) biên lai của giao dịch trước đó để chọn gửi giao dịch hiện tại. Trong trường hợp độ trễ là yếu tố quan trọng, truy vấn này cũng gây ra một số độ trễ. Đặc biệt trong một blockchain như RISE, MegaETH, Monad, Flashblocks, nơi xử lý giao dịch cực kỳ nhanh ( thời gian xử lý <10ms ), việc truy vấn dữ liệu trên chuỗi có thể dẫn đến độ trễ từ hàng chục đến hàng trăm mili-giây.
Tệ hơn nữa, việc cố gắng gửi nhiều giao dịch song song (ngay cả với các nonce khác nhau) có thể dẫn đến lỗi khoảng cách nonce không hợp lệ. Điều này xảy ra vì quá trình truyền P2P hiện tại không đảm bảo rằng một giao dịch với nonce n n sẽ được đưa vào mempool của một nút trước giao dịch n+1 n + 1 .
Những hạn chế này trở nên đặc biệt nghiêm trọng trên các chuỗi có độ trễ thấp.
Hãy cùng khám phá xem các hệ thống khác đã cố gắng giải quyết vấn đề này như thế nào.
Phá vỡ tính tuần tự
Các chuỗi hiệu suất cao có thể xử lý hàng chục nghìn giao dịch mỗi giây (TPS) với độ trễ rất thấp. Tuy nhiên, việc tận dụng tối đa hiệu suất này không thể đạt được nếu không có trải nghiệm người dùng/ví điện tử tốt hơn. Các chuỗi này có khả năng xử lý nhiều giao dịch đồng thời, nhưng hiện tại, việc gửi giao dịch vẫn diễn ra tuần tự, tiềm ẩn nguy cơ cản trở việc khai thác tối đa tiềm năng của chúng.
Trong phần này, chúng ta sẽ xem xét một số thiết kế thay thế tiềm năng để giải quyết tính tuần tự này. Các thiết kế này chủ yếu tập trung vào khía cạnh bảo mật của nonce, trong đó nonce là một số được sử dụng một lần để bảo vệ chống lại tấn công phát lại.
Chúng tôi lưu ý rằng mặc dù việc sắp xếp và đếm giao dịch rất quan trọng, nhưng chúng có thể được thực hiện bằng nhiều cách tiếp cận khác nhau. Ví dụ: các dịch vụ (thường là trình duyệt) sử dụng eth_getTransactionCount này có thể trích xuất số liệu này bằng cách sử dụng cơ sở dữ liệu cục bộ của chúng.
Nonces ngẫu nhiên
Thay vì chỉ tăng nonce một cách nghiêm ngặt, thiết kế này cho phép các giao dịch mang các mã định danh duy nhất tùy ý, cho phép gửi và xử lý giao dịch song song. Mỗi tài khoản lưu giữ một bản ghi về tất cả các nonce đã sử dụng trước đó thay vì một bộ đếm vô hướng duy nhất. Ví dụ: điều này có thể được biểu diễn dưới dạng ánh xạ từ địa chỉ sang các tập hợp nonce đã sử dụng.
UsedNonces = map [Address] map [ uint64 ] boolKhi một giao dịch được gửi đi, nút sẽ xác thực nonce bằng cách kiểm tra xem nó đã được tài khoản đó sử dụng hay chưa. Nếu nonce chưa được sử dụng, giao dịch được chấp nhận và nonce được đánh dấu là đã sử dụng.
Phương pháp này cho phép các nút xử lý thực hiện song song các giao dịch (nếu không liên quan) từ cùng một người dùng, cải thiện đáng kể hiệu suất. Về phía máy khách, ví có thể tạo ra các nonce ngẫu nhiên mà không cần phải theo dõi hoặc đồng bộ hóa bộ đếm nonce một cách cẩn thận, giúp việc gửi giao dịch song song dễ dàng hơn. Một RPC bổ sung, chẳng hạn như eth_usedNonces , có thể được triển khai để truy xuất các nonce đã sử dụng cho một địa chỉ nhất định. Hơn nữa, eth_getTransactionCount có thể trả về độ dài của UsedNonces cho một địa chỉ nhất định.
Tuy nhiên, cách tiếp cận này cũng có những nhược điểm không hề nhỏ. Đáng chú ý nhất là chi phí lưu trữ, trong đó các nút phải lưu trữ và duy trì một tập hợp nonce đã sử dụng có thể rất lớn cho mỗi tài khoản, làm tăng kích thước trạng thái và độ phức tạp của bộ nhớ. Hơn nữa, tùy thuộc vào thuật toán tạo nonce ngẫu nhiên, hiện tượng trùng lặp nonce có thể xảy ra.
Thiết kế của Hyperliquid
Thay vì lưu trữ tất cả các nonce đã sử dụng cho một địa chỉ nhất định, Hyperliquid chỉ lưu trữ 100 nonce được sử dụng nhiều nhất cho mỗi địa chỉ, và yêu cầu thêm quy tắc để kiểm tra việc tái sử dụng nonce. Nghĩa là, một giao dịch mới phải có nonce lớn hơn nonce nhỏ nhất trong tập hợp này và chưa từng được sử dụng trước đó (tức là không tồn tại trong tập hợp). Hơn nữa, nonce phải nằm trong phạm vi 1 ngày kể từ dấu thời gian UNIX mili giây trên khối mà giao dịch được bao gồm. Ví dụ: đối với một giao dịch mới, nonce có thể được đặt theo dấu thời gian hiện tại.
Tương tự như thiết kế nonce ngẫu nhiên, Hyperliquid cung cấp khả năng song song tuyệt vời. Trải nghiệm người dùng (UX) cũng được cải thiện nhờ tính linh hoạt của ví khi lựa chọn các chiến lược nonce khác nhau và khả năng gửi giao dịch song song. Tính hợp lệ theo thời gian cũng làm giảm nguy cơ bị tấn công chuyển tiếp. So với thiết kế nonce ngẫu nhiên, phương pháp này tốn ít chi phí lưu trữ hơn vì chỉ lưu trữ 100 nonce đã sử dụng. Tuy nhiên, phương pháp này đi kèm với một điểm nghẽn là không thể gửi hơn 100 giao dịch song song.
Tuy nhiên, do việc quản lý nonce hoàn toàn khác biệt, một số thao tác có thể không tương thích ngược với các ví hiện có. Trên thực tế, thiết kế nonce này chỉ được sử dụng cho lớp HyperCore. Lớp HyperEVM vẫn sử dụng thiết kế nonce truyền thống. Bên cạnh đó, yêu cầu ràng buộc thời gian cũng giới hạn thời gian của các giao dịch được lên lịch (tức là các giao dịch được ký trước được lên lịch diễn ra trong hơn một ngày là không thể).
Nonces 2D
RIP-7712 giới thiệu cơ chế Nonce 2 chiều (2D Nonce) cho các giao dịch Trừu tượng Tài khoản (AA). Nonce 2D cho phép các tài khoản hợp đồng thông minh xử lý một hệ thống nonce linh hoạt và song song hơn. Một nonce 2D là một giá trị n - bit (ví dụ: n = 256 n = 256 trong AA) được chia thành hai thành phần logic:
┌─────────────────────────────────┬──────────────────────────┐│ Upper k bits │ Lower nk bits ││ (Nonce Key) │ (Nonce Sequence) │└─────────────────────────────────┴──────────────────────────┘- nonceKey .
nonceKeyđóng vai trò là một danh mục nonce phân chia không gian nonce thành nhiều danh mục độc lập.- Nonce cổ điển tương ứng với nonce 1D tương đương với việc có một danh mục nonce duy nhất (tức là
nonceKey = 0)
- Nonce cổ điển tương ứng với nonce 1D tương đương với việc có một danh mục nonce duy nhất (tức là
- nonceSequence .
nonceSequencelà một bộ đếm trong danh mục đó phải tăng dần theo thứ tự để có thể sắp xếp.
Các giao dịch với nonceKeys riêng biệt có thể được thực hiện hoặc bao gồm theo bất kỳ thứ tự nào, cho phép xử lý song song. Mặt khác, các giao dịch với cùng một nonceKey phải được thực hiện tuần tự, với số lượng nonceSequences tăng dần.
nonceKey xác định mức độ song song của một tài khoản. k k càng lớn thì số lượng giao dịch có thể được gửi song song càng nhiều. Về mặt lý thuyết, cấu trúc này cho phép một tài khoản duy trì tối đa 2^{k} 2 k danh mục, mỗi danh mục có khả năng chứa 2^{nk} 2 n − k nonce tuần tự. Điều này có nghĩa là một tài khoản có thể gửi tối đa 2^{k} 2 k giao dịch cùng một lúc mà không cần lo lắng về thứ tự nonce.
Tuy nhiên, nonceKey chủ yếu được sử dụng làm mã định danh cho một nhóm các giao dịch liên quan (ví dụ: khóa phiên, theo thời gian). Nếu sử dụng theo cách này, các giao dịch trong cùng một nhóm không thể được song song hóa. Ví dụ: nếu nonceKeys 1, 2, 3 được sử dụng cho các giao dịch hoán đổi, chuyển ETH và chuyển ERC-20 tương ứng, thì một tài khoản không thể gửi hai giao dịch hoán đổi, hoặc hai giao dịch ETH hoặc hai giao dịch ERC-20 song song. Tài khoản chỉ có thể gửi một giao dịch hoán đổi, một giao dịch ETH và một giao dịch ERC-20 cùng một lúc (liên quan đến việc quản lý nonce). Hơn nữa, mỗi nonceKey mới sẽ tạo ra thêm một chi phí lưu trữ n n bit để lưu trữ nonceKey và nonceSequence .
Đề xuất Bitmap Nonce
Trong phần này, chúng tôi đề xuất một cơ chế quản lý nonce mới cho phép một tài khoản gửi tối đa 256 giao dịch song song, với chi phí lưu trữ hơn một bit cho mỗi giao dịch song song. Hơn nữa, đề xuất này hoàn toàn tương thích ngược và không thêm bất kỳ trường nào vào quy trình gửi giao dịch.
Thiết kế
Giải pháp của chúng tôi mở rộng trạng thái tài khoản tiêu chuẩn để kết hợp nonce truyền thống với trường Bitmap để theo dõi việc sử dụng nonce. Với mỗi giá trị Nonce , chúng tôi cho phép tối đa 256 giao dịch với Index khác nhau. Trường Bitmap là trường 256 bit, trong đó mỗi bit đại diện cho một trong 256 khe cắm khả dụng (mỗi khe cắm tương ứng với một Index ) cho các giao dịch song song tại Nonce hiện tại. Nếu một giao dịch sửa đổi Nonce , trường Bitmap sẽ được đặt thành "xóa" và bit tại vị trí Index được đặt thành "1".
// NonceBitmapStateAccount is the Ethereum consensus representation of accounts accommodating with nonce bitmap. // These objects are stored in the main account trie. type NonceBitmapStateAccount struct {Nonce uint64 // Anchor nonce: the last finalized sequential checkpoint, always have first 8 bits as 0s. Balance *uint256.IntRoot common.Hash // merkle root of the storage trie CodeHash [] byte Bitmap *uint256.Int // NEW: Tracks used slots for parallel transactions; nil for legacy accounts } Cụ thể, Nonce vẫn đang tăng dần, giống như cách triển khai truyền thống. Tuy nhiên, 8 bit đầu tiên của Nonce luôn là 0. Chúng tôi quan sát thấy giá trị Nonce hiện tại là 64 bit, và chúng tôi kỳ vọng tài khoản sẽ không bao giờ sử dụng hết. Điều này là do giá trị Nonce 64 bit có thể sử dụng tới 2^{64} = 18446744073709551616 2 64 = 18446744073709551616 giá trị, và nếu một tài khoản gửi 1 tỷ giao dịch mỗi ngày, tài khoản đó sẽ mất hơn 50 triệu năm để sử dụng hết tất cả các nonce. Do đó, chúng tôi cho rằng không gian 56 bit là đủ cho một tài khoản ( 2^{56} = 72057594037927936 2 56 = 72057594037927936 giá trị).
Mỗi bit của Bitmap cho biết chỉ mục tại bit đó đã được sử dụng hay chưa. Ví dụ: nếu bitmap tại chỉ mục 10 được đặt thành 1, điều này có nghĩa là chỉ mục 10 đã được sử dụng cho Nonce hiện tại. Trường Bitmap 256 bit cho phép một tài khoản gửi tối đa 256 giao dịch cùng một lúc, theo bất kỳ thứ tự nào (không cần thứ tự nghiêm ngặt). Bằng cách sử dụng Bitmap , việc kiểm tra xem chỉ mục đã được sử dụng hay chưa rất hiệu quả. Hơn nữa, phương pháp này chỉ yêu cầu thêm một bit cho mỗi giao dịch song song.
Tạo giao dịch
Một thách thức quan trọng là báo hiệu khe song song đã chọn mà không làm gián đoạn các định dạng giao dịch hiện có. Điều cần thiết là người dùng có thể cấu hình Index khi tạo một giao dịch mới để hỗ trợ việc gửi các giao dịch song song. Một cách tiếp cận đơn giản là thêm một biến Index 8 bit mới vào các loại giao dịch hiện có. Trường Index này được sử dụng để xác định giá trị bit tương ứng của trường Bitmap trong trạng thái tài khoản của người gửi.
// LegacyTx is the transaction data of the original Ethereum transactions. type LegacyTx struct {Nonce uint64 // nonce of sender account GasPrice *big.Int // wei per gas Gas uint64 // gas limit To *common.Address `rlp:"nil"` // nil means contract creation Value *big.Int // wei amount Data [] byte // contract invocation input data V, R, S *big.Int // signature values ~~Index uint8 ~~ // NEW: The index value for parallelism? } May mắn thay, có một cách tốt hơn để thực sự tích hợp thông tin Index vào giao dịch mà không cần thêm trường mới. Chúng tôi giải quyết vấn đề này bằng kỹ thuật đóng gói bit, tận dụng không gian rộng lớn, chưa được sử dụng hết của trường Nonce 64 bit. Điều này được thực hiện bằng cách phân tách logic trường Nonce (trong giao dịch) thành hai phần riêng biệt, và việc trích xuất được thực hiện bằng các phép toán bitwise đơn giản:
func ExtractNonce (nonce uint64 ) (index uint8 , actualNonce uint64 ) {index = uint8 (nonce >> 56 ) // Extract first 8 bits (most significant bits) actualNonce = nonce & 0x00FFFFFFFFFFFFFF // Mask lower 56 bits return }- 8 bit đầu tiên của
Nonceđược sử dụng làmIndex. - 56 bit cuối cùng được sử dụng làm giá trị nonce thực tế. Như đã phân tích ở trên, không gian nonce 56 bit là đủ cho bất kỳ tài khoản nào.
Đối với người dùng thông thường, 8 bit đầu tiên luôn là 0. actualNonce là nonce tuần tự quen thuộc. Toàn bộ hệ thống dường như không thay đổi theo góc nhìn của họ. Đối với người dùng nâng cao, họ có thể đặt 8 bit đầu tiên thành bất kỳ giá trị nào, theo bất kỳ thứ tự nào. Điều này dẫn đến việc người dùng nâng cao có thể gửi tối đa 256 giao dịch song song.
Xác thực Nonce
Logic xác thực là cốt lõi của hệ thống, đảm bảo tính bảo mật và tiến độ. Khi có giao dịch mới, logic sau sẽ được thực thi (lưu ý rằng chúng tôi không tính đến các giao dịch thay thế phí):
func ValidateNonce (account *NonceBitmapStateAccount, txPackedNonce uint64 ) bool {index, actualNonce := ExtractNonce(txPackedNonce) if actualNonce == account.Nonce + 1 { // --- CASE 1: Advancing the Sequence --- // This transaction is the next in the sequential chain. // It is valid. This will cause the account's Nonce to increment. // The bitmap is reset, as we are moving to a new base state. return true } else if actualNonce == account.Nonce { // --- CASE 2: Parallel Transaction --- // This transaction operates at the current account's Nonce. // Check if the requested parallel slot is available. if account.Bitmap == nil { // Bitmap is not initialized; this is the first parallel tx at this nonce. return true } return account.Bitmap.Bit( int (index)) == 0 // True if the slot is free } else { // --- CASE 3: Invalid Nonce --- // actualNonce is either too old (less than account's Nonce) or has a gap. // This mirrors the existing Ethereum validation rule. return false }} Hãy xem xét chuỗi giao dịch sau. Nó bắt đầu với một tài khoản có Nonce hiện tại là 5 và Bitmap hiển thị khe 0 đã được sử dụng. Người dùng gửi thành công hai giao dịch song song (TxA và TxB) tại Nonce 5 bằng các khe khác nhau ( Index 2 và 3), và trình xác thực cập nhật bitmap để đánh dấu các khe này là đã sử dụng. TxA đã hoàn tất trong thời gian trình xác thực xử lý TxB nhưng không tạo ra bất kỳ xung đột nào.
Tuy nhiên, khi người dùng cố gắng gửi một giao dịch khác (TxC) để sử dụng lại Index 2 đã được sử dụng, trình xác thực sẽ từ chối giao dịch đó vì nó là giao dịch trùng lặp. Hệ thống sau đó sẽ tiếp tục khi người dùng gửi TxD với Nonce 6, kích hoạt cập nhật nonce: Nonce hiện tại tăng lên 6 và Bitmap được cập nhật theo Index của TxD. Việc tăng nonce này rất quan trọng vì khi người dùng cố gắng gửi TxE với Nonce 5 đã cũ, trình xác thực sẽ từ chối giao dịch đó vì hệ thống đã chuyển sang giao dịch tiếp theo, ngăn chặn việc phát lại các giao dịch cũ.
Phân tích & Cân nhắc
Phương pháp Nonce Bitmap giải quyết trực tiếp vấn đề tuần tự gây khó khăn cho người dùng tần suất cao trong khi vẫn đảm bảo tính bảo mật và khả năng tương thích ngược cần thiết cho blockchain EVM.
Sự đơn giản
Thiết kế này khá đơn giản để triển khai. Về cơ bản, hệ thống hoạt động dựa trên nguyên lý trực quan: duy trì một Nonce tuần tự cho người dùng thông thường trong khi sử dụng Bitmap để theo dõi các hoạt động song song trong mỗi bước. Logic thao tác bit để kiểm tra và cập nhật Bitmap rất đơn giản về mặt tính toán, sử dụng các phép toán bitwise hiệu quả mà bộ xử lý xử lý gốc. Độ phức tạp tổng thể vẫn thấp so với các nonce ngẫu nhiên, phương pháp của Hyperliquid hoặc quản lý nonce 2D.
Hiệu quả và Hiệu suất
Phương pháp Bitmap đạt được mức giảm 64 lần chi phí lưu trữ (ở cùng mức độ song song) so với hệ thống nonce của Hyperliquid hoặc quản lý nonce 2D được sử dụng trong Account Abstraction. Hiệu quả này cho phép xử lý song song ở mức cao (mặc dù không phải là không giới hạn) trong khi vẫn duy trì mức độ mở rộng trạng thái tối thiểu (một bit cho mỗi giao dịch). Thiết kế này tận dụng không gian nonce 64 bit rộng lớn một cách khéo léo, phân vùng nó mà không ảnh hưởng đến tiến trình tuần tự đảm bảo tính bảo mật.
Khả năng tương thích ngược
Điểm mạnh quan trọng của phương pháp này là khả năng tương thích ngược liền mạch. Đối với đại đa số người dùng và ứng dụng, hệ thống không yêu cầu bất kỳ thay đổi nào. Các ví cũ tiếp tục hoạt động mà không thay đổi gì vì các giao dịch của chúng tự động sử dụng Index zero trong cấu trúc Bitmap . Hệ thống duy trì ngữ nghĩa nonce tuần tự quen thuộc cho các ứng dụng hiện có, đồng thời mở khóa tính song song cho các ví được nâng cấp. Hoạt động chế độ kép này đảm bảo quá trình chuyển đổi hệ sinh thái diễn ra suôn sẻ mà không yêu cầu nâng cấp đồng bộ giữa tất cả các bên tham gia.
Tuy nhiên, cần lưu ý rằng người dùng không nên mặc định rằng eth_getTransactionCount luôn trả về tổng giao dịch cho một tài khoản. Vấn đề này cũng được tìm thấy trong Nonces 2D hoặc phương pháp của Hyperliquid. Lưu ý rằng eth_getTransactionCount chủ yếu được sử dụng cho hàm PendingNonceAt . Với việc PendingNonceAt được thiết kế lại, RPC này có thể bị loại bỏ/vô hiệu hóa đối với người dùng nâng cao. Đối với các dịch vụ khác (thường là trình duyệt) sử dụng eth_getTransactionCount này, họ có thể trích xuất số liệu này bằng cách sử dụng cơ sở dữ liệu cục bộ của mình.
Ai được lợi từ Nonce Bitmap?
- Giao dịch viên tần suất cao. Gửi nhiều giao dịch cùng lúc mà không cần quản lý nonce phức tạp. Giảm độ trễ bằng cách loại bỏ nhu cầu truy vấn trạng thái nonce giữa các giao dịch.
- MEV Searchers. Gửi các gói giao dịch có thể được xử lý song song, cải thiện tốc độ thực hiện và tỷ lệ thành công.
- Người dùng/Cá voi DeFi nâng cao. Thực hiện các chiến lược phức tạp liên quan đến nhiều giao thức cùng lúc mà không phải lo lắng về thứ tự giao dịch hoặc giao dịch bị kẹt.
- Nhà phát triển. Xây dựng các ứng dụng có thể gửi nhiều giao dịch hiệu quả hơn, cải thiện trải nghiệm người dùng và giảm độ phức tạp trong vận hành.
- Người dùng thông thường. Không có thay đổi nào, hệ thống vẫn tương thích ngược với các ví hiện có.
So sánh với các phương pháp tiếp cận khác
| Tiếp cận | Nguyên bản | Ngẫu nhiên | Siêu lỏng | 2D Nonce | Bản đồ bit Nonce |
|---|---|---|---|---|---|
| Đặt hàng | Đúng | KHÔNG | Một phần | Một phần | Một phần |
| Xác thực | Đơn giản | Đơn giản | Phức tạp hơn (kết hợp với thời gian) | - Giống như cách tiếp cận ban đầu dành cho người dùng thông thường - Phức tạp hơn một chút đối với người dùng nâng cao | - Giống như cách tiếp cận ban đầu dành cho người dùng thông thường - Phức tạp hơn một chút đối với người dùng nâng cao |
| Sự song song | KHÔNG | Có, không giới hạn | Có, ~100 giao dịch | Có, tùy thuộc vào kích thước của nonceKey . | Có, tối đa 256 giao dịch |
| Số lượng giao dịch | Đơn giản | Đơn giản | Không tầm thường | Trung bình, cần cập nhật API | Không tầm thường |
| Khả năng tương thích của ví | Đúng | KHÔNG | KHÔNG | Có cho người dùng thường xuyên | Có cho người dùng thường xuyên |
| Lưu trữ bổ sung | KHÔNG | Theo dõi tất cả các nonce đã sử dụng | 8*100 byte (Theo dõi 100 nonce đã sử dụng cho mỗi địa chỉ) | 8 * nonceKeys đang hoạt động | 32 byte cho mỗi địa chỉ |
Phần kết luận
Phương pháp Nonce Bitmap chứng minh rằng thiết kế giao thức chu đáo có thể cho phép
Cải tiến đáng kể về trải nghiệm người dùng (UX) mà không ảnh hưởng đến bảo mật hoặc khả năng tương thích. Bằng cách quan sát thấy không gian nonce 64 bit đang bị sử dụng quá mức, chúng tôi mở khóa khả năng song song 256 chiều chỉ với 32 byte bổ sung cho mỗi tài khoản.
Đối với các chuỗi có độ trễ thấp, độ trễ giao dịch không còn bị giới hạn bởi thời gian khối nữa - mà bị giới hạn bởi tốc độ người dùng gửi giao dịch. May mắn thay, Nonce Bitmap đã loại bỏ được nút thắt này.





