This TIP proposes a UTXO-based transaction structure consisting of all the inputs and outputs of a transfer. Specifically, this TIP defines a transaction payload for blocks described in TIP-24 and extends the transaction payload described in TIP-7.
TIP-7 describes the introduction of the UTXO ledger model for Chrysalis. This TIP extends the transaction model of the UTXO ledger to:
- accommodate for the new output types introduced in TIP-18,
- include a Network ID field in the transaction for replay protection,
- introduce Inputs Commitment field to prevent client eclipse attacks that would result in loss of funds,
- relax syntactic validation rules such that inputs and outputs of a transaction are no longer lexicographically ordered, furthermore outputs do not have to be unique.
The motivation for such changes is to provide a more flexible and secure framework for wallets and layer 2 applications. Chrysalis focused solely on using the ledger as a payment application, while Stardust transforms the ledger into a settlement layer for interconnected layer 2 blockchains and applications.
The unspent transaction output (UTXO) model defines a ledger state where balances are not directly associated to addresses but to the outputs of transactions. In this model, transactions reference outputs of previous transactions as inputs, which are consumed (removed) to create new outputs. A transaction must consume all the funds of the referenced inputs.
Using a UTXO-based model provides several benefits:
- Parallel validation of transactions.
- Easier double-spend detection, since conflicting transactions would reference the same UTXO.
- Replay-protection which is important when having reusable addresses. Replaying the same transaction would manifest itself as already being applied or existent and thus not have any impact.
- Balances are no longer strictly associated to addresses. This allows a higher level of abstraction and thus enables other types of outputs with particular unlock criteria.
Within a transaction using UTXOs, inputs and outputs make up the to-be-signed data of the transaction. The section unlocking the inputs is called the unlock. An unlock may contain a signature proving ownership of a given input's address and/or other unlock criteria.
The following image depicts the flow of funds using UTXO:
A Transaction Payload is made up of two parts:
- The Transaction Essence part which contains the inputs, outputs and an optional embedded payload.
- The Unlocks which unlock the inputs of the Transaction Essence.
The serialized form of the transaction is deterministic, meaning the same logical transaction always results in the same serialized byte sequence. However, in contrast to Chrysalis Phase 2 TIP-7 the inputs and outputs are considered as lists. They can contain duplicates and their serialization order matches the order of the list; they do not need to be sorted.
The Transaction Payload ID is the BLAKE2b-256 hash of the entire serialized payload data including unlocks.
The following table describes the entirety of a Transaction Payload in its serialized form following the notation from TIP-21:
|Payload Type||uint32||Set to value 6 to denote a TIP-20 Transaction Payload.|
Describes the essence data making up a transaction by defining its inputs, outputs and an optional payload.
|Unlocks Count||uint16||The number of unlock entries. It must match the field |
Defines an unlock containing a signature.
References a previous unlock, where the same unlock can be used for multiple inputs.
References a previous unlock of a consumed alias output.
References a previous unlock of a consumed NFT output.
The Transaction Essence of a Transaction Payload carries the inputs, outputs, and an optional payload. The Transaction Essence is an explicit type and therefore starts with its own Transaction Essence Type byte which is of value 1 for TIP-20 Transaction Essence.
Network ID field of the transaction essence serves as a replay protection mechanism.
It is a unique value denoting whether the transaction was meant for the IOTA mainnet, shimmer, testnet-1, or a private network. It consists of the first 8 bytes of the BLAKE2b-256 hash of the
Network Name protocol parameter, interpreted as an unsigned integer number.
|Network Name||Resulting ||Network Name defined in|
Inputs field holds the inputs to consume in order to fund the outputs of the Transaction Payload. Currently, there is only one type of input, the UTXO Input. In the future, more types of inputs may be specified as part of protocol upgrades.
Each input must be accompanied by a corresponding Unlock at the same index in the Unlocks part of the Transaction Payload.
A UTXO Input is an input which references an unspent output of a previous transaction. This UTXO is uniquely identified by its Output ID, defined by the Transaction ID of the creating transaction together with corresponding output index. Each UTXO Input must be accompanied by an Unlock that is allowed to unlock the referenced output.
Inputs Commitment field of the Transaction Essence is a cryptographic commitment to the content of the consumed outputs (inputs). It consists of the BLAKE2b-256 hash of the concatenated output hashes.
Inputs field, they are only referenced by Output ID. While the Output ID technically depends on the content of the actual output, a client has no way of validating this without access to the original transaction. For the
Inputs Commitment, the client has to be aware of the outputs’ content in order to produce a semantically valid transaction. This protects clients against eclipse attacks that would result in loss of funds.
Outputs field holds the outputs that are created by the Transaction Payload. There are different output types, but they must all have an
Amount field denoting the number of IOTA coins to deposit.
The following table lists all the output types that are currently supported as well as links to the corresponding specification. The SigLockedSingleOutput as well as the SigLockedDustAllowanceOutput introduced in Chrysalis Phase 2 TIP-7 have been removed and are no longer supported.
|Output Name||Type Value||TIP|
The following table lists all the payload types that can be nested inside a Transaction Essence as well as links to the corresponding specification:
Unlocks field holds the unlocks unlocking inputs within a Transaction Essence.
The following table lists all the output types that are currently supported as well as links to the corresponding specification. The Signature Unlock and the Reference Unlock are specified as part of this TIP.
|Unlock Name||Type Value||TIP|
The Signature Unlock defines an Unlock which holds a signature signing the BLAKE2b-256 hash of the Transaction Essence (including the optional payload). It is serialized as follows:
|Unlock Type||uint8||Set to value 0 to denote a Signature Unlock.|
Unlock syntactic validation
Signaturemust contain an Ed25519 Signature.
- The Signature Unlock must be unique, i.e. there must not be any other Signature Unlocks in the
Unlocksfield of the transaction payload with the same signature.
The Reference Unlock defines an Unlock which references a previous Unlock (which must not be another Reference Unlock). It must be used if multiple inputs can be unlocked via the same Unlock. It is serialized as follows:
|Unlock Type||uint8||Set to value 1 to denote a Reference Unlock.|
|Reference||uint16||Represents the index of a previous unlock.|
Unlock syntactic validation
- The Reference Unlock at index i must have
Reference< i and the unlock at index
Referencemust be a Signature Unlock.
Example: Consider a Transaction Essence containing the UTXO Inputs 0, 1 and 2, where 0 and 2 are both spending outputs belonging to the same Ed25519 address A and 1 is spending from a different address B. This results in the following structure of the Unlocks part:
|0||A Signature Unlock holding the Ed25519 signature for address A.|
|1||A Signature Unlock holding the Ed25519 signature for address B.|
|2||A Reference Unlock which references 0, as both require the same signature for A.|
A Transaction Payload has different validation stages, since some validation steps can only be executed when certain information has (or has not) been received. We therefore distinguish between syntactic and semantic validation.
The different output types and optional output features introduced by TIP-18 add additional constraints to the transaction validation rules, but since these are specific to the given outputs and features, they are discussed for each output type and feature type separately.
Syntactic validation is checked as soon as the transaction has been received. It validates the structure but not the signatures of the transaction. If the transaction does not pass this stage, it must not be broadcast further and can be discarded right away.
The following criteria defines whether a payload passes the syntactical validation:
Transaction Typevalue must denote a TIP-20 Transaction Essence.
Network IDmust match the value of the current network.
Inputs Countmust be 0 < x ≤
Max Inputs Count.
- For each input the following must be true:
Input Typemust denote a UTXO Input.
Transaction Output Indexmust be 0 ≤ x <
Max Outputs Count.
- Each pair of
Transaction Output Indexmust be unique in the list of inputs.
Outputs Countmust be 0 < x ≤
Max Outputs Count.
- For each output the following must be true:
Output Typemust match one of the values described under Outputs.
- The output itself must pass syntactic validation.
- The sum of all
Amountfields must not exceed
Max IOTA Supply.
- The count of all distinct native tokens present in outputs must not be larger than
Max Native Token Count.
- Payload (if present):
Payload Typemust match one of the values described under Payload.
- Payload fields must be correctly parsable in the context of the
- The payload itself must pass syntactic validation.
Unlocks Countmust match
Inputs Countof the Transaction Essence.
- For each unlock the following must be true:
Unlock Typemust match one of the values described under Unlocks.
- The unlock itself must pass syntactic validation.
- Given the type and length information, the Transaction Payload must consume the entire byte array of the
Payloadfield of the encapsulating object.
The Semantic validation of a Transaction Payload is performed when its encapsulating block is confirmed by a milestone. The semantic validity of transactions depends on the order in which they are processed. Thus, it is necessary that all the nodes in the network perform the checks in the same order, no matter the order in which the transactions are received. This is assured by using the White-Flag ordering as described in TIP-2.
Processing transactions according to the White-Flag ordering enables users to spend UTXOs which are created in the same milestone confirmation cone, as long as the spending transaction comes after the funding transaction in the aforementioned White-Flag order. In this case, it is recommended that users include the Block ID of the funding transaction as a parent of the block containing the spending transaction.
The following criteria defines whether a payload passes the semantic validation:
- Each input must reference a valid UTXO, i.e. the output referenced by the input's
Transaction Output Indexis known (booked) and unspent.
Inputs Commitmentmust equal BLAKE2( BLAKE2(O1) || … || BLAKE2(On) ), where O1, ..., On are the complete serialized outputs referenced by the
Inputsfield in that order.
- The transaction must spend the entire coin balance, i.e. the sum of the
Amountfields of all the UTXOs referenced by inputs must match the sum of the
Amountfields of all outputs.
- The count of all distinct native tokens present in the UTXOs referenced by inputs and in the transaction outputs must not be larger than
Max Native Token Count. A native token that occurs several times in both inputs and outputs is counted as one.
- The transaction is balanced in terms of native tokens, when the amount of native tokens present in all the UTXOs referenced by inputs equals to that of outputs. When the transaction is imbalanced, it must hold true that when there is a surplus of native tokens on the:
- output side of the transaction: the foundry outputs controlling outstanding native token balances must be present in the transaction. The validation of the foundry output(s) determines if the minting operations are valid.
- input side of the transaction: the transaction destroys tokens. The presence and validation of the foundry outputs of the native tokens determines whether the tokens are burned (removed from the ledger) or melted within the foundry. When the foundry output is not present in the transaction, outstanding token balances must be burned.
- Each output and all its output features must pass semantic validation in the context of the following input:
- The Transaction Payload,
- the list of UTXOs referenced by inputs and
- the Unix timestamp of the confirming milestone.
- Each unlock must be valid with respect to the UTXO referenced by the input of the same index:
- If it is a Signature Unlock:
Signature Typemust match the
Address Typeof the UTXO,
- the BLAKE2b-256 hash of
Public Keymust match the
Addressof the UTXO and
Signaturefield must contain a valid signature for
- If it is a Reference Unlock, the referenced Signature Unlock must be valid with respect to the UTXO.
- If it is an Alias Unlock:
- The address unlocking the UTXO must be an Alias Address.
- The referenced Unlock unlocks the alias defined by the unlocking address of the UTXO.
- If it is an NFT Unlock:
- The address unlocking the UTXO must be a NFT Address.
- The referenced Unlock unlocks the NFT defined by the unlocking address of the UTXO.
- If it is a Signature Unlock:
If a Transaction Payload passes the semantic validation, its referenced UTXOs must be marked as spent and its new outputs must be created/booked in the ledger. The Block ID of the block encapsulating the processed payload then also becomes part of the input for the White-Flag Merkle tree hash of the confirming milestone (TIP-4).
Transactions that do not pass semantic validation are ignored. Their UTXOs are not marked as spent and their outputs are not booked in the ledger.
Since transaction timestamps – whether they are signed or not – do not provide any guarantee of correctness, they have been left out of the Transaction Payload. Instead, the global timestamp of the confirming milestone (TIP-8) is used.
While, in contrast to Winternitz one-time signatures (W-OTS), producing multiple Ed25519 signatures for the same private key and address does not decrease its security, it still drastically reduces the privacy of users. It is thus considered best practice that applications and services create a new address per deposit to circumvent these privacy issues.
In essence, Ed25519 support allows for smaller transaction sizes and to safely spend funds which were sent to an already used deposit address. Ed25519 addresses are not meant to be used like email addresses. See this Bitcoin wiki article for further information.
- The new transaction format is the core data type within the IOTA ecosystem. Changing it means that all projects need to accommodate it, including wallets, web services, client libraries and applications using IOTA in general. It is not possible to keep these changes backwards compatible, meaning that all nodes must upgrade to further participate in the network.
- It is not possible to produce a valid transaction without having access to the content of the consumed outputs.
Rationale and alternatives
- Inputs Commitment and Network ID are both explicit fields of the transaction, while they could be made configuration parameters for the signature generating process. In this scenario the signature would be invalid if the parameters on client and network side mismatch. While this would reduce the size of a transaction, it would make it impossible to debug the reason for having an invalid signature and transaction. With the current solution we intend to optimize for ease of development.
- Uniqueness of all inputs is kept as it prevents introducing double spends in the same transaction.
Copyright and related rights waived via CC0.