Add extra information in transaction payload
AIP-129 - Add extra information in transaction payload
Section titled “AIP-129 - Add extra information in transaction payload”Summary
Section titled “Summary”This AIP changes the structure of a user transaction to support the upcoming orderless transactions feature. To support the orderless transaction feature, we had to add some extra information inside a user transaction. This AIP creates a way to add extra information info inside a user transaction.
Each transaction contains a TransactionPayload which could be either an entry function, script, or multisig. In this AIP, we add a new variant of TransactionPayload that can store both an executable (such as entry function, script), and some extra information.
Motivation
Section titled “Motivation”Suppose Alice sends a transaction to the blockchain saying “Transfer 10 APT from Alice to Bob”. What if an attacker copies Alice’s transaction and sends it again to the blockchain? The blockchain should be smart enough to discard the replayed transaction.
Aptos supports replay protection as follows. Each account should have a 0x1::Account resource stored on the blockchain. Amongst other info, 0x1::Account resource has a sequence_number: u64. Every time a transaction is committed, the sender account’s sequence number is incremented by 1. Each transaction also contains a sequence_number field. Only if transaction’s sequence number matches with the sender account’s onchain sequence number, the transaction is executed. This means, each transaction can be executed only once and can’t be replayed.
In order to create the 0x1::Account resource, it costs 0.001 APT at the moment. So, that’s the base fee for a new user to use the blockchain. To reduce the cost, we wish to eliminate the need for user to create a 0x1::Account resource to use the blockchain. This requires us to support an alternate replay protection mechanism that doesn’t use sequence numbers.
For this, we introduce orderless transactions. These transactions contain a nonce value (which could be picked randomly). The blockchain stores the list of (sender address, nonce) pairs of transactions committed in the last 60 seconds. When a transaction is submitted to the blockchain, the transaction is executed only if the (sender address, nonce) pair isn’t stored in the nonce table. We restrict the transaction expiration time to 60 seconds. So, the transaction can’t be replayed before its expiration time.
For the orderless transaction feature, we have to add new information (nonce) to a user transaction. At the moment, the transaction payload only stores an executable (entry function, script, multisig). To support this feature, we create a new transaction payload variant that will store both an executable and some extra information.
This AIP describes the changes in the transaction format. AIP 123 describes the structure of the nonce table and how the replay protection is done.
Specification
Section titled “Specification”The current TransactionPayload looks as follows.
enum TransactionPayload { Script(s), ModuleBundle(_) <-- Deprecated EntryFunction(e), Multisig(m),}The new TransactionPayload looks as follows.
enum TransactionPayload { Script(s), ModuleBundle(_) <-- Deprecated EntryFunction(e), Multisig(m), Payload(TransactionPayloadInner)}
enum TransactionPayloadInner { V1 { executable: TransactionExecutable, extra_config: TransactionExtraConfig }}
enum TransactionExecutable { EntryFunction(e), Script(s), Empty}
enum TransactionExtraConfig { V1 { multisig_address: Option<Address>, replay_protection_nonce: Option<u64>, }}The TransactionExtraConfig contains an optional nonce field. If this field is set to some value, then the transaction is interpreted as an orderless transaction. If this field is set to None, then transaction is a regular sequence number based transaction. The user transaction contains a sequence_number: u64 field which was mandatory. This is left untouched. For orderless transactions, this field is ignored by the VM code. We recommend setting the sequence number to u64::MAX when using orderless transactions.
The TransactionExtraConfig also contains an optional multisig_address field. If this field is set to some value, then the transaction is interpreted as a multisig transaction. Earlier, when we introduced multisig transactions, we needed to store both multisig address along with an entry function payload inside the transaction. Back then, for simplicity, we chose to combine both into Multisig transaction payload variant. In this AIP, as we are introducing the TransactionExtraConfig in order to support adding extra information to the transaction, we chose to utilize this functionality for multisig transactions as well and added the multisig_address field in TransactionExtraConfig.
The TransactionPayloadInner and TransactionExtraConfig are versioned and designed to be extensible, in case more information needs to be added to support future applications.
The TransactionExecutable can be either an entry function or script or empty. A transaction executable can be empty only for multisig transactions. If a non-multisig transaction has an empty executable, the transaction will be discarded.
This means, there are two ways the same sequence number based transaction can be crafted. For example, these two transactions result in the same transaction output.
TransactionPayload::EntryFunction(e)TransactionPayload::Payload( TransactionPayloadInner::V1 { executable: TransactionExecutable::EntryFunction(e) extra_config: TransactionExtraConfig::V1 { multisig_address: None, replay_protection_nonce: None } })Transactions with both formats will be accepted in the near future. Over time, we plan to update our SDKs to craft all the future transactions in the new format.
This AIP introduces a new onchain feature flag called TRANSACTION_PAYLOAD_V2. If this flag is disabled, all the transactions crafted in the new format will be discarded by the VM.
Impact
Section titled “Impact”We need to update the dev infra to be able to support this feature.
The SDKs and wallets need to be updated to be able to craft transactions in the new format.
The indexer need to be updated to be able to index the new type of transactions.
The explorer need to be update to display the new type of transactions.
Reference Implementation
Section titled “Reference Implementation”https://github.com/aptos-labs/aptos-core/pull/16299
Timeline
Section titled “Timeline”The binary and framework code will be deployed on mainnet in May 2025.
The feature will be enabled in June 2025.
The dev tooling such as SDKs and indexer will be provided in May - June 2025.