diff --git a/tips/TIP-0020/tip-0020.md b/tips/TIP-0020/tip-0020.md new file mode 100644 index 000000000..d9ba32282 --- /dev/null +++ b/tips/TIP-0020/tip-0020.md @@ -0,0 +1,491 @@ +--- +tip: 20 +title: Transaction Payload with TIP-18 Output Types +description: Add output types, unlocks, and output features from TIP-18 into Transaction Payload +author: Levente Pap (@lzpap) +discussions-to: https://github.com/iotaledger/tips/pull/40 +status: Draft +type: Standards +layer: Core +created: 2021-11-18 +requires: 18 +replaces: 7 +--- + +# Summary + +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](../TIP-0024/tip-0024.md) and extends the transaction payload described in [TIP-7](../TIP-0007/tip-0007.md). + +# Motivation + +[TIP-7](../TIP-0007/tip-0007.md) 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](../TIP-0018/tip-0018.md), + - 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,](https://github.com/iotaledger/tips/discussions/51) + - 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. + +# Detailed design + +## UTXO + +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: + +![UTXO flow](utxo.png) + +## Structure + +### Serialized layout + +A _Transaction Payload_ is made up of two parts: +1. The _Transaction Essence_ part which contains the inputs, outputs and an optional embedded payload. +2. 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](../TIP-0007/tip-0007.md) 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](https://tools.ietf.org/html/rfc7693) 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](../TIP-0021/tip-0021.md): + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Payload Typeuint32 + Set to value 6 to denote a TIP-20 Transaction Payload. +
Essence oneOf +
+ Transaction Essence +
+ Describes the essence data making up a transaction by defining its inputs, outputs and an optional payload. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Transaction Typeuint8 + Set to value 1 to denote a TIP-20 Transaction Essence. +
Network IDuint64 + The unique value denoting whether the block was meant for mainnet, shimmer, testnet, or a private network. It consists of the first 8 bytes of the BLAKE2b-256 hash of the network name. +
Inputs Countuint16The number of input entries.
Inputs anyOf +
+ UTXO Input +
+ Describes an input which references an unspent transaction output to consume. +
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Input Typeuint8 + Set to value 0 to denote an TIP-20 UTXO Input. +
Transaction IDByteArray[32]The BLAKE2b-256 hash of the transaction payload containing the referenced output.
Transaction Output Indexuint16The output index of the referenced output.
+
+
Inputs CommitmentByteArray[32] + BLAKE2b-256 hash serving as a commitment to the serialized outputs referenced by Inputs. +
Outputs Countuint16The number of output entries.
Outputs anyOf +
+ Basic Output +
+ Describes a deposit to a single address. The output might contain optional features and native tokens. +
+
+
+ Alias Output +
+ Describes an alias account in the ledger. +
+
+
+ Foundry Output +
+ Describes a foundry that controls supply of native tokens. +
+
+
+ NFT Output +
+ Describes a unique, non-fungible token deposit to a single address. +
+
+
Payload Lengthuint32The length in bytes of the optional payload.
Payload optOneOf +
+ Tagged Data Payload +
+ Describes data with optional tag, defined in TIP-23. +
+
+
+
+
Unlocks Countuint16The number of unlock entries. It must match the field Inputs Count.
Unlocks anyOf +
+ Signature Unlock +
+ Defines an unlock containing a signature. +
+
+
+ Reference Unlock +
+ References a previous unlock, where the same unlock can be used for multiple inputs. +
+
+
+ Alias Unlock +
+ References a previous unlock of a consumed alias output. +
+
+
+ NFT Unlock +
+ References a previous unlock of a consumed NFT output. +
+
+
+ +### Transaction Essence + +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. + +#### Inputs + +The `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. + +##### UTXO Input + +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 + +The `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. + +In the `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](https://github.com/iotaledger/tips/discussions/51). + +#### Outputs + +The `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](../TIP-0007/tip-0007.md) have been removed and are no longer supported. + +| Output Name | Type Value | TIP | +| ----------- | ---------- | ------------------------------------------------------------------------------------------------------------ | +| Basic | 3 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#basic-output) | +| Alias | 4 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#alias-output) | +| Foundry | 5 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#foundry-output) | +| NFT | 6 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#nft-output) | + +#### Payload + +The _Transaction Essence_ itself can contain another payload as described in general in [TIP-24](../TIP-0024/tip-004.md). The [semantic validity](#semantic-validation) of the encapsulating _Transaction Payload_ does not have any impact on the payload. + +The following table lists all the payload types that can be nested inside a _Transaction Essence_ as well as links to the corresponding specification: + +| Name | Type Value | TIP | +|-------------|------------|-----------------------------------| +| Tagged Data | 5 | [TIP-23](../TIP-0023/tip-0023.md) | + +### Unlocks + +The `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 | +|-------------|------------|-----------------------------------------------------------------------------------------------------------------------| +| Signature | 0 | [TIP-20](#signature-unlock) | +| Reference | 1 | [TIP-20](#reference-unlock) | +| Alias | 2 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#alias-locking--unlocking) | +| NFT | 3 | [draft TIP-18](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#nft-locking--unlocking) | + +#### Signature Unlock + +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: + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Typeuint8 + Set to value 0 to denote a Signature Unlock. +
Signature oneOf +
+ Ed25519 Signature + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Signature Typeuint8 + Set to value 0 to denote an Ed25519 Signature. +
Public keyByteArray[32]The Ed25519 public key of the signature.
SignatureByteArray[64]The Ed25519 signature signing the Blake2b-256 hash of the serialized Transaction Essence.
+
+
+ +##### Unlock syntactic validation + +* `Signature` must contain an _Ed25519 Signature_. +* The _Signature Unlock_ must be unique, i.e. there must not be any other _Signature Unlocks_ in the `Unlocks` field of the transaction payload with the same signature. + +#### Reference Unlock + +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: + + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Typeuint8 + Set to value 1 to denote a Reference Unlock. +
Referenceuint16Represents the index of a previous unlock.
+ +##### Unlock syntactic validation + +* The _Reference Unlock_ at index i must have `Reference` < i and the unlock at index `Reference` must 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: +| Index | Unlock | +| ----- | ---------------------------------------------------------------------------------------- | +| 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. | + +## Validation + +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 [draft TIP-18](https://github.com/iotaledger/tips/pull/38) 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](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#output-design) and [feature type](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#output-features) separately. + +### Syntactic validation + +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: + +* Essence: + * `Transaction Type` value must denote a _TIP-20 Transaction Essence_. + * `Network ID` must match the value of the current network. + * Inputs: + * `Inputs Count` must be 0 < x ≤ `Max Inputs Count`. + * For each input the following must be true: + * `Input Type` must denote a _UTXO Input_. + * `Transaction Output Index` must be 0 ≤ x < `Max Outputs Count`. + * Each pair of `Transaction ID` and `Transaction Output Index` must be unique in the list of inputs. + * Outputs: + * `Outputs Count` must be 0 < x ≤ `Max Outputs Count`. + * For each input the following must be true: + * `Output Type` must match one of the values described under [Outputs](#outputs). + * The output itself must pass syntactic validation. + * The sum of all `Amount` fields must not exceed `Max IOTA Supply`. + * Payload (if present): + * `Payload Type` must match one of the values described under [Payload](#payload). + * Payload fields must be correctly parsable in the context of the `Payload Type`. + * The payload itself must pass syntactic validation. +* Unlocks: + * `Unlocks Count` must match `Inputs Count` of the _Transaction Essence_. + * For each unlock the following must be true: + * Each `Unlock Type` must match one of the values described under [Unlocks](#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 `Payload` field of the encapsulating object. + +### Semantic validation + +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](../TIP-0002/tip-0002.md#deterministically-ordering-the-tangle). + +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 ID` and `Transaction Output Index` is known (booked) and unspent. +* `Inputs Commitment` must equal BLAKE2( BLAKE2(O1) || … || BLAKE2(On) ), where O1, ..., On are the complete serialized outputs referenced by the `Inputs` field in that order. +* The transaction must spend the entire coin balance, i.e. the sum of the `Amount` fields of all the UTXOs referenced by inputs must match the sum of the `Amount` fields of all outputs. +* The sum of all `Native Token Counts` in the UTXOs referenced by inputs plus the sum of all `Native Token Counts` in the outputs must not be larger than `Max Native Token Count`. +* 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](https://github.com/lzpap/protocol-rfcs/blob/master/tips/TIP-0018/tip-0018.md#features) must pass semantic validation in the context of the following input: + 1. The _Transaction Payload_, + 2. the list of UTXOs referenced by inputs and + 3. 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_: + * The `Signature Type` must match the `Address Type` of the UTXO, + * the BLAKE2b-256 hash of `Public Key` must match the `Address` of the UTXO and + * the `Signature` field must contain a valid signature for `Public Key`. + * 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 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](../TIP-0004/tip-0004.md)). + +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. + +## Miscellaneous + +### Transaction timestamps + +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](../TIP-0008/tip-0008.md)) is used. + +### Address reuse + +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](https://en.bitcoin.it/wiki/Address_reuse) for further information. + +# Drawbacks + +* 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 + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/tips/TIP-0020/utxo.png b/tips/TIP-0020/utxo.png new file mode 100644 index 000000000..b29177df2 Binary files /dev/null and b/tips/TIP-0020/utxo.png differ