From 9bd3701d4eb55ae06d8dcfa960520c31bea42b46 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 5 May 2023 10:28:42 +0200 Subject: [PATCH 01/79] Add TIP-38 skeleton --- tips/TIP-0038/tip-0038.md | 1010 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1010 insertions(+) create mode 100644 tips/TIP-0038/tip-0038.md diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md new file mode 100644 index 000000000..b6c6c8a3e --- /dev/null +++ b/tips/TIP-0038/tip-0038.md @@ -0,0 +1,1010 @@ +--- +tip: TODO +title: TODO +description: TODO +author: TODO +discussions-to: TODO +status: Draft +type: Standards +layer: Core +created: 2023-05-03 +requires: TIP-19, TIP-20, TIP-21 and TIP-22 +--- + +# Table of Contents + +1. [Summary](#summary) +2. [Motivation](#motivation) +3. [Introduction to ledger programmability](#ledger-programmability) +4. [Building Blocks](#building-blocks) +5. [New concepts of output design](#new-concepts) + - [Native tokens](#native-tokens-in-outputs) + - [Chain constraint](#chain-constraint-in-utxo) + - [Unlock Conditions](#unlock-conditions) + - [Features](#features) +6. [Discussion](#drawbacks) +7. [Rationale and alternatives](#rationale-and-alternatives) +8. [Unresolved questions](#unresolved-questions) +9. [Copyright](#copyright) + +# Summary + +TODO: Adapt from TIP-18 summary. + +# Motivation + +TODO: Adapt from TIP-18 motivation. + +# Ledger Programmability + +The current UTXO model only provides support to transfer IOTA coins. However, the UTXO model presents a unique +opportunity to extend the range of possible applications by programming outputs. + +Programming the base ledger of a DLT is not a new concept. Bitcoin uses the UTXO model and attaches small executables +(scripts) that need to be executed during transaction validation. The bitcoin script language is however not +[Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness) as it can only support a small set of instructions +that are executed in a stack based environment. As each validator has to execute the same scripts and arrive at the +same conclusion, such scripts must terminate very quickly. Also, as transaction validation happens in the context of +the transaction and block, the scripts have no access to the global shared state of the system (all unspent transaction +outputs). + +The novelty of Ethereum was to achieve quasi Turing-completeness by employing an account based model and gas to limit +resource usage during program execution. As the amount of gas used per block is limited, only quasi Turing-completeness +can be achieved. The account based model of Ethereum makes it possible for transactions to have access to the global +shared state of the system, furthermore, transactions are executed one-after-the-other. These two properties make +Ethereum less scalable and susceptible to high transaction fees. + +Cardano achieves UTXO programmability by using the EUTXO model. This makes it possible to represent smart contracts in +a UTXO model as state machines. In EUTXO, states of the machine are encoded in outputs, while state transition rules +are governed by scripts. Just like in bitcoin, these scripts may only use a limited set of instructions. + +It would be quite straightforward to support EUTXO in IOTA too, except that IOTA transactions are feeless. There is no +reward to be paid out to validators for validating transactions, as all nodes in the network validate all transactions. +Due to the unique data structure of the Tangle, there is no need for miners to explicitly choose which transactions are +included in the ledger, but there still has to be a notion of objective validity of transactions. Since it is not +possible without fees to penalize scripts that consume excessive network resources (node CPU cycles) during transaction +validation, IOTA has to be overly restrictive about what instructions are supported on layer 1. + +It must also be noted that UTXO scripts are finite state machines with the state space restricted by the output and +transaction validation rules. It makes expressiveness of UTXO scripts inherently limited. In the context of complicated +application logic required by use cases such as modern DeFi, this leads to unconventional and complicated architectures +of the application, consisting of many interacting finite state machines. Apart from complexity and UX costs, it also +has performance and scalability penalties. + +For the reason mentioned above, **IOTA chooses to support configurable yet hard-coded scripts for output and +transaction validation on layer 1.** The general full-scale quasi Turing-complete programmability of the IOTA ledger is +achieved by extending the ledger state transition function with layer 2 smart contract chains. This not only makes it +possible to keep layer 1 scalable and feeless, but also allows to support any type of virtual machine on layer 2 to +program advanced business logic and features. + +Below, several new output types are discussed that implement their own configurable script logic. They can be viewed as +UTXO state machines in which the state of the machine is encoded as data inside the output. The state transition rules +are defined by the output type and by the parameters chosen upon deployment. + +# Building Blocks + +## Data Types & Subschema Notation + +Data types and subschemas used throughout this TIP are defined in [TIP-21](../TIP-0021/tip-0021.md). + +## Global Protocol Parameters + +Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA)](../TIP-0022/tip-0022.md) and [TIP-32 (Shimmer)](../TIP-0032/tip-0032.md). + +## Transaction Payload + +[TIP-20](../TIP-0020/tip-0020.md) is the basis for output validation in this TIP. + +## New Concepts + +New output types add new features to the protocol and hence new transaction validation rules. While some of these new +features are specifically tied to one output type, some are general, LEGO like building blocks that may be put in +several types of outputs. + +Below is a summary of such new features and the validation rules they introduce. + +### Native Tokens in Outputs + +Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which +funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user defined native +tokens, that is, tokens that are not IOTA coins but were minted by foundries and are tracked in the very same ledger. +Therefore, **every output must be able to hold not only IOTA coins, but also native tokens**. + +Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the +storage deposit requirements must be covered via IOTA coins. + +User defined tokens are called Native Tokens on protocol level. The maximum supply of a particular native token +is defined by the representation chosen on protocol level for defining their amounts in outputs. Since native tokens +are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the +maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the +maximum supply of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such huge amount of +assets on layer 1. + +Outputs must have the following fields to define the balance of native tokens they hold: + + + + + + + + + + + + + + + + +
NameTypeDescription
Native Tokens Countuint8The number of native tokens present in the output.
Native Tokens optAnyOf +
+ Native Token + + + + + + + + + + + + + + + + +
NameTypeDescription
Token IDByteArray[38] + Identifier of the native token. Derivation defined here. +
Amountuint256 + Amount of tokens. +
+
+
+ +#### Additional syntactic output validation rules: + +- `Native Tokens` must be lexicographically sorted based on `Token ID`. +- Each Native Token must be unique in the set of `Native Tokens` based on its `Token ID`. No duplicates are + allowed. +- `Amount` of any Native Token must not be `0`. + +#### Additional semantic transaction validation rules: + +- The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs + equals that of the created outputs. +- When the transaction is **imbalanced** and 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 in the foundry. + +### Chain Constraint in UTXO + +Previously created transaction outputs are destroyed when they are consumed in a subsequent transaction as an input. +The chain constraint makes it possible to **carry the UTXO state machine state encoded in outputs across transactions.** +When an output with chain constraint is consumed, that transaction has to create a single subsequent output that +carries the state forward. The **state can be updated according to the transition rules defined for the given type of +output and its current state**. As a consequence, each such output has a unique successor, and together they form a path +or *chain* in the graph induced by the UTXO spends. Each chain is identified by its globally unique identifier. + +![](chain-constraint.png) + +Alias outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique +identifiers. + +### New Functionality in Outputs + +The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some outputs +were specifically designed for such new features, some are optional additions that may be used with any outputs that +support them. + +These new functionalities are grouped into two categories: + - **Unlock Conditions** and + - simple **Features**. + +The [Output Design](#output-design) section lists all supported Unlock Conditions and Features for +each output type. + + +#### Unlock Conditions + +New output features that introduce unlocking conditions, that is, they define constraints on how the output can +be unlocked and spent, are grouped under the field Unlock Conditions. + +Each output **must not contain more than one unlock condition of each type** and not all unlock condition types are +supported for each output type. + +##### Address Unlock Condition + +It is merely a layout change that the previously defined `Address` field of outputs ([TIP-7](../TIP-0007/tip-0007.md)) +is represented as an Address Unlock Condition. Unlocking an Ed25519 Address doesn't change, it has to +be performed via a Signature Unlock in a transaction by signing the hash of the transaction essence. +Transaction validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). + +New additions are the Alias Address and NFT Address types, which have to be unlocked with their +corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs). + +
+ Address Unlock +
+ Defines the Address that owns this output, that is, it can unlock it with the proper Unlock in a + transaction. +
+
+ + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 + Set to value 0 to denote an Address Unlock Condition. +
Address +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Alias Address. +
Alias IDByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ +| :information_source: Good to know about address format | +|---------------------------------------------------------| + +The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, +which is the recommended address format for user facing applications. + +A usual bech32 encoded mainnet address starts with `iota1`, and continues with the bech32 encoded bytes of the address. +By choosing Address Type as a multiple of 8 for different address types, the first character after the `1` +separator in the bech32 address will always be different. + +| Address | Type Byte as `uint8` | Bech32 Encoded | +|---------|----------------------|----------------| +| Ed25519 | 0 | iota1**q**... | +| Alias | 8 | iota1**p**... | +| NFT | 16 | iota1**z**... | + +A user can identify by looking at the address whether it is a signature backed address, a smart contract chain account +or an NFT address. + +##### Storage Deposit Return Unlock Condition + +This unlock condition is employed to achieve conditional sending. An output that has +Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits +`Return Amount` IOTA coins into `Return Address`. When several of such outputs are consumed, their return amounts per +`Return Addresses` are summed up and the output side must deposit this total sum per `Return Address`. + +###### Additional syntactic transaction validation rule: + +- `Minimum Storage Deposit` is the storage deposit in the base currency required for a Basic Output that only + has an Address Unlock Condition, no additional unlock conditions, no features and + no native tokens. +- It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. + +###### Additional semantic transaction validation rule: + +- An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a + transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: + - are of type [Basic Output](#basic-output), + - have only an [Address Unlock Condition](#address-unlock-condition) defined, + - have no [Native Tokens](#native-tokens-in-outputs), and + - have no [Features](#features). +- When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, + their return amounts per `Return Addresses` are summed up and the output side of the transaction must deposit + _at least_ this total sum per `Return Address` via output(s) that satisfy the previous condition. + +
+ Storage Deposit Return Unlock Condition +
+ Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. +
+
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 + Set to value 1 to denote a Storage Deposit Return Unlock Condition. +
Return AddressoneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Alias Address. +
Alias IDByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Return Amountuint64 + Amount of IOTA coins the consuming transaction should deposit to Return Address. +
+ +This unlock condition makes it possible to send small amounts of IOTA coins or native tokens to addresses without having +to lose control of the required storage deposit. It is also a vehicle to send on-chain requests to ISCP chains that do not +require fees. To prevent the receiving party from blocking access to the storage deposit, it is advised to be used +together with the [Expiration Unlock Conditions](#expiration-unlock-conditions). The receiving party then has a sender-defined +time window to agree to the transfer by consuming the output, or the sender regains total control after expiration. + +##### Timelock Unlock Condition + +The notion of time in the Tangle is introduced via milestones. Each milestone +[carries the current unix timestamp](../TIP-0008/tip-0008.md#structure) +corresponding to that milestone index. Whenever a new milestone appears, nodes perform the white-flag ordering and transaction +validation on its past cone. The timestamp of the confirming milestone provide the time as an input parameter to +transaction validation. + +An output that contains a Timelock Unlock Condition can not be unlocked before the specified timelock has +expired. The timelock is expired when the timestamp of the confirming milestone is equal or past the timestamp defined +in the Timelock Unlock Condition. + +###### Additional syntactic transaction validation rules: +- `Unix Time` field of a Timelock Unlock Condition must be > `0`. +###### Additional semantic transaction validation rules: +- An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a + transaction, if the timestamp of the confirming milestone is equal or past the `Unix Time` specified in the unlock + condition. + +
+ Timelock Unlock Condition +
+ Defines a unix timestamp until which the output can not be unlocked. +
+
+ + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 + Set to value 2 to denote a Timelock Unlock Condition. +
Unix Timeuint32 + Unix time (seconds since Unix epoch) starting from which the output can be consumed. +
+ +##### Expiration Unlock Condition + +The expiration feature of outputs makes it possible for the return address to reclaim an output after a given expiration +time has been passed. The expiration can be specified as a unix timestamp. + +The expiration feature can be viewed as an opt-in receive feature, because the recipient loses access to the received +funds after the output expires, while the return address specified by the sender regains control over them. This feature +is a big help for on-chain smart contract requests. Those that have expiration set and are sent to dormant smart contract +chains can be recovered by their senders. Not to mention the possibility to time requests by specifying both a +timelock and an expiration unlock condition. + +###### Additional syntactic transaction validation rules: +- `Unix Time` field of an Expiration Unlock Condition must be > `0`. + +###### Additional semantic transaction validation rules: +- An output that has Expiration Unlock Condition set must only be consumed and + unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction that has a confirming + milestone timestamp earlier than the `Unix Time` defined in the unlock condition. +- An output that has Expiration Unlock Condition set must only be consumed and unlocked by the `Return Address` + in a transaction that has a confirming milestone timestamp same or later than the `Unix Time` defined in the unlock + condition. +- Semantic validation of an output that has Expiration Unlock Condition set and is unlocked by the + `Return Address` must ignore: + - [Semantic validation of Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) if present. + +The following table summarizes the outcome of syntactic and semantic validation rules with respect to which account +is allowed to unlock the output containing the Expiration Unlock Condition: + +| Milestone Unix Timestamp Condition | Outcome | +|-----------------------------------------------------|-----------------------------------------------| +| `Unix Time` = `0` | Output and containing transaction is invalid. | +| `Unix Time` > `Confirming Milestone Unix Timestamp` | Unlockable by `Address` | +| `Unix Time` ≤ `Confirming Milestone Unix Timestamp` | Unlockable by `Return Address` | + +
+ Expiration Unlock Condition +
+ Defines a unix time until which only Address, defined in Address Unlock Condition, is allowed to + unlock the output. After the unix time is reached/passed, only Return Address can unlock it. +
+
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 + Set to value 3 to denote a Expiration Unlock Condition. +
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Alias Address. +
Alias IDByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Unix Timeuint32 + Before this unix time, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. +
+ + +### Features + +New output features that do not introduce unlocking conditions, but rather add new functionality and add constraints on +output creation are grouped under Features. + +Each output **must not contain more than one feature of each type** and not all feature types are supported for each output +type. + +##### Sender Feature + +Every transaction consumes several elements from the UTXO set and creates new outputs. However, certain applications +(smart contracts) require to associate each output with exactly one sender address. Here, the sender feature is used to +specify the validated sender of an output. + +Outputs that support the Sender Feature may specify a `Sender` address which is validated by the protocol during +transaction validation. + +###### Additional semantic transaction validation rule: +- The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: + - Ed25519 Address: + - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. + - Alias Address: + - The Alias Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - NFT Address: + - The NFT Output that defines the address is consumed as input in the transaction. + +
+ Sender Feature +
+ Identifies the validated sender of the output. +
+
+ + + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 + Set to value 0 to denote a Sender Feature. +
Sender oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Alias Address. +
Alias IDByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ +##### Issuer Feature + +The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state +machine with [chain constraint](#chain-constraint-in-utxo) (alias, NFT). +Only when the state machine is created (e.g. minted) it is checked during transaction validation that an output +corresponding to the `Issuer` address is consumed. In every future transition of the state machine, it is instead +checked that the issuer feature is still present and unchanged. + +###### Additional semantic transaction validation rule: +- When an Issuer Feature is present in an output representing the initial state of an UTXO state machine, the + transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: + - Ed25519 Address: + - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. + - Alias Address: + - The Alias Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - NFT Address: + - The NFT Output that defines the address is consumed as input in the transaction. + +The main use case is proving authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) can +fill the Issuer Feature with their address that they have to unlock in the transaction. Issuers then can publicly +disclose their addresses to prove the authenticity of the NFT once it is in circulation. + +
+ Issuer Feature +
+ Identifies the validated issuer of the UTXO state machine. +
+
+ + + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 + Set to value 1 to denote an Issuer Feature. +
Issuer oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Alias Address. +
Alias IDByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ +Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the +chain's address, since user does not sign the layer 1 transaction. As a consequence, artist would have to mint NFTs +themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. + +##### Metadata Feature + +Outputs may carry additional data with them that is interpreted by higher layer applications built on the Tangle. The +protocol treats this metadata as pure binary data, it has no effect on the validity of an output except that it +increases the required storage deposit. ISC is a great example of a higher layer protocol that makes use of +Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. + +###### Additional syntactic transaction validation rules: +- An output with Metadata Feature is valid, if and only if 0 < `length(Data)` ≤ `Max Metadata Length`. + +
+ Metadata Feature +
+ Defines metadata (arbitrary binary data) that will be stored in the output. +
+
+ + + + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 + Set to value 2 to denote a Metadata Feature. +
Data(uint16)ByteArrayBinary data. A leading uint16 denotes its length.
+ +#### Tag Feature + +A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not +only by their address, but also based on the `Tag`. **The combination of a Tag Feature, a +Metadata Feature and a Sender Feature makes it possible to retrieve data associated to an address and stored +in outputs that were created by a specific party (`Sender`) for a specific purpose (`Tag`).** + +An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) plugin. + +##### Additional syntactic transaction validation rules: +- An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ + `Max Tag Length`. + +
+ Tag Feature +
+ Defines an indexation tag to which the output can be indexed by additional node plugins. +
+
+ + + + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 + Set to value 3 to denote a Tag Feature. +
Tag(uint8)ByteArrayBinary indexation tag. A leading uint8 denotes its length.
+ +# Drawbacks +- New output types increase transaction validation complexity, however it is still bounded. +- Outputs take up more space in the ledger, UTXO database size might increase. +- It is possible to intentionally deadlock aliases and NFTs, however client side software can notify users when they + perform such action. Deadlocked aliases and NFTs can not be unlocked, but this is true for any funds locked into + unspendable addresses. +- Time based output locking conditions can only be evaluated after attachment to the Tangle, during milestone + confirmation. +- IOTA ledger can only support hard-coded scripts. Users can not write their own scripts because there is no way + currently to charge them based on resource usage, all IOTA transactions are feeless by nature. +- Aliases can be destroyed even if there are foundries alive that they control. Since only the controlling alias can + unlock the foundry, such foundries and the supply of the tokens remain forever locked in the Tangle. +- Token schemes and needed supply control rules are unclear. + +# Rationale and alternatives + +The feeless nature of IOTA makes it inherently impossible to implement smart contracts on layer 1. A smart contract +platform shall not only be capable of executing smart contracts, but also to limit their resource usage and make users +pay validators for the used resources. IOTA has no concept of validators, neither fees. While it would technically be +possible to run EUTXO smart contracts on the layer 1 Tangle, it is not possible to properly charge users for executing +them. + +The current design aims to combine the best of both worlds: Scalable and feeless layer 1 and Turing-complete smart +contracts on layer 2. Layer 1 remains scalable because of parallel transaction validation, feeless because the bounded +hard-coded script execution time, and layer 2 can offer support for all kinds of virtual machines, smart contracts and +advanced tokenization use cases. + +# Unresolved questions + +- List of supported Token Schemes is not complete. + - Deflationary token scheme + - Inflationary token scheme with scheduled minting + - etc. +- Adapt the current congestion control, i.e. *Block PoW*, to better match the validation complexity of the different + outputs and types. + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 674cebdd47ec48ac40a227516b18f8ecda63bb95 Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Thu, 11 May 2023 16:30:28 +0200 Subject: [PATCH 02/79] Uploaded chain-constraint figure --- tips/TIP-0038/chain-constraint.png | Bin 0 -> 35766 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tips/TIP-0038/chain-constraint.png diff --git a/tips/TIP-0038/chain-constraint.png b/tips/TIP-0038/chain-constraint.png new file mode 100644 index 0000000000000000000000000000000000000000..4b854f3b287349c8dfbbee3f5e3b7765ccb92008 GIT binary patch literal 35766 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 literal 0 HcmV?d00001 From 9bf65e78dee68f56e7c7b608a7aca3be9ba8b7c7 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 12 May 2023 10:41:37 +0200 Subject: [PATCH 03/79] Add `Manalock Unlock Condition` --- tips/TIP-0038/tip-0038.md | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index b6c6c8a3e..9fb9622c0 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -350,7 +350,7 @@ This unlock condition is employed to achieve conditional sending. An output that - `Minimum Storage Deposit` is the storage deposit in the base currency required for a Basic Output that only has an Address Unlock Condition, no additional unlock conditions, no features and no native tokens. -- It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. +- It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. ###### Additional semantic transaction validation rule: @@ -653,6 +653,52 @@ is allowed to unlock the output containing the Expiration Unlock Condition +## Manalock Unlock Condition + +Slot indices in the Tangle are introduced via slot commitments. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. + +An output that contains a Manalock Unlock Condition can not be unlocked before the specified lock has +expired. The lock is expired when the index of the slot in which the transaction belongs to is equal or past the slot index defined in the Manalock Unlock Condition. + +### Additional syntactic transaction validation rules: + +- `Slot Index` field of a Manalock Unlock Condition must be > `0`. + +### Additional semantic transaction validation rules: + +- An output that has a Manalock Unlock Condition specified can only be created in a transaction if it also contains an Address Unlock Condition with an `Account Address`. +- An output that has a Manalock Unlock Condition specified must only be consumed and unlocked in a transaction, if both of the following conditions hold: + - the index of the slot to which the transaction belongs is equal or past the `Slot Index` specified in the unlock condition. + - the specified `Account Address` of the Address Unlock Condition has a non-negative BIC balance. + +
+ Manalock Unlock Condition +
+ Defines a slot index until which the output can not be unlocked. +
+
+ + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 + Set to value 7 to denote a Manalock Unlock Condition. +
Slot Indexuint64 + Slot index starting from which the output can be consumed. +
### Features From f2b67a29d2cbd44b05e64f5dd0b69952cc5ffe9c Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 12 May 2023 10:45:00 +0200 Subject: [PATCH 04/79] Rename `Alias` to `Account` --- tips/TIP-0038/tip-0038.md | 67 +++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 9fb9622c0..9858fa0c4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -31,6 +31,11 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 TODO: Adapt from TIP-18 summary. +## Summary of changes compared to TIP-18 + +- Rename "Alias" to "Account". +- Add `Manalock Unlock Condition`. + # Motivation TODO: Adapt from TIP-18 motivation. @@ -190,7 +195,7 @@ or *chain* in the graph induced by the UTXO spends. Each chain is identified by ![](chain-constraint.png) -Alias outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique +Account outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique identifiers. ### New Functionality in Outputs @@ -222,7 +227,7 @@ is represented as an Address Unlock Condition. Unlocking an Ed25519 Ad be performed via a Signature Unlock in a transaction by signing the hash of the transaction essence. Transaction validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). -New additions are the Alias Address and NFT Address types, which have to be unlocked with their +New additions are the Account Address and NFT Address types, which have to be unlocked with their corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs).
@@ -272,7 +277,7 @@ corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#un
- Alias Address + Account Address @@ -283,13 +288,13 @@ corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#un - + - +
NameAddress Type uint8 - Set to value 8 to denote an Alias Address. + Set to value 8 to denote an Account Address.
Alias IDAccount ID ByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
@@ -332,7 +337,7 @@ separator in the bech32 address will always be different. | Address | Type Byte as `uint8` | Bech32 Encoded | |---------|----------------------|----------------| | Ed25519 | 0 | iota1**q**... | -| Alias | 8 | iota1**p**... | +| Account | 8 | iota1**p**... | | NFT | 16 | iota1**z**... | A user can identify by looking at the address whether it is a signature backed address, a smart contract chain account @@ -410,7 +415,7 @@ This unlock condition is employed to achieve conditional sending. An output that
- Alias Address + Account Address @@ -421,13 +426,13 @@ This unlock condition is employed to achieve conditional sending. An output that - + - +
NameAddress Type uint8 - Set to value 8 to denote an Alias Address. + Set to value 8 to denote an Account Address.
Alias IDAccount ID ByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
@@ -599,7 +604,7 @@ is allowed to unlock the output containing the Expiration Unlock Condition
- Alias Address + Account Address @@ -610,13 +615,13 @@ is allowed to unlock the output containing the Expiration Unlock ConditionAddress Type - + - +
Name uint8 - Set to value 8 to denote an Alias Address. + Set to value 8 to denote an Account Address.
Alias IDAccount ID ByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
@@ -721,8 +726,8 @@ transaction validation. - The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. - - Alias Address: - - The Alias Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - Account Address: + - The Account Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. @@ -772,7 +777,7 @@ transaction validation.
- Alias Address + Account Address @@ -783,13 +788,13 @@ transaction validation. - + - +
NameAddress Type uint8 - Set to value 8 to denote an Alias Address. + Set to value 8 to denote an Account Address.
Alias IDAccount ID ByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
@@ -822,7 +827,7 @@ transaction validation. ##### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state -machine with [chain constraint](#chain-constraint-in-utxo) (alias, NFT). +machine with [chain constraint](#chain-constraint-in-utxo) (account, NFT). Only when the state machine is created (e.g. minted) it is checked during transaction validation that an output corresponding to the `Issuer` address is consumed. In every future transition of the state machine, it is instead checked that the issuer feature is still present and unchanged. @@ -832,8 +837,8 @@ checked that the issuer feature is still present and unchanged. transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. - - Alias Address: - - The Alias Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - Account Address: + - The Account Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. @@ -887,7 +892,7 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ
- Alias Address + Account Address @@ -898,13 +903,13 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ - + - +
NameAddress Type uint8 - Set to value 8 to denote an Alias Address. + Set to value 8 to denote an Account Address.
Alias IDAccount ID ByteArray[32]The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
@@ -1018,14 +1023,14 @@ An example use case is voting on the Tangle via the [participation](https://gith # Drawbacks - New output types increase transaction validation complexity, however it is still bounded. - Outputs take up more space in the ledger, UTXO database size might increase. -- It is possible to intentionally deadlock aliases and NFTs, however client side software can notify users when they - perform such action. Deadlocked aliases and NFTs can not be unlocked, but this is true for any funds locked into +- It is possible to intentionally deadlock accounts and NFTs, however client side software can notify users when they + perform such action. Deadlocked accounts and NFTs can not be unlocked, but this is true for any funds locked into unspendable addresses. - Time based output locking conditions can only be evaluated after attachment to the Tangle, during milestone confirmation. - IOTA ledger can only support hard-coded scripts. Users can not write their own scripts because there is no way currently to charge them based on resource usage, all IOTA transactions are feeless by nature. -- Aliases can be destroyed even if there are foundries alive that they control. Since only the controlling alias can +- Accounts can be destroyed even if there are foundries alive that they control. Since only the controlling account can unlock the foundry, such foundries and the supply of the tokens remain forever locked in the Tangle. - Token schemes and needed supply control rules are unclear. From b9e050a75c16fc69a2908cd563877f188cee0dfb Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 15 May 2023 09:48:31 +0200 Subject: [PATCH 05/79] Add unlocking chain constraint description --- tips/TIP-0038/tip-0038.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 9858fa0c4..fc95ec5ce 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -198,6 +198,14 @@ or *chain* in the graph induced by the UTXO spends. Each chain is identified by Account outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique identifiers. +#### Unlocking Chain Script Locked Outputs + +Outputs with a chain constraint receive their unique identifiers upon creation, generated by the protocol, and carry it forward with them through transactions until they are destroyed. These unique identifiers also function as global addresses for the state machines, but unlike Ed25519 Addresses, they are not backed by private keys that could be used for signing. The rightful owners who can unlock these addresses are defined in the outputs themselves. + +Since such addresses are accounts in the ledger, it is possible to send funds to these addresses. The unlock mechanism +of such funds is designed in a way that **proving ownership of the address is reduced to the ability to unlock the +corresponding output that defines the address.** + ### New Functionality in Outputs The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some outputs From 048d18146b1e7654471296006f531e967e770f6b Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Wed, 17 May 2023 13:05:50 +0200 Subject: [PATCH 06/79] Changed Manalock UC heading level --- tips/TIP-0038/tip-0038.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index fc95ec5ce..973d94719 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -666,18 +666,18 @@ is allowed to unlock the output containing the Expiration Unlock Condition -## Manalock Unlock Condition +##### Manalock Unlock Condition Slot indices in the Tangle are introduced via slot commitments. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. An output that contains a Manalock Unlock Condition can not be unlocked before the specified lock has expired. The lock is expired when the index of the slot in which the transaction belongs to is equal or past the slot index defined in the Manalock Unlock Condition. -### Additional syntactic transaction validation rules: +###### Additional syntactic transaction validation rules: - `Slot Index` field of a Manalock Unlock Condition must be > `0`. -### Additional semantic transaction validation rules: +###### Additional semantic transaction validation rules: - An output that has a Manalock Unlock Condition specified can only be created in a transaction if it also contains an Address Unlock Condition with an `Account Address`. - An output that has a Manalock Unlock Condition specified must only be consumed and unlocked in a transaction, if both of the following conditions hold: From ed7b4a02c1b4330ee412990f620c33803c11b86f Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 23 May 2023 08:41:19 +0200 Subject: [PATCH 07/79] Update ToC, indentation, motivation & summary --- tips/TIP-0038/tip-0038.md | 189 +++++++++++++------------------------- 1 file changed, 65 insertions(+), 124 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 973d94719..16f958841 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -1,7 +1,7 @@ --- -tip: TODO -title: TODO -description: TODO +tip: 38 +title: Building Blocks for IOTA 2.0 Output Types +description: Support for extended unlock conditions, native tokens and features author: TODO discussions-to: TODO status: Draft @@ -17,19 +17,25 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 2. [Motivation](#motivation) 3. [Introduction to ledger programmability](#ledger-programmability) 4. [Building Blocks](#building-blocks) -5. [New concepts of output design](#new-concepts) +5. [Concepts of output design](#concepts-of-output-design) - [Native tokens](#native-tokens-in-outputs) - [Chain constraint](#chain-constraint-in-utxo) - - [Unlock Conditions](#unlock-conditions) - - [Features](#features) -6. [Discussion](#drawbacks) -7. [Rationale and alternatives](#rationale-and-alternatives) -8. [Unresolved questions](#unresolved-questions) -9. [Copyright](#copyright) + - [New Functionality in Outputs](#new-functionality-in-outputs) + - [Unlock Conditions](#unlock-conditions) + - [Address Unlock Condition](#address-unlock-condition) + - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) + - [Timelock Unlock Condition](#timelock-unlock-condition) + - [Expiration Unlock Condition](#expiration-unlock-condition) + - [Manalock Unlock Condition](#manalock-unlock-condition) + - [Features](#features) + - [Sender Feature](#sender-feature) + - [Issuer Feature](#issuer-feature) + - [Metadata Feature](#metadata-feature) +6. [Copyright](#copyright) # Summary -TODO: Adapt from TIP-18 summary. +This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 @@ -38,53 +44,17 @@ TODO: Adapt from TIP-18 summary. # Motivation -TODO: Adapt from TIP-18 motivation. - -# Ledger Programmability - -The current UTXO model only provides support to transfer IOTA coins. However, the UTXO model presents a unique -opportunity to extend the range of possible applications by programming outputs. - -Programming the base ledger of a DLT is not a new concept. Bitcoin uses the UTXO model and attaches small executables -(scripts) that need to be executed during transaction validation. The bitcoin script language is however not -[Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness) as it can only support a small set of instructions -that are executed in a stack based environment. As each validator has to execute the same scripts and arrive at the -same conclusion, such scripts must terminate very quickly. Also, as transaction validation happens in the context of -the transaction and block, the scripts have no access to the global shared state of the system (all unspent transaction -outputs). - -The novelty of Ethereum was to achieve quasi Turing-completeness by employing an account based model and gas to limit -resource usage during program execution. As the amount of gas used per block is limited, only quasi Turing-completeness -can be achieved. The account based model of Ethereum makes it possible for transactions to have access to the global -shared state of the system, furthermore, transactions are executed one-after-the-other. These two properties make -Ethereum less scalable and susceptible to high transaction fees. - -Cardano achieves UTXO programmability by using the EUTXO model. This makes it possible to represent smart contracts in -a UTXO model as state machines. In EUTXO, states of the machine are encoded in outputs, while state transition rules -are governed by scripts. Just like in bitcoin, these scripts may only use a limited set of instructions. - -It would be quite straightforward to support EUTXO in IOTA too, except that IOTA transactions are feeless. There is no -reward to be paid out to validators for validating transactions, as all nodes in the network validate all transactions. -Due to the unique data structure of the Tangle, there is no need for miners to explicitly choose which transactions are -included in the ledger, but there still has to be a notion of objective validity of transactions. Since it is not -possible without fees to penalize scripts that consume excessive network resources (node CPU cycles) during transaction -validation, IOTA has to be overly restrictive about what instructions are supported on layer 1. - -It must also be noted that UTXO scripts are finite state machines with the state space restricted by the output and -transaction validation rules. It makes expressiveness of UTXO scripts inherently limited. In the context of complicated -application logic required by use cases such as modern DeFi, this leads to unconventional and complicated architectures -of the application, consisting of many interacting finite state machines. Apart from complexity and UX costs, it also -has performance and scalability penalties. - -For the reason mentioned above, **IOTA chooses to support configurable yet hard-coded scripts for output and -transaction validation on layer 1.** The general full-scale quasi Turing-complete programmability of the IOTA ledger is -achieved by extending the ledger state transition function with layer 2 smart contract chains. This not only makes it -possible to keep layer 1 scalable and feeless, but also allows to support any type of virtual machine on layer 2 to -program advanced business logic and features. - -Below, several new output types are discussed that implement their own configurable script logic. They can be viewed as -UTXO state machines in which the state of the machine is encoded as data inside the output. The state transition rules -are defined by the output type and by the parameters chosen upon deployment. +The aim of this TIP is to define the common building blocks for output types that support for the use cases of the Native Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. + +The UTXO model becomes even more powerful when unlocking criteria (validation) of outputs are extended as demonstrated +by the [EUTXO model (Chakravarty et al., 2020)](https://fc20.ifca.ai/wtsc/WTSC2020/WTSC20_paper_25.pdf): instead of +requiring only a valid signature for the output's address to unlock it, additional unlock conditions can be +programmed into outputs. This programmability of outputs is the main idea behind the building blocks presented in this +document. + +In combination with the other layer 1 output types that build on top of the primitives defined here, users will be able to interact with layer 2 smart contracts by posting requests through the Tangle. Requests can carry commands to smart contracts and can additionally also transfer native tokens and NFTs. + +With the Native Tokens defined in this TIP, users will be able to mint their own tokens directly in the base ledger, which can then be transferred without any fees just like regular IOTA coins. Each native token has its own supply control policy enforced by the protocol. These policies are transparent to all network participants. Issuers will be able to store metadata about their tokens on-ledger, accessible to anyone. # Building Blocks @@ -100,7 +70,7 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA [TIP-20](../TIP-0020/tip-0020.md) is the basis for output validation in this TIP. -## New Concepts +# Concepts of output design New output types add new features to the protocol and hence new transaction validation rules. While some of these new features are specifically tied to one output type, some are general, LEGO like building blocks that may be put in @@ -108,7 +78,7 @@ several types of outputs. Below is a summary of such new features and the validation rules they introduce. -### Native Tokens in Outputs +## Native Tokens in Outputs Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user defined native @@ -169,14 +139,14 @@ Outputs must have the following fields to define the balance of native tokens th -#### Additional syntactic output validation rules: +### Additional syntactic output validation rules: - `Native Tokens` must be lexicographically sorted based on `Token ID`. - Each Native Token must be unique in the set of `Native Tokens` based on its `Token ID`. No duplicates are allowed. - `Amount` of any Native Token must not be `0`. -#### Additional semantic transaction validation rules: +### Additional semantic transaction validation rules: - The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs equals that of the created outputs. @@ -184,7 +154,7 @@ Outputs must have the following fields to define the balance of native tokens th - **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 in the foundry. -### Chain Constraint in UTXO +## Chain Constraint in UTXO Previously created transaction outputs are destroyed when they are consumed in a subsequent transaction as an input. The chain constraint makes it possible to **carry the UTXO state machine state encoded in outputs across transactions.** @@ -198,7 +168,7 @@ or *chain* in the graph induced by the UTXO spends. Each chain is identified by Account outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique identifiers. -#### Unlocking Chain Script Locked Outputs +### Unlocking Chain Script Locked Outputs Outputs with a chain constraint receive their unique identifiers upon creation, generated by the protocol, and carry it forward with them through transactions until they are destroyed. These unique identifiers also function as global addresses for the state machines, but unlike Ed25519 Addresses, they are not backed by private keys that could be used for signing. The rightful owners who can unlock these addresses are defined in the outputs themselves. @@ -206,7 +176,7 @@ Since such addresses are accounts in the ledger, it is possible to send funds to of such funds is designed in a way that **proving ownership of the address is reduced to the ability to unlock the corresponding output that defines the address.** -### New Functionality in Outputs +## New Functionality in Outputs The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some outputs were specifically designed for such new features, some are optional additions that may be used with any outputs that @@ -216,11 +186,9 @@ These new functionalities are grouped into two categories: - **Unlock Conditions** and - simple **Features**. -The [Output Design](#output-design) section lists all supported Unlock Conditions and Features for -each output type. +Each output type defines its list of supported Unlock Conditions and Features. - -#### Unlock Conditions +### Unlock Conditions New output features that introduce unlocking conditions, that is, they define constraints on how the output can be unlocked and spent, are grouped under the field Unlock Conditions. @@ -228,7 +196,7 @@ be unlocked and spent, are grouped under the field Unlock Conditions. Each output **must not contain more than one unlock condition of each type** and not all unlock condition types are supported for each output type. -##### Address Unlock Condition +#### Address Unlock Condition It is merely a layout change that the previously defined `Address` field of outputs ([TIP-7](../TIP-0007/tip-0007.md)) is represented as an Address Unlock Condition. Unlocking an Ed25519 Address doesn't change, it has to @@ -351,21 +319,21 @@ separator in the bech32 address will always be different. A user can identify by looking at the address whether it is a signature backed address, a smart contract chain account or an NFT address. -##### Storage Deposit Return Unlock Condition +#### Storage Deposit Return Unlock Condition This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into `Return Address`. When several of such outputs are consumed, their return amounts per `Return Addresses` are summed up and the output side must deposit this total sum per `Return Address`. -###### Additional syntactic transaction validation rule: +##### Additional syntactic transaction validation rule: - `Minimum Storage Deposit` is the storage deposit in the base currency required for a Basic Output that only has an Address Unlock Condition, no additional unlock conditions, no features and no native tokens. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. -###### Additional semantic transaction validation rule: +##### Additional semantic transaction validation rule: - An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: @@ -483,7 +451,7 @@ require fees. To prevent the receiving party from blocking access to the storage together with the [Expiration Unlock Conditions](#expiration-unlock-conditions). The receiving party then has a sender-defined time window to agree to the transfer by consuming the output, or the sender regains total control after expiration. -##### Timelock Unlock Condition +#### Timelock Unlock Condition The notion of time in the Tangle is introduced via milestones. Each milestone [carries the current unix timestamp](../TIP-0008/tip-0008.md#structure) @@ -495,9 +463,12 @@ An output that contains a Timelock Unlock Condition can not be unlocked b expired. The timelock is expired when the timestamp of the confirming milestone is equal or past the timestamp defined in the Timelock Unlock Condition. -###### Additional syntactic transaction validation rules: +##### Additional syntactic transaction validation rules: + - `Unix Time` field of a Timelock Unlock Condition must be > `0`. -###### Additional semantic transaction validation rules: + +##### Additional semantic transaction validation rules: + - An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if the timestamp of the confirming milestone is equal or past the `Unix Time` specified in the unlock condition. @@ -531,7 +502,7 @@ in the Timelock Unlock Condition. -##### Expiration Unlock Condition +#### Expiration Unlock Condition The expiration feature of outputs makes it possible for the return address to reclaim an output after a given expiration time has been passed. The expiration can be specified as a unix timestamp. @@ -542,10 +513,12 @@ is a big help for on-chain smart contract requests. Those that have expiration s chains can be recovered by their senders. Not to mention the possibility to time requests by specifying both a timelock and an expiration unlock condition. -###### Additional syntactic transaction validation rules: +##### Additional syntactic transaction validation rules: + - `Unix Time` field of an Expiration Unlock Condition must be > `0`. -###### Additional semantic transaction validation rules: +##### Additional semantic transaction validation rules: + - An output that has Expiration Unlock Condition set must only be consumed and unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction that has a confirming milestone timestamp earlier than the `Unix Time` defined in the unlock condition. @@ -666,18 +639,18 @@ is allowed to unlock the output containing the Expiration Unlock Condition -##### Manalock Unlock Condition +#### Manalock Unlock Condition Slot indices in the Tangle are introduced via slot commitments. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. An output that contains a Manalock Unlock Condition can not be unlocked before the specified lock has expired. The lock is expired when the index of the slot in which the transaction belongs to is equal or past the slot index defined in the Manalock Unlock Condition. -###### Additional syntactic transaction validation rules: +##### Additional syntactic transaction validation rules: - `Slot Index` field of a Manalock Unlock Condition must be > `0`. -###### Additional semantic transaction validation rules: +##### Additional semantic transaction validation rules: - An output that has a Manalock Unlock Condition specified can only be created in a transaction if it also contains an Address Unlock Condition with an `Account Address`. - An output that has a Manalock Unlock Condition specified must only be consumed and unlocked in a transaction, if both of the following conditions hold: @@ -721,7 +694,7 @@ output creation are grouped under Features. Each output **must not contain more than one feature of each type** and not all feature types are supported for each output type. -##### Sender Feature +#### Sender Feature Every transaction consumes several elements from the UTXO set and creates new outputs. However, certain applications (smart contracts) require to associate each output with exactly one sender address. Here, the sender feature is used to @@ -730,7 +703,8 @@ specify the validated sender of an output. Outputs that support the Sender Feature may specify a `Sender` address which is validated by the protocol during transaction validation. -###### Additional semantic transaction validation rule: +##### Additional semantic transaction validation rule: + - The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. @@ -832,7 +806,7 @@ transaction validation. -##### Issuer Feature +#### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state machine with [chain constraint](#chain-constraint-in-utxo) (account, NFT). @@ -840,7 +814,8 @@ Only when the state machine is created (e.g. minted) it is checked during transa corresponding to the `Issuer` address is consumed. In every future transition of the state machine, it is instead checked that the issuer feature is still present and unchanged. -###### Additional semantic transaction validation rule: +##### Additional semantic transaction validation rule: + - When an Issuer Feature is present in an output representing the initial state of an UTXO state machine, the transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: @@ -951,14 +926,15 @@ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Is chain's address, since user does not sign the layer 1 transaction. As a consequence, artist would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. -##### Metadata Feature +#### Metadata Feature Outputs may carry additional data with them that is interpreted by higher layer applications built on the Tangle. The protocol treats this metadata as pure binary data, it has no effect on the validity of an output except that it increases the required storage deposit. ISC is a great example of a higher layer protocol that makes use of Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. -###### Additional syntactic transaction validation rules: +##### Additional syntactic transaction validation rules: + - An output with Metadata Feature is valid, if and only if 0 < `length(Data)` ≤ `Max Metadata Length`.
@@ -998,6 +974,7 @@ in outputs that were created by a specific party (`Sender`) for a specific purpo An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) plugin. ##### Additional syntactic transaction validation rules: + - An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ `Max Tag Length`. @@ -1028,42 +1005,6 @@ An example use case is voting on the Tangle via the [participation](https://gith -# Drawbacks -- New output types increase transaction validation complexity, however it is still bounded. -- Outputs take up more space in the ledger, UTXO database size might increase. -- It is possible to intentionally deadlock accounts and NFTs, however client side software can notify users when they - perform such action. Deadlocked accounts and NFTs can not be unlocked, but this is true for any funds locked into - unspendable addresses. -- Time based output locking conditions can only be evaluated after attachment to the Tangle, during milestone - confirmation. -- IOTA ledger can only support hard-coded scripts. Users can not write their own scripts because there is no way - currently to charge them based on resource usage, all IOTA transactions are feeless by nature. -- Accounts can be destroyed even if there are foundries alive that they control. Since only the controlling account can - unlock the foundry, such foundries and the supply of the tokens remain forever locked in the Tangle. -- Token schemes and needed supply control rules are unclear. - -# Rationale and alternatives - -The feeless nature of IOTA makes it inherently impossible to implement smart contracts on layer 1. A smart contract -platform shall not only be capable of executing smart contracts, but also to limit their resource usage and make users -pay validators for the used resources. IOTA has no concept of validators, neither fees. While it would technically be -possible to run EUTXO smart contracts on the layer 1 Tangle, it is not possible to properly charge users for executing -them. - -The current design aims to combine the best of both worlds: Scalable and feeless layer 1 and Turing-complete smart -contracts on layer 2. Layer 1 remains scalable because of parallel transaction validation, feeless because the bounded -hard-coded script execution time, and layer 2 can offer support for all kinds of virtual machines, smart contracts and -advanced tokenization use cases. - -# Unresolved questions - -- List of supported Token Schemes is not complete. - - Deflationary token scheme - - Inflationary token scheme with scheduled minting - - etc. -- Adapt the current congestion control, i.e. *Block PoW*, to better match the validation complexity of the different - outputs and types. - # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7a33df59c9e7c5fac30cb658cd06c812a1644268 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 26 May 2023 11:07:07 +0200 Subject: [PATCH 08/79] Remove `Manalock Unlock Condition` --- tips/TIP-0038/tip-0038.md | 49 --------------------------------------- 1 file changed, 49 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 16f958841..91cfc1c4f 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -26,7 +26,6 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) - [Timelock Unlock Condition](#timelock-unlock-condition) - [Expiration Unlock Condition](#expiration-unlock-condition) - - [Manalock Unlock Condition](#manalock-unlock-condition) - [Features](#features) - [Sender Feature](#sender-feature) - [Issuer Feature](#issuer-feature) @@ -40,7 +39,6 @@ This document defines the common building blocks used across multiple output typ ## Summary of changes compared to TIP-18 - Rename "Alias" to "Account". -- Add `Manalock Unlock Condition`. # Motivation @@ -639,53 +637,6 @@ is allowed to unlock the output containing the Expiration Unlock Condition -#### Manalock Unlock Condition - -Slot indices in the Tangle are introduced via slot commitments. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. - -An output that contains a Manalock Unlock Condition can not be unlocked before the specified lock has -expired. The lock is expired when the index of the slot in which the transaction belongs to is equal or past the slot index defined in the Manalock Unlock Condition. - -##### Additional syntactic transaction validation rules: - -- `Slot Index` field of a Manalock Unlock Condition must be > `0`. - -##### Additional semantic transaction validation rules: - -- An output that has a Manalock Unlock Condition specified can only be created in a transaction if it also contains an Address Unlock Condition with an `Account Address`. -- An output that has a Manalock Unlock Condition specified must only be consumed and unlocked in a transaction, if both of the following conditions hold: - - the index of the slot to which the transaction belongs is equal or past the `Slot Index` specified in the unlock condition. - - the specified `Account Address` of the Address Unlock Condition has a non-negative BIC balance. - -
- Manalock Unlock Condition -
- Defines a slot index until which the output can not be unlocked. -
-
- - - - - - - - - - - - - - - - - -
NameTypeDescription
Unlock Condition Typeuint8 - Set to value 7 to denote a Manalock Unlock Condition. -
Slot Indexuint64 - Slot index starting from which the output can be consumed. -
- ### Features New output features that do not introduce unlocking conditions, but rather add new functionality and add constraints on From e1ee04d41740eb0fd20ba8e66753cf7f42131334 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 26 May 2023 12:13:13 +0200 Subject: [PATCH 09/79] Use slot index in timelock & expiration UCs --- tips/TIP-0038/tip-0038.md | 60 ++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 91cfc1c4f..30c6db995 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -451,19 +451,14 @@ time window to agree to the transfer by consuming the output, or the sender rega #### Timelock Unlock Condition -The notion of time in the Tangle is introduced via milestones. Each milestone -[carries the current unix timestamp](../TIP-0008/tip-0008.md#structure) -corresponding to that milestone index. Whenever a new milestone appears, nodes perform the white-flag ordering and transaction -validation on its past cone. The timestamp of the confirming milestone provide the time as an input parameter to -transaction validation. +Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. -An output that contains a Timelock Unlock Condition can not be unlocked before the specified timelock has -expired. The timelock is expired when the timestamp of the confirming milestone is equal or past the timestamp defined -in the Timelock Unlock Condition. +An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has +expired. The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined in the Timelock Unlock Condition. ##### Additional syntactic transaction validation rules: -- `Unix Time` field of a Timelock Unlock Condition must be > `0`. +- `Slot Index` field of a Timelock Unlock Condition must be > `0`. ##### Additional semantic transaction validation rules: @@ -474,7 +469,7 @@ in the Timelock Unlock Condition.
Timelock Unlock Condition
- Defines a unix timestamp until which the output can not be unlocked. + Defines a slot index until which the output can not be unlocked.
@@ -492,10 +487,10 @@ in the Timelock Unlock Condition. - Unix Time - uint32 + Slot Index + uint64+ - Unix time (seconds since Unix epoch) starting from which the output can be consumed. + Slot index starting from which the output can be consumed. @@ -503,7 +498,7 @@ in the Timelock Unlock Condition. #### Expiration Unlock Condition The expiration feature of outputs makes it possible for the return address to reclaim an output after a given expiration -time has been passed. The expiration can be specified as a unix timestamp. +slot index has passed. The expiration feature can be viewed as an opt-in receive feature, because the recipient loses access to the received funds after the output expires, while the return address specified by the sender regains control over them. This feature @@ -513,34 +508,33 @@ timelock and an expiration unlock condition. ##### Additional syntactic transaction validation rules: -- `Unix Time` field of an Expiration Unlock Condition must be > `0`. +- `Slot Index` field of a Timelock Unlock Condition must be > `0`. ##### Additional semantic transaction validation rules: -- An output that has Expiration Unlock Condition set must only be consumed and - unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction that has a confirming - milestone timestamp earlier than the `Unix Time` defined in the unlock condition. -- An output that has Expiration Unlock Condition set must only be consumed and unlocked by the `Return Address` - in a transaction that has a confirming milestone timestamp same or later than the `Unix Time` defined in the unlock - condition. -- Semantic validation of an output that has Expiration Unlock Condition set and is unlocked by the +- An output that has an Expiration Unlock Condition set must only be consumed and + unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction whose slot index + is less than the `Slot Index` defined in the unlock condition. +- An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the `Return Address` + in a transaction whose slot index is greater or equal to the `Slot Index` defined in the unlock condition. +- Semantic validation of an output that has an Expiration Unlock Condition set and is unlocked by the `Return Address` must ignore: - [Semantic validation of Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) if present. -The following table summarizes the outcome of syntactic and semantic validation rules with respect to which account +The following table summarizes the outcome of the syntactic and semantic validation rules with respect to which address is allowed to unlock the output containing the Expiration Unlock Condition: -| Milestone Unix Timestamp Condition | Outcome | +| Transaction Slot Index Condition | Outcome | |-----------------------------------------------------|-----------------------------------------------| -| `Unix Time` = `0` | Output and containing transaction is invalid. | -| `Unix Time` > `Confirming Milestone Unix Timestamp` | Unlockable by `Address` | -| `Unix Time` ≤ `Confirming Milestone Unix Timestamp` | Unlockable by `Return Address` | +| `Slot Index` = `0` | Output and containing transaction is invalid. | +| `Slot Index` > `Transaction Slot Index` | Unlockable by `Address` | +| `Slot Index` ≤ `Transaction Slot Index` | Unlockable by `Return Address` |
Expiration Unlock Condition
- Defines a unix time until which only Address, defined in Address Unlock Condition, is allowed to - unlock the output. After the unix time is reached/passed, only Return Address can unlock it. + Defines a slot index until which only Address, defined in Address Unlock Condition, is allowed to + unlock the output. After the slot index is reached/passed, only Return Address can unlock it.
@@ -554,7 +548,7 @@ is allowed to unlock the output containing the Expiration Unlock ConditionUnlock Condition Type uint8 - Set to value 3 to denote a Expiration Unlock Condition. + Set to value 3 to denote an Expiration Unlock Condition. @@ -629,10 +623,10 @@ is allowed to unlock the output containing the Expiration Unlock Condition - Unix Time - uint32 + Slot Index + uint64 - Before this unix time, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. + Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. From 3956ffea4a85c3c691b74607d608d2ce5a47691c Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 26 May 2023 12:17:09 +0200 Subject: [PATCH 10/79] Update change summary --- tips/TIP-0038/tip-0038.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 30c6db995..2a71f11a3 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -34,11 +34,13 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 # Summary -This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the primitives defined in TIP-18. +This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 - Rename "Alias" to "Account". +- The `Unix Time` field of the Timelock Unlock Condition is replaced by `Slot Index`. +- The `Unix Time` field of the Expiration Unlock Condition is replaced by `Slot Index`. # Motivation From 027b3a75130941ccc7ad5b5af94246c9c7155e01 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 13:37:59 +0200 Subject: [PATCH 11/79] Polish header and references to other TIPs --- tips/TIP-0038/tip-0038.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 2a71f11a3..d0f6eaf21 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -2,13 +2,14 @@ tip: 38 title: Building Blocks for IOTA 2.0 Output Types description: Support for extended unlock conditions, native tokens and features -author: TODO +author: Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards layer: Core created: 2023-05-03 -requires: TIP-19, TIP-20, TIP-21 and TIP-22 +requires: TIP-21, TIP-22, TIP-41, TIP-42, TIP-43, TIP-44, TIP-45 and TIP-47 +replaces: TIP-18 --- # Table of Contents @@ -17,10 +18,10 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 2. [Motivation](#motivation) 3. [Introduction to ledger programmability](#ledger-programmability) 4. [Building Blocks](#building-blocks) -5. [Concepts of output design](#concepts-of-output-design) +5. [Output Design Primitives](#output-design-primitives) - [Native tokens](#native-tokens-in-outputs) - [Chain constraint](#chain-constraint-in-utxo) - - [New Functionality in Outputs](#new-functionality-in-outputs) + - [Functionality in Outputs](#functionality-in-outputs) - [Unlock Conditions](#unlock-conditions) - [Address Unlock Condition](#address-unlock-condition) - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) @@ -34,7 +35,7 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 # Summary -This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the primitives defined in TIP-18. +This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 @@ -70,13 +71,13 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA [TIP-20](../TIP-0020/tip-0020.md) is the basis for output validation in this TIP. -# Concepts of output design +# Output Design Primitives New output types add new features to the protocol and hence new transaction validation rules. While some of these new features are specifically tied to one output type, some are general, LEGO like building blocks that may be put in several types of outputs. -Below is a summary of such new features and the validation rules they introduce. +The following defines various primitives and the validation rules they introduce. ## Native Tokens in Outputs @@ -123,7 +124,7 @@ Outputs must have the following fields to define the balance of native tokens th Token ID ByteArray[38] - Identifier of the native token. Derivation defined
here. + Identifier of the native token. Derivation defined here. @@ -176,7 +177,7 @@ Since such addresses are accounts in the ledger, it is possible to send funds to of such funds is designed in a way that **proving ownership of the address is reduced to the ability to unlock the corresponding output that defines the address.** -## New Functionality in Outputs +## Functionality in Outputs The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some outputs were specifically designed for such new features, some are optional additions that may be used with any outputs that @@ -204,7 +205,8 @@ be performed via a Signature Unlock in a transaction by signing the hash Transaction validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). New additions are the Account Address and NFT Address types, which have to be unlocked with their -corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs). +corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs) +and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs.
Address Unlock @@ -328,7 +330,7 @@ This unlock condition is employed to achieve conditional sending. An output that ##### Additional syntactic transaction validation rule: -- `Minimum Storage Deposit` is the storage deposit in the base currency required for a Basic Output that only +- `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock conditions, no features and no native tokens. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. @@ -337,7 +339,7 @@ This unlock condition is employed to achieve conditional sending. An output that - An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: - - are of type [Basic Output](#basic-output), + - are of type Basic Output, - have only an [Address Unlock Condition](#address-unlock-condition) defined, - have no [Native Tokens](#native-tokens-in-outputs), and - have no [Features](#features). From 805038e34c97f83bfc7b458617402305823b28e1 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 13:59:37 +0200 Subject: [PATCH 12/79] Update TX validation TIP --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d0f6eaf21..4e7904e43 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -69,7 +69,7 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA ## Transaction Payload -[TIP-20](../TIP-0020/tip-0020.md) is the basis for output validation in this TIP. +[TIP-45](../TIP-0045/tip-0045.md) is the basis for output validation in this TIP. # Output Design Primitives From bd0e06448e00dda015886eba5e40fc9e2b335bb2 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 14:31:59 +0200 Subject: [PATCH 13/79] Remove stray `+` --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 4e7904e43..1f0055ee2 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -492,7 +492,7 @@ expired. The lock is expired when the index of the slot to which the transaction Slot Index - uint64+ + uint64 Slot index starting from which the output can be consumed. From d272827aad6da229f51042651ad0f6e1c99b357c Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 31 May 2023 09:54:06 +0200 Subject: [PATCH 14/79] Format markdown --- tips/TIP-0038/tip-0038.md | 251 +++++++++++++++++++++----------------- 1 file changed, 140 insertions(+), 111 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 1f0055ee2..48f0ba3d4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -2,7 +2,8 @@ tip: 38 title: Building Blocks for IOTA 2.0 Output Types description: Support for extended unlock conditions, native tokens and features -author: Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) +author: + Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards @@ -19,23 +20,25 @@ replaces: TIP-18 3. [Introduction to ledger programmability](#ledger-programmability) 4. [Building Blocks](#building-blocks) 5. [Output Design Primitives](#output-design-primitives) - - [Native tokens](#native-tokens-in-outputs) - - [Chain constraint](#chain-constraint-in-utxo) - - [Functionality in Outputs](#functionality-in-outputs) - - [Unlock Conditions](#unlock-conditions) - - [Address Unlock Condition](#address-unlock-condition) - - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) - - [Timelock Unlock Condition](#timelock-unlock-condition) - - [Expiration Unlock Condition](#expiration-unlock-condition) - - [Features](#features) - - [Sender Feature](#sender-feature) - - [Issuer Feature](#issuer-feature) - - [Metadata Feature](#metadata-feature) + - [Native tokens](#native-tokens-in-outputs) + - [Chain constraint](#chain-constraint-in-utxo) + - [Functionality in Outputs](#functionality-in-outputs) + - [Unlock Conditions](#unlock-conditions) + - [Address Unlock Condition](#address-unlock-condition) + - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) + - [Timelock Unlock Condition](#timelock-unlock-condition) + - [Expiration Unlock Condition](#expiration-unlock-condition) + - [Features](#features) + - [Sender Feature](#sender-feature) + - [Issuer Feature](#issuer-feature) + - [Metadata Feature](#metadata-feature) 6. [Copyright](#copyright) # Summary -This document defines the common building blocks used across multiple output types and transaction validation rules for the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the primitives defined in TIP-18. +This document defines the common building blocks used across multiple output types and transaction validation rules for +the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined +in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 @@ -45,17 +48,22 @@ This document defines the common building blocks used across multiple output typ # Motivation -The aim of this TIP is to define the common building blocks for output types that support for the use cases of the Native Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. +The aim of this TIP is to define the common building blocks for output types that support for the use cases of the +Native Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. The UTXO model becomes even more powerful when unlocking criteria (validation) of outputs are extended as demonstrated by the [EUTXO model (Chakravarty et al., 2020)](https://fc20.ifca.ai/wtsc/WTSC2020/WTSC20_paper_25.pdf): instead of -requiring only a valid signature for the output's address to unlock it, additional unlock conditions can be -programmed into outputs. This programmability of outputs is the main idea behind the building blocks presented in this -document. +requiring only a valid signature for the output's address to unlock it, additional unlock conditions can be programmed +into outputs. This programmability of outputs is the main idea behind the building blocks presented in this document. -In combination with the other layer 1 output types that build on top of the primitives defined here, users will be able to interact with layer 2 smart contracts by posting requests through the Tangle. Requests can carry commands to smart contracts and can additionally also transfer native tokens and NFTs. +In combination with the other layer 1 output types that build on top of the primitives defined here, users will be able +to interact with layer 2 smart contracts by posting requests through the Tangle. Requests can carry commands to smart +contracts and can additionally also transfer native tokens and NFTs. -With the Native Tokens defined in this TIP, users will be able to mint their own tokens directly in the base ledger, which can then be transferred without any fees just like regular IOTA coins. Each native token has its own supply control policy enforced by the protocol. These policies are transparent to all network participants. Issuers will be able to store metadata about their tokens on-ledger, accessible to anyone. +With the Native Tokens defined in this TIP, users will be able to mint their own tokens directly in the base ledger, +which can then be transferred without any fees just like regular IOTA coins. Each native token has its own supply +control policy enforced by the protocol. These policies are transparent to all network participants. Issuers will be +able to store metadata about their tokens on-ledger, accessible to anyone. # Building Blocks @@ -65,7 +73,8 @@ Data types and subschemas used throughout this TIP are defined in [TIP-21](../TI ## Global Protocol Parameters -Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA)](../TIP-0022/tip-0022.md) and [TIP-32 (Shimmer)](../TIP-0032/tip-0032.md). +Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA)](../TIP-0022/tip-0022.md) and +[TIP-32 (Shimmer)](../TIP-0032/tip-0032.md). ## Transaction Payload @@ -86,15 +95,14 @@ funds it holds. With the addition of the Native Tokenization Framework, outputs tokens, that is, tokens that are not IOTA coins but were minted by foundries and are tracked in the very same ledger. Therefore, **every output must be able to hold not only IOTA coins, but also native tokens**. -Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the -storage deposit requirements must be covered via IOTA coins. +Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the storage +deposit requirements must be covered via IOTA coins. User defined tokens are called Native Tokens on protocol level. The maximum supply of a particular native token -is defined by the representation chosen on protocol level for defining their amounts in outputs. Since native tokens -are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the -maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the -maximum supply of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such huge amount of -assets on layer 1. +is defined by the representation chosen on protocol level for defining their amounts in outputs. Since native tokens are +also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the maximum +possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum supply of an +ERC-20 token as `MaxUint256`, therefore it should be possible to represent such huge amount of assets on layer 1. Outputs must have the following fields to define the balance of native tokens they hold: @@ -152,17 +160,20 @@ Outputs must have the following fields to define the balance of native tokens th - The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs equals that of the created outputs. - When the transaction is **imbalanced** and 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 in the foundry. + - **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 in the + foundry. ## Chain Constraint in UTXO -Previously created transaction outputs are destroyed when they are consumed in a subsequent transaction as an input. -The chain constraint makes it possible to **carry the UTXO state machine state encoded in outputs across transactions.** -When an output with chain constraint is consumed, that transaction has to create a single subsequent output that -carries the state forward. The **state can be updated according to the transition rules defined for the given type of -output and its current state**. As a consequence, each such output has a unique successor, and together they form a path -or *chain* in the graph induced by the UTXO spends. Each chain is identified by its globally unique identifier. +Previously created transaction outputs are destroyed when they are consumed in a subsequent transaction as an input. The +chain constraint makes it possible to **carry the UTXO state machine state encoded in outputs across transactions.** +When an output with chain constraint is consumed, that transaction has to create a single subsequent output that carries +the state forward. The **state can be updated according to the transition rules defined for the given type of output and +its current state**. As a consequence, each such output has a unique successor, and together they form a path or _chain_ +in the graph induced by the UTXO spends. Each chain is identified by its globally unique identifier. ![](chain-constraint.png) @@ -171,7 +182,10 @@ identifiers. ### Unlocking Chain Script Locked Outputs -Outputs with a chain constraint receive their unique identifiers upon creation, generated by the protocol, and carry it forward with them through transactions until they are destroyed. These unique identifiers also function as global addresses for the state machines, but unlike Ed25519 Addresses, they are not backed by private keys that could be used for signing. The rightful owners who can unlock these addresses are defined in the outputs themselves. +Outputs with a chain constraint receive their unique identifiers upon creation, generated by the protocol, and carry it +forward with them through transactions until they are destroyed. These unique identifiers also function as global +addresses for the state machines, but unlike Ed25519 Addresses, they are not backed by private keys that could be +used for signing. The rightful owners who can unlock these addresses are defined in the outputs themselves. Since such addresses are accounts in the ledger, it is possible to send funds to these addresses. The unlock mechanism of such funds is designed in a way that **proving ownership of the address is reduced to the ability to unlock the @@ -179,20 +193,21 @@ corresponding output that defines the address.** ## Functionality in Outputs -The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some outputs -were specifically designed for such new features, some are optional additions that may be used with any outputs that -support them. +The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some +outputs were specifically designed for such new features, some are optional additions that may be used with any outputs +that support them. These new functionalities are grouped into two categories: - - **Unlock Conditions** and - - simple **Features**. + +- **Unlock Conditions** and +- simple **Features**. Each output type defines its list of supported Unlock Conditions and Features. ### Unlock Conditions -New output features that introduce unlocking conditions, that is, they define constraints on how the output can -be unlocked and spent, are grouped under the field Unlock Conditions. +New output features that introduce unlocking conditions, that is, they define constraints on how the output can be +unlocked and spent, are grouped under the field Unlock Conditions. Each output **must not contain more than one unlock condition of each type** and not all unlock condition types are supported for each output type. @@ -200,13 +215,13 @@ supported for each output type. #### Address Unlock Condition It is merely a layout change that the previously defined `Address` field of outputs ([TIP-7](../TIP-0007/tip-0007.md)) -is represented as an Address Unlock Condition. Unlocking an Ed25519 Address doesn't change, it has to -be performed via a Signature Unlock in a transaction by signing the hash of the transaction essence. -Transaction validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). +is represented as an Address Unlock Condition. Unlocking an Ed25519 Address doesn't change, it has to be +performed via a Signature Unlock in a transaction by signing the hash of the transaction essence. Transaction +validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). New additions are the Account Address and NFT Address types, which have to be unlocked with their -corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs) -and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs. +corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs) and +the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs.
Address Unlock @@ -302,8 +317,8 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t -| :information_source: Good to know about address format | -|---------------------------------------------------------| +| :information_source: Good to know about address format | +| ------------------------------------------------------ | The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, which is the recommended address format for user facing applications. @@ -313,7 +328,7 @@ By choosing Address Type as a multiple of 8 for different address types, separator in the bech32 address will always be different. | Address | Type Byte as `uint8` | Bech32 Encoded | -|---------|----------------------|----------------| +| ------- | -------------------- | -------------- | | Ed25519 | 0 | iota1**q**... | | Account | 8 | iota1**p**... | | NFT | 16 | iota1**z**... | @@ -323,29 +338,29 @@ or an NFT address. #### Storage Deposit Return Unlock Condition -This unlock condition is employed to achieve conditional sending. An output that has -Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits -`Return Amount` IOTA coins into `Return Address`. When several of such outputs are consumed, their return amounts per -`Return Addresses` are summed up and the output side must deposit this total sum per `Return Address`. +This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock +Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into +`Return Address`. When several of such outputs are consumed, their return amounts per `Return Addresses` are summed up +and the output side must deposit this total sum per `Return Address`. ##### Additional syntactic transaction validation rule: -- `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only - has an Address Unlock Condition, no additional unlock conditions, no features and - no native tokens. +- `Minimum Storage Deposit` is the storage deposit in the base currency required for a + [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock + conditions, no features and no native tokens. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. ##### Additional semantic transaction validation rule: - An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: - - are of type Basic Output, - - have only an [Address Unlock Condition](#address-unlock-condition) defined, - - have no [Native Tokens](#native-tokens-in-outputs), and - - have no [Features](#features). + - are of type Basic Output, + - have only an [Address Unlock Condition](#address-unlock-condition) defined, + - have no [Native Tokens](#native-tokens-in-outputs), and + - have no [Features](#features). - When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, - their return amounts per `Return Addresses` are summed up and the output side of the transaction must deposit - _at least_ this total sum per `Return Address` via output(s) that satisfy the previous condition. + their return amounts per `Return Addresses` are summed up and the output side of the transaction must deposit _at + least_ this total sum per `Return Address` via output(s) that satisfy the previous condition.
Storage Deposit Return Unlock Condition @@ -448,17 +463,22 @@ This unlock condition is employed to achieve conditional sending. An output that This unlock condition makes it possible to send small amounts of IOTA coins or native tokens to addresses without having -to lose control of the required storage deposit. It is also a vehicle to send on-chain requests to ISCP chains that do not -require fees. To prevent the receiving party from blocking access to the storage deposit, it is advised to be used -together with the [Expiration Unlock Conditions](#expiration-unlock-conditions). The receiving party then has a sender-defined -time window to agree to the transfer by consuming the output, or the sender regains total control after expiration. +to lose control of the required storage deposit. It is also a vehicle to send on-chain requests to ISCP chains that do +not require fees. To prevent the receiving party from blocking access to the storage deposit, it is advised to be used +together with the [Expiration Unlock Conditions](#expiration-unlock-conditions). The receiving party then has a +sender-defined time window to agree to the transfer by consuming the output, or the sender regains total control after +expiration. #### Timelock Unlock Condition -Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location of formula currently defined in https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. +Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment +carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location +of formula currently defined in +https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. -An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has -expired. The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined in the Timelock Unlock Condition. +An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. +The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined +in the Timelock Unlock Condition. ##### Additional syntactic transaction validation rules: @@ -466,9 +486,8 @@ expired. The lock is expired when the index of the slot to which the transaction ##### Additional semantic transaction validation rules: -- An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a - transaction, if the timestamp of the confirming milestone is equal or past the `Unix Time` specified in the unlock - condition. +- An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if + the timestamp of the confirming milestone is equal or past the `Unix Time` specified in the unlock condition.
Timelock Unlock Condition @@ -506,8 +525,8 @@ slot index has passed. The expiration feature can be viewed as an opt-in receive feature, because the recipient loses access to the received funds after the output expires, while the return address specified by the sender regains control over them. This feature -is a big help for on-chain smart contract requests. Those that have expiration set and are sent to dormant smart contract -chains can be recovered by their senders. Not to mention the possibility to time requests by specifying both a +is a big help for on-chain smart contract requests. Those that have expiration set and are sent to dormant smart +contract chains can be recovered by their senders. Not to mention the possibility to time requests by specifying both a timelock and an expiration unlock condition. ##### Additional syntactic transaction validation rules: @@ -516,23 +535,25 @@ timelock and an expiration unlock condition. ##### Additional semantic transaction validation rules: -- An output that has an Expiration Unlock Condition set must only be consumed and - unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction whose slot index - is less than the `Slot Index` defined in the unlock condition. -- An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the `Return Address` - in a transaction whose slot index is greater or equal to the `Slot Index` defined in the unlock condition. +- An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the target + `Address` (defined in Address Unlock Condition) in a transaction whose slot index is less than the `Slot Index` + defined in the unlock condition. +- An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the + `Return Address` in a transaction whose slot index is greater or equal to the `Slot Index` defined in the unlock + condition. - Semantic validation of an output that has an Expiration Unlock Condition set and is unlocked by the `Return Address` must ignore: - - [Semantic validation of Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) if present. + - [Semantic validation of Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) if + present. The following table summarizes the outcome of the syntactic and semantic validation rules with respect to which address is allowed to unlock the output containing the Expiration Unlock Condition: -| Transaction Slot Index Condition | Outcome | -|-----------------------------------------------------|-----------------------------------------------| -| `Slot Index` = `0` | Output and containing transaction is invalid. | -| `Slot Index` > `Transaction Slot Index` | Unlockable by `Address` | -| `Slot Index` ≤ `Transaction Slot Index` | Unlockable by `Return Address` | +| Transaction Slot Index Condition | Outcome | +| --------------------------------------- | --------------------------------------------- | +| `Slot Index` = `0` | Output and containing transaction is invalid. | +| `Slot Index` > `Transaction Slot Index` | Unlockable by `Address` | +| `Slot Index` ≤ `Transaction Slot Index` | Unlockable by `Return Address` |
Expiration Unlock Condition @@ -640,8 +661,8 @@ is allowed to unlock the output containing the Expiration Unlock ConditionFeatures. -Each output **must not contain more than one feature of each type** and not all feature types are supported for each output -type. +Each output **must not contain more than one feature of each type** and not all feature types are supported for each +output type. #### Sender Feature @@ -654,11 +675,15 @@ transaction validation. ##### Additional semantic transaction validation rule: -- The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: +- The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` + address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and + only if: - Ed25519 Address: - - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. + - The Unlock of the first output in the transaction that contains the address is a valid Signature + Unlock with respect to the address. - Account Address: - - The Account Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - The Account Output that defines the address is **state transitioned** in the transaction. A governance + transition does not unlock the address. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. @@ -758,19 +783,22 @@ transaction validation. #### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state -machine with [chain constraint](#chain-constraint-in-utxo) (account, NFT). -Only when the state machine is created (e.g. minted) it is checked during transaction validation that an output -corresponding to the `Issuer` address is consumed. In every future transition of the state machine, it is instead -checked that the issuer feature is still present and unchanged. +machine with [chain constraint](#chain-constraint-in-utxo) (account, NFT). Only when the state machine is created (e.g. +minted) it is checked during transaction validation that an output corresponding to the `Issuer` address is consumed. In +every future transition of the state machine, it is instead checked that the issuer feature is still present and +unchanged. ##### Additional semantic transaction validation rule: - When an Issuer Feature is present in an output representing the initial state of an UTXO state machine, the - transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: + transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based + on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. + - The Unlock of the first output in the transaction that contains the address is a valid Signature + Unlock with respect to the address. - Account Address: - - The Account Output that defines the address is **state transitioned** in the transaction. A governance transition does not unlock the address. + - The Account Output that defines the address is **state transitioned** in the transaction. A governance + transition does not unlock the address. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. @@ -871,16 +899,16 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ -Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the -chain's address, since user does not sign the layer 1 transaction. As a consequence, artist would have to mint NFTs -themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. +Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the chain's +address, since user does not sign the layer 1 transaction. As a consequence, artist would have to mint NFTs themselves +on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. #### Metadata Feature Outputs may carry additional data with them that is interpreted by higher layer applications built on the Tangle. The protocol treats this metadata as pure binary data, it has no effect on the validity of an output except that it -increases the required storage deposit. ISC is a great example of a higher layer protocol that makes use of -Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. +increases the required storage deposit. ISC is a great example of a higher layer protocol that makes use of Metadata +Feature: smart contract request parameters are encoded in the metadata field of outputs. ##### Additional syntactic transaction validation rules: @@ -916,16 +944,17 @@ increases the required storage deposit. ISC is a great example of a higher layer #### Tag Feature A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not -only by their address, but also based on the `Tag`. **The combination of a Tag Feature, a -Metadata Feature and a Sender Feature makes it possible to retrieve data associated to an address and stored -in outputs that were created by a specific party (`Sender`) for a specific purpose (`Tag`).** +only by their address, but also based on the `Tag`. **The combination of a Tag Feature, a Metadata Feature +and a Sender Feature makes it possible to retrieve data associated to an address and stored in outputs that were +created by a specific party (`Sender`) for a specific purpose (`Tag`).** -An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) plugin. +An example use case is voting on the Tangle via the +[participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) +plugin. ##### Additional syntactic transaction validation rules: -- An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ - `Max Tag Length`. +- An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ `Max Tag Length`.
Tag Feature From 026ea5421eabaa6a36391ce9828453cf05d5e5bf Mon Sep 17 00:00:00 2001 From: Andrew Cullen <45826600+cyberphysic4l@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:56:49 +0100 Subject: [PATCH 15/79] correct errors in timelock and expiration --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 48f0ba3d4..a4da2fe62 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -487,7 +487,7 @@ in the Timelock Unlock Condition. ##### Additional semantic transaction validation rules: - An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if - the timestamp of the confirming milestone is equal or past the `Unix Time` specified in the unlock condition. + the creation time of the transaction is equal or past the `Slot Index` specified in the unlock condition.
Timelock Unlock Condition @@ -531,7 +531,7 @@ timelock and an expiration unlock condition. ##### Additional syntactic transaction validation rules: -- `Slot Index` field of a Timelock Unlock Condition must be > `0`. +- `Slot Index` field of a Expiration Unlock Condition must be > `0`. ##### Additional semantic transaction validation rules: From b7626e41347b08449663c3689db52071d7e37a41 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 17 Jul 2023 12:36:20 +0200 Subject: [PATCH 16/79] Add time boundary for Timelock --- tips/TIP-0038/tip-0038.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index a4da2fe62..a1c8f8a40 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -472,9 +472,7 @@ expiration. #### Timelock Unlock Condition Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment -carries an index. The slot index of a transaction can be calculated based on its timestamp. TODO: Link to final location -of formula currently defined in -https://github.com/iotaledger/iota-core/blob/develop/documentation/APIs/core-models.md#slot-index. +carries an index. When using any feature related to time, a [_Commitment Input_](https://github.com/iotaledger/tips-draft/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined @@ -486,8 +484,11 @@ in the Timelock Unlock Condition. ##### Additional semantic transaction validation rules: -- An output that has Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if - the creation time of the transaction is equal or past the `Slot Index` specified in the unlock condition. +- A _Commitment Input_ must be present. +- Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the + slot index of the commitment input. +- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if + the `Future Bounded Slot Index` is equal or past the `Slot Index` specified in the unlock condition.
Timelock Unlock Condition From 87eb92b8c95bd5377d5661ce60612505cb6643a3 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 17 Jul 2023 12:50:08 +0200 Subject: [PATCH 17/79] Add time boundary for Expiration UC --- tips/TIP-0038/tip-0038.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index a1c8f8a40..b7bf9aa6b 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -472,7 +472,9 @@ expiration. #### Timelock Unlock Condition Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment -carries an index. When using any feature related to time, a [_Commitment Input_](https://github.com/iotaledger/tips-draft/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. +carries an index. When using any feature related to time, a +[_Commitment Input_](https://github.com/iotaledger/tips-draft/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is +needed as a reference of time. An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined @@ -487,8 +489,8 @@ in the Timelock Unlock Condition. - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the slot index of the commitment input. -- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, if - the `Future Bounded Slot Index` is equal or past the `Slot Index` specified in the unlock condition. +- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, + if the `Future Bounded Slot Index` is equal or past the `Slot Index` specified in the unlock condition.
Timelock Unlock Condition @@ -536,12 +538,17 @@ timelock and an expiration unlock condition. ##### Additional semantic transaction validation rules: +- A _Commitment Input_ must be present. +- Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the + slot index of the commitment input. +- Let `Past Bounded Slot Index` be given by `Commitment Index + Max Committable Age` where `Commitment Index` is the + slot index of the commitment input. - An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the target - `Address` (defined in Address Unlock Condition) in a transaction whose slot index is less than the `Slot Index` - defined in the unlock condition. + `Address` (defined in Address Unlock Condition) in a transaction if `Past Bounded Slot Index` is less than the + `Slot Index` defined in the unlock condition. - An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the - `Return Address` in a transaction whose slot index is greater or equal to the `Slot Index` defined in the unlock - condition. + `Return Address` in a transaction if `Future Bounded Slot Index` is greater or equal to the `Slot Index` defined in + the unlock condition. - Semantic validation of an output that has an Expiration Unlock Condition set and is unlocked by the `Return Address` must ignore: - [Semantic validation of Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) if @@ -550,11 +557,11 @@ timelock and an expiration unlock condition. The following table summarizes the outcome of the syntactic and semantic validation rules with respect to which address is allowed to unlock the output containing the Expiration Unlock Condition: -| Transaction Slot Index Condition | Outcome | -| --------------------------------------- | --------------------------------------------- | -| `Slot Index` = `0` | Output and containing transaction is invalid. | -| `Slot Index` > `Transaction Slot Index` | Unlockable by `Address` | -| `Slot Index` ≤ `Transaction Slot Index` | Unlockable by `Return Address` | +| Slot Index Condition | Outcome | +| ------------------------------------------ | --------------------------------------------- | +| `Slot Index` = `0` | Output and containing transaction is invalid. | +| `Slot Index` > `Past Bounded Slot Index` | Unlockable by `Address` | +| `Slot Index` ≤ `Future Bounded Slot Index` | Unlockable by `Return Address` |
Expiration Unlock Condition From 4772377e44dcfc4d38f7ce2c0fee48e07cc3bf44 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 17 Jul 2023 13:00:06 +0200 Subject: [PATCH 18/79] Add rationale section on expiration index choice --- tips/TIP-0038/tip-0038.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index b7bf9aa6b..ace8bb57d 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -32,7 +32,8 @@ replaces: TIP-18 - [Sender Feature](#sender-feature) - [Issuer Feature](#issuer-feature) - [Metadata Feature](#metadata-feature) -6. [Copyright](#copyright) +6. [Rationale & Design](#rationale--design) +7. [Copyright](#copyright) # Summary @@ -991,6 +992,14 @@ plugin. +# Rationale & Design + +## Expiration Bounded Indices + +In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and `Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest (`Min Committable Age` old) one, respectively. +In practice, however, it is likely that a node will provide a commitment within the range of maximum and minimum committable age. If both pick the same commitment this causes a period of time ("deadzone") where neither `Address` nor `Return Address` can unlock the output with the expiration unlock condition. +However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` and `Return Address` would be able to unlock the output, potentially allowing a double spend. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 83a4629010f5f078e2a3757c61f2aaf4cc848823 Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Tue, 18 Jul 2023 17:12:48 +0200 Subject: [PATCH 19/79] Fix broken links, typos --- tips/TIP-0038/tip-0038.md | 80 +++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ace8bb57d..0d85bbe30 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -38,21 +38,21 @@ replaces: TIP-18 # Summary This document defines the common building blocks used across multiple output types and transaction validation rules for -the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined +the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md), and the functionality defined in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 -- Rename "Alias" to "Account". +- "Alias" is renamed to "Account". - The `Unix Time` field of the Timelock Unlock Condition is replaced by `Slot Index`. - The `Unix Time` field of the Expiration Unlock Condition is replaced by `Slot Index`. # Motivation -The aim of this TIP is to define the common building blocks for output types that support for the use cases of the +The aim of this TIP is to define the common building blocks for output types that support the use cases of the Native Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. -The UTXO model becomes even more powerful when unlocking criteria (validation) of outputs are extended as demonstrated +The UTXO model becomes even more powerful when unlocking criteria (validation) of outputs are extended, as demonstrated by the [EUTXO model (Chakravarty et al., 2020)](https://fc20.ifca.ai/wtsc/WTSC2020/WTSC20_paper_25.pdf): instead of requiring only a valid signature for the output's address to unlock it, additional unlock conditions can be programmed into outputs. This programmability of outputs is the main idea behind the building blocks presented in this document. @@ -84,7 +84,7 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA # Output Design Primitives New output types add new features to the protocol and hence new transaction validation rules. While some of these new -features are specifically tied to one output type, some are general, LEGO like building blocks that may be put in +features are specifically tied to one output type, some are general, LEGO-like building blocks that may be put in several types of outputs. The following defines various primitives and the validation rules they introduce. @@ -92,18 +92,18 @@ The following defines various primitives and the validation rules they introduce ## Native Tokens in Outputs Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which -funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user defined native +funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user-defined native tokens, that is, tokens that are not IOTA coins but were minted by foundries and are tracked in the very same ledger. -Therefore, **every output must be able to hold not only IOTA coins, but also native tokens**. +Therefore, **every output must be able to hold not only IOTA coins but also native tokens**. Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the storage deposit requirements must be covered via IOTA coins. -User defined tokens are called Native Tokens on protocol level. The maximum supply of a particular native token -is defined by the representation chosen on protocol level for defining their amounts in outputs. Since native tokens are +User-defined tokens are called Native Tokens on the protocol level. The maximum supply of a particular native token +is defined by the representation chosen on the protocol level for defining their amounts in outputs. Since native tokens are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum supply of an -ERC-20 token as `MaxUint256`, therefore it should be possible to represent such huge amount of assets on layer 1. +ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on layer 1. Outputs must have the following fields to define the balance of native tokens they hold: @@ -164,7 +164,7 @@ Outputs must have the following fields to define the balance of native tokens th - **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 in the + outputs of the native tokens determine whether the tokens are burned (removed from the ledger) or melted in the foundry. ## Chain Constraint in UTXO @@ -178,7 +178,7 @@ in the graph induced by the UTXO spends. Each chain is identified by its globall ![](chain-constraint.png) -Account outputs, foundry outputs and NFT outputs all use this chain constraint concept and define their own unique +Account outputs, foundry outputs, and NFT outputs all use this chain constraint concept and define their own unique identifiers. ### Unlocking Chain Script Locked Outputs @@ -221,7 +221,7 @@ performed via a Signature Unlock in a transaction by signing the hash of validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). New additions are the Account Address and NFT Address types, which have to be unlocked with their -corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs) and +corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs), and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs.
@@ -324,8 +324,8 @@ the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0 The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, which is the recommended address format for user facing applications. -A usual bech32 encoded mainnet address starts with `iota1`, and continues with the bech32 encoded bytes of the address. -By choosing Address Type as a multiple of 8 for different address types, the first character after the `1` +A usual bech32 encoded mainnet address starts with `iota1` and continues with the bech32 encoded bytes of the address. +By choosing Address Type as a multiple of `8` for different address types, the first character after the `1` separator in the bech32 address will always be different. | Address | Type Byte as `uint8` | Bech32 Encoded | @@ -334,21 +334,21 @@ separator in the bech32 address will always be different. | Account | 8 | iota1**p**... | | NFT | 16 | iota1**z**... | -A user can identify by looking at the address whether it is a signature backed address, a smart contract chain account +A user can identify by looking at the address whether it is a signature-backed address, a smart contract chain account, or an NFT address. #### Storage Deposit Return Unlock Condition This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into -`Return Address`. When several of such outputs are consumed, their return amounts per `Return Addresses` are summed up +`Return Address`. When several of such outputs are consumed, their return amounts per `Return Addresses` are summed up, and the output side must deposit this total sum per `Return Address`. ##### Additional syntactic transaction validation rule: - `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock - conditions, no features and no native tokens. + conditions, no features, and no native tokens. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. ##### Additional semantic transaction validation rule: @@ -360,7 +360,7 @@ and the output side must deposit this total sum per `Return Address`. - have no [Native Tokens](#native-tokens-in-outputs), and - have no [Features](#features). - When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, - their return amounts per `Return Addresses` are summed up and the output side of the transaction must deposit _at + their return amounts per `Return Addresses` are summed up, and the output side of the transaction must deposit _at least_ this total sum per `Return Address` via output(s) that satisfy the previous condition.
@@ -466,7 +466,7 @@ and the output side must deposit this total sum per `Return Address`. This unlock condition makes it possible to send small amounts of IOTA coins or native tokens to addresses without having to lose control of the required storage deposit. It is also a vehicle to send on-chain requests to ISCP chains that do not require fees. To prevent the receiving party from blocking access to the storage deposit, it is advised to be used -together with the [Expiration Unlock Conditions](#expiration-unlock-conditions). The receiving party then has a +together with the [Expiration Unlock Conditions](#expiration-unlock-condition). The receiving party then has a sender-defined time window to agree to the transfer by consuming the output, or the sender regains total control after expiration. @@ -474,11 +474,11 @@ expiration. Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. When using any feature related to time, a -[_Commitment Input_](https://github.com/iotaledger/tips-draft/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is +[_Commitment Input_](../TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. -The lock is expired when the index of the slot to which the transaction belongs is equal or past the slot index defined +The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index defined in the Timelock Unlock Condition. ##### Additional syntactic transaction validation rules: @@ -490,8 +490,8 @@ in the Timelock Unlock Condition. - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the slot index of the commitment input. -- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction, - if the `Future Bounded Slot Index` is equal or past the `Slot Index` specified in the unlock condition. +- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction + if the `Future Bounded Slot Index` is equal to or past the `Slot Index` specified in the unlock condition.
Timelock Unlock Condition @@ -530,19 +530,19 @@ slot index has passed. The expiration feature can be viewed as an opt-in receive feature, because the recipient loses access to the received funds after the output expires, while the return address specified by the sender regains control over them. This feature is a big help for on-chain smart contract requests. Those that have expiration set and are sent to dormant smart -contract chains can be recovered by their senders. Not to mention the possibility to time requests by specifying both a +contract chains can be recovered by their senders, not to mention the possibility of time requests by specifying both a timelock and an expiration unlock condition. ##### Additional syntactic transaction validation rules: -- `Slot Index` field of a Expiration Unlock Condition must be > `0`. +- `Slot Index` field of an Expiration Unlock Condition must be > `0`. ##### Additional semantic transaction validation rules: - A _Commitment Input_ must be present. -- Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the +- Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age`, where `Commitment Index` is the slot index of the commitment input. -- Let `Past Bounded Slot Index` be given by `Commitment Index + Max Committable Age` where `Commitment Index` is the +- Let `Past Bounded Slot Index` be given by `Commitment Index + Max Committable Age`, where `Commitment Index` is the slot index of the commitment input. - An output that has an Expiration Unlock Condition set must only be consumed and unlocked by the target `Address` (defined in Address Unlock Condition) in a transaction if `Past Bounded Slot Index` is less than the @@ -561,8 +561,8 @@ is allowed to unlock the output containing the Expiration Unlock Condition `Past Bounded Slot Index` | Unlockable by `Address` | -| `Slot Index` ≤ `Future Bounded Slot Index` | Unlockable by `Return Address` | +| `Slot Index` > `Past Bounded Slot Index` | Unlockable by `Address`. | +| `Slot Index` ≤ `Future Bounded Slot Index` | Unlockable by `Return Address`. |
Expiration Unlock Condition @@ -676,7 +676,7 @@ output type. #### Sender Feature Every transaction consumes several elements from the UTXO set and creates new outputs. However, certain applications -(smart contracts) require to associate each output with exactly one sender address. Here, the sender feature is used to +(smart contracts) require associating each output with exactly one sender address. Here, the sender feature is used to specify the validated sender of an output. Outputs that support the Sender Feature may specify a `Sender` address which is validated by the protocol during @@ -684,7 +684,7 @@ transaction validation. ##### Additional semantic transaction validation rule: -- The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if `Sender` +- The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if the `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: @@ -799,8 +799,8 @@ unchanged. ##### Additional semantic transaction validation rule: -- When an Issuer Feature is present in an output representing the initial state of an UTXO state machine, the - transaction that contains this output is valid, if and only if `Issuer` address is unlocked in the transaction. Based +- When an Issuer Feature is present in an output representing the initial state of a UTXO state machine, the + transaction that contains this output is valid, if and only if the `Issuer` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - The Unlock of the first output in the transaction that contains the address is a valid Signature @@ -811,7 +811,7 @@ unchanged. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. -The main use case is proving authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) can +The main use case is proving the authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) can fill the Issuer Feature with their address that they have to unlock in the transaction. Issuers then can publicly disclose their addresses to prove the authenticity of the NFT once it is in circulation. @@ -909,14 +909,14 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the chain's -address, since user does not sign the layer 1 transaction. As a consequence, artist would have to mint NFTs themselves +address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. #### Metadata Feature -Outputs may carry additional data with them that is interpreted by higher layer applications built on the Tangle. The +Outputs may carry additional data with them that is interpreted by higher-layer applications built on the Tangle. The protocol treats this metadata as pure binary data, it has no effect on the validity of an output except that it -increases the required storage deposit. ISC is a great example of a higher layer protocol that makes use of Metadata +increases the required storage deposit. ISC is a great example of a higher-layer protocol that makes use of Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. ##### Additional syntactic transaction validation rules: @@ -953,8 +953,8 @@ Feature: smart contract request parameters are encoded in the metadata field #### Tag Feature A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not -only by their address, but also based on the `Tag`. **The combination of a Tag Feature, a Metadata Feature -and a Sender Feature makes it possible to retrieve data associated to an address and stored in outputs that were +only by their address but also based on the `Tag`. **The combination of a Tag Feature, a Metadata Feature, +and a Sender Feature makes it possible to retrieve data associated with an address and stored in outputs that were created by a specific party (`Sender`) for a specific purpose (`Tag`).** An example use case is voting on the Tangle via the From 5ec5633132a9ae71785fa57b3b7e6a271f5fdcbc Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 15 Aug 2023 09:41:08 +0200 Subject: [PATCH 20/79] Address typos and broken links --- tips/TIP-0038/tip-0038.md | 78 ++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 0d85bbe30..2ff30c87d 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -17,9 +17,8 @@ replaces: TIP-18 1. [Summary](#summary) 2. [Motivation](#motivation) -3. [Introduction to ledger programmability](#ledger-programmability) -4. [Building Blocks](#building-blocks) -5. [Output Design Primitives](#output-design-primitives) +3. [Building Blocks](#building-blocks) +4. [Output Design Primitives](#output-design-primitives) - [Native tokens](#native-tokens-in-outputs) - [Chain constraint](#chain-constraint-in-utxo) - [Functionality in Outputs](#functionality-in-outputs) @@ -32,8 +31,9 @@ replaces: TIP-18 - [Sender Feature](#sender-feature) - [Issuer Feature](#issuer-feature) - [Metadata Feature](#metadata-feature) -6. [Rationale & Design](#rationale--design) -7. [Copyright](#copyright) + - [Tag Feature](#tag-feature) +5. [Rationale & Design](#rationale--design) +6. [Copyright](#copyright) # Summary @@ -49,8 +49,8 @@ in this document is an extension of the primitives defined in TIP-18. # Motivation -The aim of this TIP is to define the common building blocks for output types that support the use cases of the -Native Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. +The aim of this TIP is to define the common building blocks for output types that support the use cases of the Native +Tokenization Framework and seamless interoperability between layer 1 and layer 2 tokenization concepts. The UTXO model becomes even more powerful when unlocking criteria (validation) of outputs are extended, as demonstrated by the [EUTXO model (Chakravarty et al., 2020)](https://fc20.ifca.ai/wtsc/WTSC2020/WTSC20_paper_25.pdf): instead of @@ -94,16 +94,19 @@ The following defines various primitives and the validation rules they introduce Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user-defined native tokens, that is, tokens that are not IOTA coins but were minted by foundries and are tracked in the very same ledger. -Therefore, **every output must be able to hold not only IOTA coins but also native tokens**. +Therefore, **every output must be able to hold not only IOTA coins but also native tokens**, with the exception of the +purpose-built Delegation Output introduced in [TIP-40](../TIP-0040/tip-0040.md). Since Native Tokens cannot be +delegated, this output has no need for holding Native Tokens. Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the storage deposit requirements must be covered via IOTA coins. -User-defined tokens are called Native Tokens on the protocol level. The maximum supply of a particular native token -is defined by the representation chosen on the protocol level for defining their amounts in outputs. Since native tokens are -also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the maximum -possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum supply of an -ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on layer 1. +User-defined tokens are called Native Tokens on the protocol level. The maximum supply of a particular native +token is defined by the representation chosen on the protocol level for defining their amounts in outputs. Since native +tokens are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account +the maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum +supply of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on +layer 1. Outputs must have the following fields to define the balance of native tokens they hold: @@ -221,8 +224,8 @@ performed via a Signature Unlock in a transaction by signing the hash of validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). New additions are the Account Address and NFT Address types, which have to be unlocked with their -corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs), and -the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs. +corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs), +and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs.
Address Unlock @@ -334,15 +337,13 @@ separator in the bech32 address will always be different. | Account | 8 | iota1**p**... | | NFT | 16 | iota1**z**... | -A user can identify by looking at the address whether it is a signature-backed address, a smart contract chain account, -or an NFT address. +A user can identify by looking at the address whether it is a signature-backed address, an account, or an NFT address. #### Storage Deposit Return Unlock Condition This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into -`Return Address`. When several of such outputs are consumed, their return amounts per `Return Addresses` are summed up, -and the output side must deposit this total sum per `Return Address`. +`Return Address`. ##### Additional syntactic transaction validation rule: @@ -474,12 +475,11 @@ expiration. Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. When using any feature related to time, a -[_Commitment Input_](../TIP-0045/tip-0045.md#commitment-input) is -needed as a reference of time. +[_Commitment Input_](../TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. -The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index defined -in the Timelock Unlock Condition. +The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index +defined in the Timelock Unlock Condition. ##### Additional syntactic transaction validation rules: @@ -490,8 +490,8 @@ in the Timelock Unlock Condition. - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the slot index of the commitment input. -- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction - if the `Future Bounded Slot Index` is equal to or past the `Slot Index` specified in the unlock condition. +- An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction if + the `Future Bounded Slot Index` is equal to or past the `Slot Index` specified in the unlock condition.
Timelock Unlock Condition @@ -800,8 +800,8 @@ unchanged. ##### Additional semantic transaction validation rule: - When an Issuer Feature is present in an output representing the initial state of a UTXO state machine, the - transaction that contains this output is valid, if and only if the `Issuer` address is unlocked in the transaction. Based - on the `Address Type`, an address is unlocked in the transaction, if and only if: + transaction that contains this output is valid, if and only if the `Issuer` address is unlocked in the transaction. + Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - Ed25519 Address: - The Unlock of the first output in the transaction that contains the address is a valid Signature Unlock with respect to the address. @@ -811,9 +811,9 @@ unchanged. - NFT Address: - The NFT Output that defines the address is consumed as input in the transaction. -The main use case is proving the authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) can -fill the Issuer Feature with their address that they have to unlock in the transaction. Issuers then can publicly -disclose their addresses to prove the authenticity of the NFT once it is in circulation. +The main use case is proving the authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) +can fill the Issuer Feature with their address that they have to unlock in the transaction. Issuers then can +publicly disclose their addresses to prove the authenticity of the NFT once it is in circulation.
Issuer Feature @@ -909,8 +909,8 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the chain's -address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves -on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. +address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs +themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. #### Metadata Feature @@ -954,8 +954,8 @@ Feature: smart contract request parameters are encoded in the metadata field A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not only by their address but also based on the `Tag`. **The combination of a Tag Feature, a Metadata Feature, -and a Sender Feature makes it possible to retrieve data associated with an address and stored in outputs that were -created by a specific party (`Sender`) for a specific purpose (`Tag`).** +and a Sender Feature makes it possible to retrieve data associated with an address and stored in outputs that +were created by a specific party (`Sender`) for a specific purpose (`Tag`).** An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) @@ -996,9 +996,13 @@ plugin. ## Expiration Bounded Indices -In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and `Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest (`Min Committable Age` old) one, respectively. -In practice, however, it is likely that a node will provide a commitment within the range of maximum and minimum committable age. If both pick the same commitment this causes a period of time ("deadzone") where neither `Address` nor `Return Address` can unlock the output with the expiration unlock condition. -However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` and `Return Address` would be able to unlock the output, potentially allowing a double spend. +In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and +`Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest +(`Min Committable Age` old) one, respectively. In practice, however, it is likely that a node will provide a commitment +within the range of maximum and minimum committable age. If both pick the same commitment this causes a period of time +("deadzone") where neither `Address` nor `Return Address` can unlock the output with the expiration unlock condition. +However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` +and `Return Address` would be able to unlock the output, potentially allowing a double spend. # Copyright From 171097da7b95e12195230bb4122dad5405dd9a4b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Sep 2023 10:05:39 +0200 Subject: [PATCH 21/79] Format schema tables (no content changes) --- tips/TIP-0038/tip-0038.md | 1164 +++++++++++++++++++------------------ 1 file changed, 606 insertions(+), 558 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 2ff30c87d..d37d307b7 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -111,45 +111,27 @@ layer 1. Outputs must have the following fields to define the balance of native tokens they hold: - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Native Tokens Countuint8The number of native tokens present in the output.
Native Tokens optAnyOf -
- Native Token - - - - - - - - - - - - - - - - -
NameTypeDescription
Token IDByteArray[38] - Identifier of the native token. Derivation defined here. -
Amountuint256 - Amount of tokens. -
-
-
+ Name + + Type + + Description +
Token IDByteArray[38]Identifier of the native token. Its derivation is defined in TIP-44.
Amountuint256Amount of native tokens of the given Token ID.
### Additional syntactic output validation rules: @@ -228,97 +210,108 @@ corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#un and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs.
- Address Unlock -
- Defines the Address that owns this output, that is, it can unlock it with the proper Unlock in a - transaction. -
+ Address Unlock Condition
- - - - - - - - - - - - - - - + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 - Set to value 0 to denote an Address Unlock Condition. -
Address -
- Ed25519 Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
+ Name + + Type + + Description +
Unlock Condition Typeuint8Set to value 0 to denote an Address Unlock Condition.
Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
| :information_source: Good to know about address format | @@ -365,103 +358,114 @@ Condition specified can only be consumed in a transaction that deposits `Ret least_ this total sum per `Return Address` via output(s) that satisfy the previous condition.
- Storage Deposit Return Unlock Condition -
- Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. -
+ Storage Deposit Return Unlock Condition +
Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address.
- - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 - Set to value 1 to denote a Storage Deposit Return Unlock Condition. -
Return AddressoneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
Return Amountuint64 - Amount of IOTA coins the consuming transaction should deposit to Return Address. -
+ Name + + Type + + Description +
Unlock Condition Typeuint8Set to value 1 to denote a Storage Deposit Return Unlock Condition.
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Return Amountuint64Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address.
This unlock condition makes it possible to send small amounts of IOTA coins or native tokens to addresses without having @@ -500,26 +504,32 @@ defined in the Timelock Unlock Condition.
+
+ Timelock Unlock Condition +
Defines a slot index until which the output can not be unlocked.
+
- - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 - Set to value 2 to denote a Timelock Unlock Condition. -
Slot Indexuint64 - Slot index starting from which the output can be consumed. -
+ Name + + Type + + Description +
Unlock Condition Typeuint8Set to value 2 to denote a Timelock Unlock Condition.
Slot Indexuint64Slot index starting from which the output can be consumed.
#### Expiration Unlock Condition @@ -565,104 +575,114 @@ is allowed to unlock the output containing the Expiration Unlock Condition - Expiration Unlock Condition -
- Defines a slot index until which only Address, defined in Address Unlock Condition, is allowed to - unlock the output. After the slot index is reached/passed, only Return Address can unlock it. -
+ Expiration Unlock Condition +
Defines a slot index until which only Address, defined in Address Unlock Condition, is allowed to unlock the output. After the slot index is reached/passed, only Return Address can unlock it.
- - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Condition Typeuint8 - Set to value 3 to denote an Expiration Unlock Condition. -
Return Address oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
Slot Indexuint64 - Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. -
+ Name + + Type + + Description +
Unlock Condition Typeuint8Set to value 3 to denote an Expiration Unlock Condition.
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Slot Indexuint64Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address.
### Features @@ -697,96 +717,109 @@ transaction validation. - The NFT Output that defines the address is consumed as input in the transaction.
- Sender Feature -
- Identifies the validated sender of the output. -
+ Sender Feature +
Identifies the validated sender of the output.
- - - - - - - - - - - - - - - + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 - Set to value 0 to denote a Sender Feature. -
Sender oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
+ Name + + Type + + Description +
Feature Typeuint8Set to value 0 to denote a Sender Feature.
Sender oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
#### Issuer Feature @@ -816,96 +849,109 @@ can fill the Issuer Feature with their address that they have to unlock i publicly disclose their addresses to prove the authenticity of the NFT once it is in circulation.
- Issuer Feature -
- Identifies the validated issuer of the UTXO state machine. -
+ Issuer Feature +
Identifies the validated issuer of the UTXO state machine.
- - - - - - - - - - - - - - - + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 - Set to value 1 to denote an Issuer Feature. -
Issuer oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - -
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
+ Name + + Type + + Description +
Feature Typeuint8Set to value 1 to denote a Issuer Feature.
Issuer oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Issuer` field can only contain the chain's @@ -924,30 +970,31 @@ Feature: smart contract request parameters are encoded in the metadata field - An output with Metadata Feature is valid, if and only if 0 < `length(Data)` ≤ `Max Metadata Length`.
- Metadata Feature -
- Defines metadata (arbitrary binary data) that will be stored in the output. -
+ Metadata Feature +
Defines metadata (arbitrary binary data) that will be stored in the output.
- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 - Set to value 2 to denote a Metadata Feature. -
Data(uint16)ByteArrayBinary data. A leading uint16 denotes its length.
+ Name + + Type + + Description +
Feature Typeuint8Set to value 2 to denote a Metadata Feature.
Data(uint16)ByteArrayBinary data. A leading uint16 denotes its length.
#### Tag Feature @@ -966,30 +1013,31 @@ plugin. - An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ `Max Tag Length`.
- Tag Feature -
- Defines an indexation tag to which the output can be indexed by additional node plugins. -
+ Tag Feature +
Defines an indexation tag to which the output can be indexed by additional node plugins.
- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Feature Typeuint8 - Set to value 3 to denote a Tag Feature. -
Tag(uint8)ByteArrayBinary indexation tag. A leading uint8 denotes its length.
+ Name + + Type + + Description +
Feature Typeuint8Set to value 3 to denote a Tag Feature.
Tag(uint8)ByteArrayBinary indexation data. A leading uint8 denotes its length.
# Rationale & Design From 912dde094d9f3a32bf7bc19e4563cf3d3bdc4417 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 26 Sep 2023 11:51:23 +0200 Subject: [PATCH 22/79] Do not allow Mana in SDRUC return transaction --- tips/TIP-0038/tip-0038.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d37d307b7..b7613fa7a 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -352,6 +352,7 @@ Condition specified can only be consumed in a transaction that deposits `Ret - are of type Basic Output, - have only an [Address Unlock Condition](#address-unlock-condition) defined, - have no [Native Tokens](#native-tokens-in-outputs), and + - have no Mana, and - have no [Features](#features). - When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, their return amounts per `Return Addresses` are summed up, and the output side of the transaction must deposit _at From 4f065ee0f7e3505dc0ce51fc68aff148a1dcc532 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 26 Sep 2023 12:43:07 +0200 Subject: [PATCH 23/79] Add dedicated Address section w/ basic addresses --- tips/TIP-0038/tip-0038.md | 103 +++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 18 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index b7613fa7a..4ee74cf23 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -190,6 +190,91 @@ These new functionalities are grouped into two categories: Each output type defines its list of supported Unlock Conditions and Features. +### Addresses + +The following section shows the basic supported Address Types and their serialization. + +| Address | Type Byte as `uint8` | Bech32 Encoded | +| ------- | -------------------- | -------------- | +| Ed25519 | 0 | iota1**q**... | +| Account | 8 | iota1**p**... | +| NFT | 16 | iota1**z**... | + +The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, +which is the recommended address format for user facing applications. + +An IOTA mainnet address starts with `iota1`, and continues with the bech32 encoded bytes of the address. By choosing the +integer value of the _Address Type_ as a multiple of 8 for different address types, the first character after the `1` +separator in the bech32 address will always be different. + +A user can identify by looking at the address whether it is a signature-backed address, an Account, or an NFT address. + +#### Ed25519 Address + + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+ +#### Account Address + + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 8 to denote an Account Address. +
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+ +#### NFT Address + + + + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 + Set to value 16 to denote an NFT Address. +
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+ ### Unlock Conditions New output features that introduce unlocking conditions, that is, they define constraints on how the output can be @@ -314,24 +399,6 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t -| :information_source: Good to know about address format | -| ------------------------------------------------------ | - -The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, -which is the recommended address format for user facing applications. - -A usual bech32 encoded mainnet address starts with `iota1` and continues with the bech32 encoded bytes of the address. -By choosing Address Type as a multiple of `8` for different address types, the first character after the `1` -separator in the bech32 address will always be different. - -| Address | Type Byte as `uint8` | Bech32 Encoded | -| ------- | -------------------- | -------------- | -| Ed25519 | 0 | iota1**q**... | -| Account | 8 | iota1**p**... | -| NFT | 16 | iota1**z**... | - -A user can identify by looking at the address whether it is a signature-backed address, an account, or an NFT address. - #### Storage Deposit Return Unlock Condition This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock From 0e20137f630385d383ecabcd7f430c381f406341 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 26 Sep 2023 12:44:03 +0200 Subject: [PATCH 24/79] Add Addresses to ToC --- tips/TIP-0038/tip-0038.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 4ee74cf23..69fcf844a 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -22,6 +22,7 @@ replaces: TIP-18 - [Native tokens](#native-tokens-in-outputs) - [Chain constraint](#chain-constraint-in-utxo) - [Functionality in Outputs](#functionality-in-outputs) + - [Addresses](#addresses) - [Unlock Conditions](#unlock-conditions) - [Address Unlock Condition](#address-unlock-condition) - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) From 2f02fbcec5b503fb71f18f43f6b821ba2a2e9e3e Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 26 Sep 2023 14:12:41 +0200 Subject: [PATCH 25/79] Update tips/TIP-0038/tip-0038.md Co-authored-by: Thibault Martinez --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 69fcf844a..0699d98f2 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -419,7 +419,7 @@ Condition specified can only be consumed in a transaction that deposits `Ret transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: - are of type Basic Output, - have only an [Address Unlock Condition](#address-unlock-condition) defined, - - have no [Native Tokens](#native-tokens-in-outputs), and + - have no [Native Tokens](#native-tokens-in-outputs), - have no Mana, and - have no [Features](#features). - When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, From 2745fa371f4216ee9d8f8ee8f24440609ebe246b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 27 Sep 2023 15:17:00 +0200 Subject: [PATCH 26/79] Remove duplicated Timelock summary --- tips/TIP-0038/tip-0038.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 0699d98f2..e691432f0 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -566,13 +566,6 @@ defined in the Timelock Unlock Condition. - An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction if the `Future Bounded Slot Index` is equal to or past the `Slot Index` specified in the unlock condition. -
- Timelock Unlock Condition -
- Defines a slot index until which the output can not be unlocked. -
-
-
Timelock Unlock Condition
Defines a slot index until which the output can not be unlocked.
From 31170d452a615e6f66a98fa287802d5bf3b8eee7 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 27 Sep 2023 17:19:34 +0200 Subject: [PATCH 27/79] Add example for Expiration UC indices --- tips/TIP-0038/tip-0038.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index e691432f0..3a8476e1b 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -605,6 +605,9 @@ is a big help for on-chain smart contract requests. Those that have expiration s contract chains can be recovered by their senders, not to mention the possibility of time requests by specifying both a timelock and an expiration unlock condition. +For the rationale behind the index choices for the slot index conditions in this Unlock Condition, refer to +[Expiration Unlock Condition Index Bounds](#expiration-unlock-condition-index-bounds). + ##### Additional syntactic transaction validation rules: - `Slot Index` field of an Expiration Unlock Condition must be > `0`. @@ -1104,7 +1107,7 @@ plugin. # Rationale & Design -## Expiration Bounded Indices +## Expiration Unlock Condition Index Bounds In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and `Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest @@ -1114,6 +1117,21 @@ within the range of maximum and minimum committable age. If both pick the same c However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` and `Return Address` would be able to unlock the output, potentially allowing a double spend. +**Example with optimal Commitment Input choice** + +Suppose that `Minimum Committable Age` is 3 and `Maximum Commitable Age` is 10, and there is an Expiration Unlock +Condition with `Slot Index` set to 20. Note the restrictions on the Commitment Input within a transaction relative to a +[Block's `Issuing Time`](../TIP-0046/tip-0046.md#syntactic-validation). If the current slot is 19, the oldest Commitment +the Address owner can pick as the Commitment Input is the one with index = 19-10 = 9 and can therefore unlock the +output, because 20 > 9+10. The newest Commitment the Return Address owner can pick is the one with index 19-3 = 16, and +because 20 <= 16+3 is not true, they cannot unlock. If the current slot is 20, the oldest Commitment the Address owner +can pick is the one with index = 20-10 = 10, but since 20 > 10+10 is not true, they cannot unlock. Now the newest +Commitment the Return Address owner can pick is 20-3 = 17, and because 20 <= 17+3 is true, they can unlock. + +If however, the current slot is 18, and both owners would use the same Commitment Input with index 13, within the range +of 8 and 15 of possible commitments, then neither one of them can unlock the output, as neither 20 > 13+10 nor 20 <= +13+3 is true. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From d511084b073b78969d2711663e16d1ddc3247712 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 3 Oct 2023 12:12:42 +0200 Subject: [PATCH 28/79] Update Native Token fragment --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 3a8476e1b..f07c82b5a 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -19,7 +19,7 @@ replaces: TIP-18 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) 4. [Output Design Primitives](#output-design-primitives) - - [Native tokens](#native-tokens-in-outputs) + - [Native tokens](#native-token) - [Chain constraint](#chain-constraint-in-utxo) - [Functionality in Outputs](#functionality-in-outputs) - [Addresses](#addresses) @@ -90,7 +90,7 @@ several types of outputs. The following defines various primitives and the validation rules they introduce. -## Native Tokens in Outputs +## Native Token Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user-defined native From a0c1052183b2b131a755edc68f5716ea929d5b58 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 3 Oct 2023 13:17:21 +0200 Subject: [PATCH 29/79] Add Signatures section --- tips/TIP-0038/tip-0038.md | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index f07c82b5a..6afffc49d 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -23,6 +23,7 @@ replaces: TIP-18 - [Chain constraint](#chain-constraint-in-utxo) - [Functionality in Outputs](#functionality-in-outputs) - [Addresses](#addresses) + - [Signatures](#signatures) - [Unlock Conditions](#unlock-conditions) - [Address Unlock Condition](#address-unlock-condition) - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) @@ -276,6 +277,45 @@ A user can identify by looking at the address whether it is a signature-backed a +### Signatures + +#### Ed25519 Signature + +The _Ed25519 Signature_ is supported and it is serialized as follows: + +
+ Ed25519 Signature +
An Ed25519 Signature with the public key that verifies it.
+
+ + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Signature Typeuint8Set to value 0 to denote an Ed25519 Signature.
Public KeyByteArray[32]The Ed25519 public key that verifies the signature.
SignatureByteArray[64]The Ed25519 signature that must be verified according to TIP-14.
+ ### Unlock Conditions New output features that introduce unlocking conditions, that is, they define constraints on how the output can be From 147752c2902608181537f28b4ef4960e2d30ca9f Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 3 Oct 2023 21:30:55 +0200 Subject: [PATCH 30/79] Replace Native Tokens by Feature --- tips/TIP-0038/tip-0038.md | 112 ++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 42 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 6afffc49d..0b0bf00b5 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -34,6 +34,7 @@ replaces: TIP-18 - [Issuer Feature](#issuer-feature) - [Metadata Feature](#metadata-feature) - [Tag Feature](#tag-feature) + - [Native Token Feature](#native-token-feature) 5. [Rationale & Design](#rationale--design) 6. [Copyright](#copyright) @@ -48,6 +49,8 @@ in this document is an extension of the primitives defined in TIP-18. - "Alias" is renamed to "Account". - The `Unix Time` field of the Timelock Unlock Condition is replaced by `Slot Index`. - The `Unix Time` field of the Expiration Unlock Condition is replaced by `Slot Index`. +- The list of _Native Tokens_ in Basic, Alias, NFT and Foundry Outputs is replaced by a _Native Token Feature_ that + holds a single Native Token which can only be present in Basic and Foundry outputs. # Motivation @@ -61,12 +64,12 @@ into outputs. This programmability of outputs is the main idea behind the buildi In combination with the other layer 1 output types that build on top of the primitives defined here, users will be able to interact with layer 2 smart contracts by posting requests through the Tangle. Requests can carry commands to smart -contracts and can additionally also transfer native tokens and NFTs. +contracts and can additionally also transfer Native Tokens and NFTs. With the Native Tokens defined in this TIP, users will be able to mint their own tokens directly in the base ledger, -which can then be transferred without any fees just like regular IOTA coins. Each native token has its own supply -control policy enforced by the protocol. These policies are transparent to all network participants. Issuers will be -able to store metadata about their tokens on-ledger, accessible to anyone. +which can then be transferred just like regular IOTA coins. Each native token has its own supply control policy enforced +by the protocol. These policies are transparent to all network participants. Issuers will be able to store metadata +about their tokens on-ledger, accessible to anyone. # Building Blocks @@ -91,50 +94,24 @@ several types of outputs. The following defines various primitives and the validation rules they introduce. -## Native Token +## Native Tokens Outputs are records in the UTXO ledger that track ownership of funds. Thus, each output must be able to specify which -funds it holds. With the addition of the Native Tokenization Framework, outputs may also carry user-defined native -tokens, that is, tokens that are not IOTA coins but were minted by foundries and are tracked in the very same ledger. -Therefore, **every output must be able to hold not only IOTA coins but also native tokens**, with the exception of the -purpose-built Delegation Output introduced in [TIP-40](../TIP-0040/tip-0040.md). Since Native Tokens cannot be -delegated, this output has no need for holding Native Tokens. +funds it holds. With the addition of the Native Tokenization Framework, some outputs may also carry user-defined native +tokens via a _Native Token Feature_, that is, tokens that are not IOTA coins but were minted by foundries and are +tracked in the very same ledger. -Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens, the storage +Dust protection applies to all outputs, therefore it is not possible for outputs to hold only native tokens. The storage deposit requirements must be covered via IOTA coins. -User-defined tokens are called Native Tokens on the protocol level. The maximum supply of a particular native -token is defined by the representation chosen on the protocol level for defining their amounts in outputs. Since native -tokens are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account -the maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum -supply of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on +User-defined tokens are called _Native Tokens_ on the protocol level. The maximum supply of a particular native token is +defined by the representation chosen on the protocol level for defining their amounts in outputs. Since native tokens +are also a vehicle to wrap layer 2 tokens into layer 1 tokens, the chosen representation must take into account the +maximum possible supply of layer 2 tokens. Solidity, the most popular smart contract language defines the maximum supply +of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on layer 1. -Outputs must have the following fields to define the balance of native tokens they hold: - - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Token IDByteArray[38]Identifier of the native token. Its derivation is defined in TIP-44.
Amountuint256Amount of native tokens of the given Token ID.
+Outputs that can carry Native Tokens have a [_Native Token Feature_](#todo). ### Additional syntactic output validation rules: @@ -188,7 +165,7 @@ that support them. These new functionalities are grouped into two categories: - **Unlock Conditions** and -- simple **Features**. +- **Features**. Each output type defines its list of supported Unlock Conditions and Features. @@ -1145,6 +1122,57 @@ plugin. +#### Native Token Feature + +
+ Native Token Feature +
A feature that carries a user-defined Native Token minted by a Foundry Output.
+
+ + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 4 to denote a Native Token Feature.
Token IDByteArray[38]Identifier of the native token. Its derivation is defined in TIP-44.
Amountuint256Amount of native tokens of the given Token ID.
+ +##### Additional syntactic output validation rules: + +- `Amount` must not be `0`. + +##### Additional semantic transaction validation rules: + +- The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs + equals that of the created outputs. +- When the transaction is **imbalanced** and 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 in the + foundry. + - TODO: Transaction Burn Flag. + # Rationale & Design ## Expiration Unlock Condition Index Bounds From a3519488094b69fff9829cffd39fd799dd2eb1a5 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 10:12:16 +0200 Subject: [PATCH 31/79] Add description to Address Types --- tips/TIP-0038/tip-0038.md | 209 ++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 121 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 0b0bf00b5..44fe4ec0b 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -19,7 +19,7 @@ replaces: TIP-18 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) 4. [Output Design Primitives](#output-design-primitives) - - [Native tokens](#native-token) + - [Native Tokens](#native-tokens) - [Chain constraint](#chain-constraint-in-utxo) - [Functionality in Outputs](#functionality-in-outputs) - [Addresses](#addresses) @@ -190,68 +190,92 @@ A user can identify by looking at the address whether it is a signature-backed a #### Ed25519 Address +
+ Ed25519 Address +
An Address derived from an Ed25519 Public Key.
+
- - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+ Name + + Type + + Description +
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
#### Account Address +
+ Account Address +
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account.
+
- - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 - Set to value 8 to denote an Account Address. -
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+ Name + + Type + + Description +
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
#### NFT Address +
+ NFT Address +
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT.
+
- - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Address Typeuint8 - Set to value 16 to denote an NFT Address. -
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+ Name + + Type + + Description +
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
### Signatures @@ -314,6 +338,7 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t
Address Unlock Condition +
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction.
@@ -337,81 +362,23 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t From ba4b1ffcb9f748538d19f48b4cf9261e021c2fc1 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 10:17:27 +0200 Subject: [PATCH 32/79] Add new Address types to unlock conditions --- tips/TIP-0038/tip-0038.md | 160 ++++++-------------------------------- 1 file changed, 22 insertions(+), 138 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 44fe4ec0b..ee55f6a79 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -436,81 +436,23 @@ Condition specified can only be consumed in a transaction that deposits `Ret @@ -649,81 +591,23 @@ is allowed to unlock the output containing the Expiration Unlock Condition
Ed25519 Address -
Ed25519 Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
Account Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
NFT Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+
+ Multi Address +
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
Ed25519 Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
Account Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
NFT Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+
+ Multi Address +
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
- - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
Account Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
NFT Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+
+ Multi Address +
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
From 00ab201551f442dbceb89ea6e2472662296409dd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 11:41:52 +0200 Subject: [PATCH 33/79] Add Multi Address to Sender & Issuer Feature --- tips/TIP-0038/tip-0038.md | 152 ++++---------------------------------- 1 file changed, 14 insertions(+), 138 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ee55f6a79..bbcd5b7a2 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -675,81 +675,19 @@ transaction validation.
Ed25519 Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
Account Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
NFT Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+
+ Multi Address +
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
@@ -807,81 +745,19 @@ publicly disclose their addresses to prove the authenticity of the NFT once it i
Ed25519 Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 0 to denote an Ed25519 Address.
PubKeyHashByteArray[32]The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
Account Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 8 to denote an Account Address.
Account IDByteArray[32]The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
NFT Address - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 16 to denote an NFT Address.
NFT IDByteArray[32]The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+
+ Multi Address +
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From 19ee9ae5802575d8dda03f8f4d80eb05256d158b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 11:46:24 +0200 Subject: [PATCH 34/79] Simplify indentation of design primitives --- tips/TIP-0038/tip-0038.md | 109 ++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 57 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index bbcd5b7a2..36b1c76e8 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -21,20 +21,19 @@ replaces: TIP-18 4. [Output Design Primitives](#output-design-primitives) - [Native Tokens](#native-tokens) - [Chain constraint](#chain-constraint-in-utxo) - - [Functionality in Outputs](#functionality-in-outputs) - - [Addresses](#addresses) - - [Signatures](#signatures) - - [Unlock Conditions](#unlock-conditions) - - [Address Unlock Condition](#address-unlock-condition) - - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) - - [Timelock Unlock Condition](#timelock-unlock-condition) - - [Expiration Unlock Condition](#expiration-unlock-condition) - - [Features](#features) - - [Sender Feature](#sender-feature) - - [Issuer Feature](#issuer-feature) - - [Metadata Feature](#metadata-feature) - - [Tag Feature](#tag-feature) - - [Native Token Feature](#native-token-feature) + - [Addresses](#addresses) + - [Signatures](#signatures) + - [Unlock Conditions](#unlock-conditions) + - [Address Unlock Condition](#address-unlock-condition) + - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) + - [Timelock Unlock Condition](#timelock-unlock-condition) + - [Expiration Unlock Condition](#expiration-unlock-condition) + - [Features](#features) + - [Sender Feature](#sender-feature) + - [Issuer Feature](#issuer-feature) + - [Metadata Feature](#metadata-feature) + - [Tag Feature](#tag-feature) + - [Native Token Feature](#native-token-feature) 5. [Rationale & Design](#rationale--design) 6. [Copyright](#copyright) @@ -90,7 +89,16 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA New output types add new features to the protocol and hence new transaction validation rules. While some of these new features are specifically tied to one output type, some are general, LEGO-like building blocks that may be put in -several types of outputs. +several types of outputs. The programmability of outputs opens the door for implementing new functionalities for the +base protocol. While some outputs were specifically designed for such new features, some are optional additions that may +be used with any outputs that support them. + +These functionalities are grouped into two categories: + +- **Unlock Conditions** and +- **Features**. + +Each output type defines its list of supported Unlock Conditions and Features. The following defines various primitives and the validation rules they introduce. @@ -156,20 +164,7 @@ Since such addresses are accounts in the ledger, it is possible to send funds to of such funds is designed in a way that **proving ownership of the address is reduced to the ability to unlock the corresponding output that defines the address.** -## Functionality in Outputs - -The programmability of outputs opens the door for implementing new functionalities for the base protocol. While some -outputs were specifically designed for such new features, some are optional additions that may be used with any outputs -that support them. - -These new functionalities are grouped into two categories: - -- **Unlock Conditions** and -- **Features**. - -Each output type defines its list of supported Unlock Conditions and Features. - -### Addresses +## Addresses The following section shows the basic supported Address Types and their serialization. @@ -188,7 +183,7 @@ separator in the bech32 address will always be different. A user can identify by looking at the address whether it is a signature-backed address, an Account, or an NFT address. -#### Ed25519 Address +### Ed25519 Address
Ed25519 Address @@ -218,7 +213,7 @@ A user can identify by looking at the address whether it is a signature-backed a -#### Account Address +### Account Address
Account Address @@ -248,7 +243,7 @@ A user can identify by looking at the address whether it is a signature-backed a -#### NFT Address +### NFT Address
NFT Address @@ -278,9 +273,9 @@ A user can identify by looking at the address whether it is a signature-backed a -### Signatures +## Signatures -#### Ed25519 Signature +### Ed25519 Signature The _Ed25519 Signature_ is supported and it is serialized as follows: @@ -317,7 +312,7 @@ The _Ed25519 Signature_ is supported and it is serialized as follows: -### Unlock Conditions +## Unlock Conditions New output features that introduce unlocking conditions, that is, they define constraints on how the output can be unlocked and spent, are grouped under the field Unlock Conditions. @@ -325,7 +320,7 @@ unlocked and spent, are grouped under the field Unlock Conditions. Each output **must not contain more than one unlock condition of each type** and not all unlock condition types are supported for each output type. -#### Address Unlock Condition +### Address Unlock Condition It is merely a layout change that the previously defined `Address` field of outputs ([TIP-7](../TIP-0007/tip-0007.md)) is represented as an Address Unlock Condition. Unlocking an Ed25519 Address doesn't change, it has to be @@ -384,20 +379,20 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t -#### Storage Deposit Return Unlock Condition +### Storage Deposit Return Unlock Condition This unlock condition is employed to achieve conditional sending. An output that has Storage Deposit Return Unlock Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into `Return Address`. -##### Additional syntactic transaction validation rule: +#### Additional syntactic transaction validation rule: - `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock conditions, no features, and no native tokens. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. -##### Additional semantic transaction validation rule: +#### Additional semantic transaction validation rule: - An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: @@ -470,7 +465,7 @@ together with the [Expiration Unlock Conditions](#expiration-unlock-condition). sender-defined time window to agree to the transfer by consuming the output, or the sender regains total control after expiration. -#### Timelock Unlock Condition +### Timelock Unlock Condition Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. When using any feature related to time, a @@ -480,11 +475,11 @@ An output that contains a Timelock Unlock Condition can not be unlocked b The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index defined in the Timelock Unlock Condition. -##### Additional syntactic transaction validation rules: +#### Additional syntactic transaction validation rules: - `Slot Index` field of a Timelock Unlock Condition must be > `0`. -##### Additional semantic transaction validation rules: +#### Additional semantic transaction validation rules: - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the @@ -520,7 +515,7 @@ defined in the Timelock Unlock Condition. -#### Expiration Unlock Condition +### Expiration Unlock Condition The expiration feature of outputs makes it possible for the return address to reclaim an output after a given expiration slot index has passed. @@ -534,11 +529,11 @@ timelock and an expiration unlock condition. For the rationale behind the index choices for the slot index conditions in this Unlock Condition, refer to [Expiration Unlock Condition Index Bounds](#expiration-unlock-condition-index-bounds). -##### Additional syntactic transaction validation rules: +#### Additional syntactic transaction validation rules: - `Slot Index` field of an Expiration Unlock Condition must be > `0`. -##### Additional semantic transaction validation rules: +#### Additional semantic transaction validation rules: - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age`, where `Commitment Index` is the @@ -618,7 +613,7 @@ is allowed to unlock the output containing the Expiration Unlock Condition -### Features +## Features New output features that do not introduce unlocking conditions, but rather add new functionality and add constraints on output creation are grouped under Features. @@ -626,7 +621,7 @@ output creation are grouped under Features. Each output **must not contain more than one feature of each type** and not all feature types are supported for each output type. -#### Sender Feature +### Sender Feature Every transaction consumes several elements from the UTXO set and creates new outputs. However, certain applications (smart contracts) require associating each output with exactly one sender address. Here, the sender feature is used to @@ -635,7 +630,7 @@ specify the validated sender of an output. Outputs that support the Sender Feature may specify a `Sender` address which is validated by the protocol during transaction validation. -##### Additional semantic transaction validation rule: +#### Additional semantic transaction validation rule: - The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if the `Sender` address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and @@ -693,7 +688,7 @@ transaction validation. -#### Issuer Feature +### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state machine with [chain constraint](#chain-constraint-in-utxo) (account, NFT). Only when the state machine is created (e.g. @@ -701,7 +696,7 @@ minted) it is checked during transaction validation that an output corresponding every future transition of the state machine, it is instead checked that the issuer feature is still present and unchanged. -##### Additional semantic transaction validation rule: +#### Additional semantic transaction validation rule: - When an Issuer Feature is present in an output representing the initial state of a UTXO state machine, the transaction that contains this output is valid, if and only if the `Issuer` address is unlocked in the transaction. @@ -767,14 +762,14 @@ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Is address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. -#### Metadata Feature +### Metadata Feature Outputs may carry additional data with them that is interpreted by higher-layer applications built on the Tangle. The protocol treats this metadata as pure binary data, it has no effect on the validity of an output except that it increases the required storage deposit. ISC is a great example of a higher-layer protocol that makes use of Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. -##### Additional syntactic transaction validation rules: +#### Additional syntactic transaction validation rules: - An output with Metadata Feature is valid, if and only if 0 < `length(Data)` ≤ `Max Metadata Length`. @@ -806,7 +801,7 @@ Feature: smart contract request parameters are encoded in the metadata field -#### Tag Feature +### Tag Feature A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not only by their address but also based on the `Tag`. **The combination of a Tag Feature, a Metadata Feature, @@ -817,7 +812,7 @@ An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) plugin. -##### Additional syntactic transaction validation rules: +#### Additional syntactic transaction validation rules: - An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ `Max Tag Length`. @@ -849,7 +844,7 @@ plugin. -#### Native Token Feature +### Native Token Feature
Native Token Feature @@ -884,11 +879,11 @@ plugin. -##### Additional syntactic output validation rules: +#### Additional syntactic output validation rules: - `Amount` must not be `0`. -##### Additional semantic transaction validation rules: +#### Additional semantic transaction validation rules: - The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs equals that of the created outputs. From 7f7b9ab89541ff98229ac9be68974ed0bb754484 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 12:37:51 +0200 Subject: [PATCH 35/79] Add restricted addrs in Sender & Issuer Feat note --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 36b1c76e8..ff6a4b757 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -688,6 +688,8 @@ transaction validation. +_Restricted Addresses_ cannot be put into _Sender Features_ because they are resolved to the underlying address during unlocking Therefore, when using an Sender Feature with a Restricted Address, the underlying Address must be put into the feature. + ### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state @@ -762,6 +764,8 @@ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Is address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. +_Restricted Addresses_ cannot be put into _Issuer Features_ because they are resolved to the underlying address during unlocking. Therefore, when using an Issuer Feature with a Restricted Address, the underlying Address must be put into the feature. + ### Metadata Feature Outputs may carry additional data with them that is interpreted by higher-layer applications built on the Tangle. The From f8ee7d4ab6cba0ffff9ac87bb8a25c03f4d28a15 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 13:41:01 +0200 Subject: [PATCH 36/79] Define unlock criteria for address individually --- tips/TIP-0038/tip-0038.md | 41 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ff6a4b757..341f93fe4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -213,6 +213,11 @@ A user can identify by looking at the address whether it is a signature-backed a +#### Unlocking + +The address is unlocked in a transaction if and only if: +- The _Unlock_ of the first output in the transaction that contains the address is a valid _Signature Unlock_ with respect to the address. + ### Account Address
@@ -243,6 +248,11 @@ A user can identify by looking at the address whether it is a signature-backed a +#### Unlocking + +The address is unlocked in a transaction if and only if: +- The _Account Output_ from whose _Account ID_ the address is derived from, is **state transitioned** in the transaction. A governance transition does not unlock the address. + ### NFT Address
@@ -273,6 +283,11 @@ A user can identify by looking at the address whether it is a signature-backed a +#### Unlocking + +The address is unlocked in a transaction if and only if: +- The _NFT Output_ from whose _NFT ID_ the address is derived from, is consumed as an input in the transaction. + ## Signatures ### Ed25519 Signature @@ -633,16 +648,7 @@ transaction validation. #### Additional semantic transaction validation rule: - The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if the `Sender` - address is unlocked in the transaction. Based on the `Address Type`, an address is unlocked in the transaction, if and - only if: - - Ed25519 Address: - - The Unlock of the first output in the transaction that contains the address is a valid Signature - Unlock with respect to the address. - - Account Address: - - The Account Output that defines the address is **state transitioned** in the transaction. A governance - transition does not unlock the address. - - NFT Address: - - The NFT Output that defines the address is consumed as input in the transaction. + address is unlocked in the transaction. Every Address Type specifies under which conditions it is considered unlocked.
Sender Feature @@ -700,20 +706,11 @@ unchanged. #### Additional semantic transaction validation rule: -- When an Issuer Feature is present in an output representing the initial state of a UTXO state machine, the - transaction that contains this output is valid, if and only if the `Issuer` address is unlocked in the transaction. - Based on the `Address Type`, an address is unlocked in the transaction, if and only if: - - Ed25519 Address: - - The Unlock of the first output in the transaction that contains the address is a valid Signature - Unlock with respect to the address. - - Account Address: - - The Account Output that defines the address is **state transitioned** in the transaction. A governance - transition does not unlock the address. - - NFT Address: - - The NFT Output that defines the address is consumed as input in the transaction. +- The _Issuer Feature_, and hence the output and transaction that contain it, is valid, if and only if the `Issuer` + address is unlocked in the transaction. Every Address Type specifies under which conditions it is considered unlocked. The main use case is proving the authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) -can fill the Issuer Feature with their address that they have to unlock in the transaction. Issuers then can +can fill the _Issuer Feature_ with their address that they have to unlock in the transaction. Issuers then can publicly disclose their addresses to prove the authenticity of the NFT once it is in circulation.
From 4a1a83587ff449bae45c96da249a5a8e311605b6 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 15:22:00 +0200 Subject: [PATCH 37/79] Add Restricted Address to Sender & Issuer Feature --- tips/TIP-0038/tip-0038.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 341f93fe4..52bcc7099 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -690,6 +690,10 @@ transaction validation. Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
@@ -753,6 +757,10 @@ publicly disclose their addresses to prove the authenticity of the NFT once it i Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
From 8a321ee069133822569a044dbf4b2d46cceb46c7 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 16:36:35 +0200 Subject: [PATCH 38/79] Add Migration for Native Tokens --- tips/TIP-0038/tip-0038.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 52bcc7099..d8e4e405b 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -904,6 +904,23 @@ plugin. foundry. - TODO: Transaction Burn Flag. +# Migration + +## Native Tokens + +The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capabaility is moved from a field to the _Native Token Feature_. Moreover, each output can only hold one Native Token instead of up to 64. This section specifies the migration. + +Let `Owner Address` be: +- the _Alias Address_ if the Output is an _Alias Output_. +- the _NFT Address_ if the Output is an _NFT Output_. +- the _Address_ in the _Address Unlock Condition_ in the output if the Output is a _Basic Output_. +- the _Alias Address_ in the _Immutable Alias Address Unlock Condition_ in the output if the Output is a _Foundry Output_. + +For each Native Token `Token` in an output with `Native Tokens Count >= 1`, a Basic Output `Output` is created as follows: +- The `Amount` is set to `0`. +- The `Output` has one Feature of type _Native Token Feature_ which holds the `Token`. +- The `Output` has one Unlock Condition of type _Address Unlock Condition_ with the `Address` set to `Owner Address`. + # Rationale & Design ## Expiration Unlock Condition Index Bounds From fd7b50b0148c05cb33ab98c749a84e39d8dcf428 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 18:27:15 +0200 Subject: [PATCH 39/79] Add Migration header --- tips/TIP-0038/tip-0038.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d8e4e405b..479ef7f0f 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -34,8 +34,9 @@ replaces: TIP-18 - [Metadata Feature](#metadata-feature) - [Tag Feature](#tag-feature) - [Native Token Feature](#native-token-feature) -5. [Rationale & Design](#rationale--design) -6. [Copyright](#copyright) +5. [Migration](#migration) +6. [Rationale & Design](#rationale--design) +7. [Copyright](#copyright) # Summary From d364ad1da833c1a332d2a17884cf27299aa9adcd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 5 Oct 2023 11:41:28 +0200 Subject: [PATCH 40/79] Update Timelock & Expiration UC Slot Index --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 479ef7f0f..d72ddf80d 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -526,7 +526,7 @@ defined in the Timelock Unlock Condition. Slot Index - uint64 + uint32 Slot index starting from which the output can be consumed. @@ -624,7 +624,7 @@ is allowed to unlock the output containing the Expiration Unlock Condition Slot Index - uint64 + uint32 Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. From c3da616941e5720d7ba566a50996b658af4ea349 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 16 Oct 2023 11:18:50 +0100 Subject: [PATCH 41/79] Clarify Exp UC description --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d72ddf80d..4ed9766fc 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -578,7 +578,7 @@ is allowed to unlock the output containing the Expiration Unlock Condition Expiration Unlock Condition -
Defines a slot index until which only Address, defined in Address Unlock Condition, is allowed to unlock the output. After the slot index is reached/passed, only Return Address can unlock it.
+
Defines a slot index until which only the Address defined in the Address Unlock Condition is allowed to unlock the output. After the slot index is reached/passed, only the Return Address can unlock it.
From 17feb60546423d34df1788bd5747600cced8bd28 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 16 Oct 2023 13:15:19 +0100 Subject: [PATCH 42/79] Rename Native Token Migration header --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 4ed9766fc..b7c91e280 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -907,7 +907,7 @@ plugin. # Migration -## Native Tokens +## Native Token Migration The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capabaility is moved from a field to the _Native Token Feature_. Moreover, each output can only hold one Native Token instead of up to 64. This section specifies the migration. From 51983272527cb9b897709e125e259d41c7de5f97 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 11:43:38 +0100 Subject: [PATCH 43/79] Update SDRUC and Native Token section --- tips/TIP-0038/tip-0038.md | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index b7c91e280..1b233f826 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -41,16 +41,15 @@ replaces: TIP-18 # Summary This document defines the common building blocks used across multiple output types and transaction validation rules for -the IOTA protocol. These were originally introduced in [TIP-18](../TIP-0018/tip-0018.md), and the functionality defined +the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md), and the functionality defined in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 -- "Alias" is renamed to "Account". - The `Unix Time` field of the Timelock Unlock Condition is replaced by `Slot Index`. - The `Unix Time` field of the Expiration Unlock Condition is replaced by `Slot Index`. - The list of _Native Tokens_ in Basic, Alias, NFT and Foundry Outputs is replaced by a _Native Token Feature_ that - holds a single Native Token which can only be present in Basic and Foundry outputs. + holds a single Native Token which can only be present in Basic and Foundry Outputs. # Motivation @@ -120,25 +119,7 @@ maximum possible supply of layer 2 tokens. Solidity, the most popular smart cont of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on layer 1. -Outputs that can carry Native Tokens have a [_Native Token Feature_](#todo). - -### Additional syntactic output validation rules: - -- `Native Tokens` must be lexicographically sorted based on `Token ID`. -- Each Native Token must be unique in the set of `Native Tokens` based on its `Token ID`. No duplicates are - allowed. -- `Amount` of any Native Token must not be `0`. - -### Additional semantic transaction validation rules: - -- The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs - equals that of the created outputs. -- When the transaction is **imbalanced** and 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 determine whether the tokens are burned (removed from the ledger) or melted in the - foundry. +Outputs that can carry Native Tokens have a [_Native Token Feature_](#native-token-feature). Its transaction validation rules are defined in that section. ## Chain Constraint in UTXO @@ -405,7 +386,7 @@ Condition specified can only be consumed in a transaction that deposits `Ret - `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock - conditions, no features, and no native tokens. + conditions, no Mana and no features. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. #### Additional semantic transaction validation rule: @@ -414,7 +395,6 @@ Condition specified can only be consumed in a transaction that deposits `Ret transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: - are of type Basic Output, - have only an [Address Unlock Condition](#address-unlock-condition) defined, - - have no [Native Tokens](#native-tokens-in-outputs), - have no Mana, and - have no [Features](#features). - When several outputs with Storage Deposit Return Unlock Condition and the same `Return Address` are consumed, @@ -919,6 +899,7 @@ Let `Owner Address` be: For each Native Token `Token` in an output with `Native Tokens Count >= 1`, a Basic Output `Output` is created as follows: - The `Amount` is set to `0`. + - TODO: (Discuss) It would be possible to set this at least to `1` or even higher so as to not violate the `Amount != 0` assumption of outputs, by moving some tokens from the output that originally contained it to the newly created output. - The `Output` has one Feature of type _Native Token Feature_ which holds the `Token`. - The `Output` has one Unlock Condition of type _Address Unlock Condition_ with the `Address` set to `Owner Address`. From cd86c13b8e08dd4a81d738046f3b7027ba91d7eb Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 11:44:00 +0100 Subject: [PATCH 44/79] Format Markdown --- tips/TIP-0038/tip-0038.md | 44 +++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 1b233f826..94221da56 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -41,8 +41,8 @@ replaces: TIP-18 # Summary This document defines the common building blocks used across multiple output types and transaction validation rules for -the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md), and the functionality defined -in this document is an extension of the primitives defined in TIP-18. +the IOTA protocol. Many of these were originally introduced in [TIP-18](../TIP-0018/tip-0018.md), and the functionality +defined in this document is an extension of the primitives defined in TIP-18. ## Summary of changes compared to TIP-18 @@ -119,7 +119,8 @@ maximum possible supply of layer 2 tokens. Solidity, the most popular smart cont of an ERC-20 token as `MaxUint256`, therefore it should be possible to represent such a huge amount of assets on layer 1. -Outputs that can carry Native Tokens have a [_Native Token Feature_](#native-token-feature). Its transaction validation rules are defined in that section. +Outputs that can carry Native Tokens have a [_Native Token Feature_](#native-token-feature). Its transaction validation +rules are defined in that section. ## Chain Constraint in UTXO @@ -198,7 +199,9 @@ A user can identify by looking at the address whether it is a signature-backed a #### Unlocking The address is unlocked in a transaction if and only if: -- The _Unlock_ of the first output in the transaction that contains the address is a valid _Signature Unlock_ with respect to the address. + +- The _Unlock_ of the first output in the transaction that contains the address is a valid _Signature Unlock_ with + respect to the address. ### Account Address @@ -233,7 +236,9 @@ The address is unlocked in a transaction if and only if: #### Unlocking The address is unlocked in a transaction if and only if: -- The _Account Output_ from whose _Account ID_ the address is derived from, is **state transitioned** in the transaction. A governance transition does not unlock the address. + +- The _Account Output_ from whose _Account ID_ the address is derived from, is **state transitioned** in the + transaction. A governance transition does not unlock the address. ### NFT Address @@ -268,6 +273,7 @@ The address is unlocked in a transaction if and only if: #### Unlocking The address is unlocked in a transaction if and only if: + - The _NFT Output_ from whose _NFT ID_ the address is derived from, is consumed as an input in the transaction. ## Signatures @@ -679,7 +685,9 @@ transaction validation.
-_Restricted Addresses_ cannot be put into _Sender Features_ because they are resolved to the underlying address during unlocking Therefore, when using an Sender Feature with a Restricted Address, the underlying Address must be put into the feature. +_Restricted Addresses_ cannot be put into _Sender Features_ because they are resolved to the underlying address during +unlocking Therefore, when using an Sender Feature with a Restricted Address, the underlying Address must be put into the +feature. ### Issuer Feature @@ -695,8 +703,8 @@ unchanged. address is unlocked in the transaction. Every Address Type specifies under which conditions it is considered unlocked. The main use case is proving the authenticity of NFTs. Whenever an NFT is minted as an NFT output, the creator (issuer) -can fill the _Issuer Feature_ with their address that they have to unlock in the transaction. Issuers then can -publicly disclose their addresses to prove the authenticity of the NFT once it is in circulation. +can fill the _Issuer Feature_ with their address that they have to unlock in the transaction. Issuers then can publicly +disclose their addresses to prove the authenticity of the NFT once it is in circulation.
Issuer Feature @@ -750,7 +758,9 @@ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Is address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. -_Restricted Addresses_ cannot be put into _Issuer Features_ because they are resolved to the underlying address during unlocking. Therefore, when using an Issuer Feature with a Restricted Address, the underlying Address must be put into the feature. +_Restricted Addresses_ cannot be put into _Issuer Features_ because they are resolved to the underlying address during +unlocking. Therefore, when using an Issuer Feature with a Restricted Address, the underlying Address must be put into +the feature. ### Metadata Feature @@ -889,17 +899,25 @@ plugin. ## Native Token Migration -The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capabaility is moved from a field to the _Native Token Feature_. Moreover, each output can only hold one Native Token instead of up to 64. This section specifies the migration. +The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capabaility +is moved from a field to the _Native Token Feature_. Moreover, each output can only hold one Native Token instead of up +to 64. This section specifies the migration. Let `Owner Address` be: + - the _Alias Address_ if the Output is an _Alias Output_. - the _NFT Address_ if the Output is an _NFT Output_. - the _Address_ in the _Address Unlock Condition_ in the output if the Output is a _Basic Output_. -- the _Alias Address_ in the _Immutable Alias Address Unlock Condition_ in the output if the Output is a _Foundry Output_. +- the _Alias Address_ in the _Immutable Alias Address Unlock Condition_ in the output if the Output is a _Foundry + Output_. + +For each Native Token `Token` in an output with `Native Tokens Count >= 1`, a Basic Output `Output` is created as +follows: -For each Native Token `Token` in an output with `Native Tokens Count >= 1`, a Basic Output `Output` is created as follows: - The `Amount` is set to `0`. - - TODO: (Discuss) It would be possible to set this at least to `1` or even higher so as to not violate the `Amount != 0` assumption of outputs, by moving some tokens from the output that originally contained it to the newly created output. + - TODO: (Discuss) It would be possible to set this at least to `1` or even higher so as to not violate the + `Amount != 0` assumption of outputs, by moving some tokens from the output that originally contained it to the newly + created output. - The `Output` has one Feature of type _Native Token Feature_ which holds the `Token`. - The `Output` has one Unlock Condition of type _Address Unlock Condition_ with the `Address` set to `Owner Address`. From 23aa4d883671dcbe043b74164743a58b0921b2c0 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 11:44:37 +0100 Subject: [PATCH 45/79] Remove manually added Table of Contents GitHub and the Wiki both auto-generate a ToC, so it's unnecessary to maintain it. --- tips/TIP-0038/tip-0038.md | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 94221da56..a71f03b5d 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -13,31 +13,6 @@ requires: TIP-21, TIP-22, TIP-41, TIP-42, TIP-43, TIP-44, TIP-45 and TIP-47 replaces: TIP-18 --- -# Table of Contents - -1. [Summary](#summary) -2. [Motivation](#motivation) -3. [Building Blocks](#building-blocks) -4. [Output Design Primitives](#output-design-primitives) - - [Native Tokens](#native-tokens) - - [Chain constraint](#chain-constraint-in-utxo) - - [Addresses](#addresses) - - [Signatures](#signatures) - - [Unlock Conditions](#unlock-conditions) - - [Address Unlock Condition](#address-unlock-condition) - - [Storage Deposit Return Unlock Condition](#storage-deposit-return-unlock-condition) - - [Timelock Unlock Condition](#timelock-unlock-condition) - - [Expiration Unlock Condition](#expiration-unlock-condition) - - [Features](#features) - - [Sender Feature](#sender-feature) - - [Issuer Feature](#issuer-feature) - - [Metadata Feature](#metadata-feature) - - [Tag Feature](#tag-feature) - - [Native Token Feature](#native-token-feature) -5. [Migration](#migration) -6. [Rationale & Design](#rationale--design) -7. [Copyright](#copyright) - # Summary This document defines the common building blocks used across multiple output types and transaction validation rules for From 1626afe024a9465279509bbae8a8899561d5350f Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 11:51:51 +0100 Subject: [PATCH 46/79] Fix "commitable" typo --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index a71f03b5d..d7fde42a3 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -910,7 +910,7 @@ and `Return Address` would be able to unlock the output, potentially allowing a **Example with optimal Commitment Input choice** -Suppose that `Minimum Committable Age` is 3 and `Maximum Commitable Age` is 10, and there is an Expiration Unlock +Suppose that `Minimum Committable Age` is 3 and `Maximum Committable Age` is 10, and there is an Expiration Unlock Condition with `Slot Index` set to 20. Note the restrictions on the Commitment Input within a transaction relative to a [Block's `Issuing Time`](../TIP-0046/tip-0046.md#syntactic-validation). If the current slot is 19, the oldest Commitment the Address owner can pick as the Commitment Input is the one with index = 19-10 = 9 and can therefore unlock the From 861e8d0502dbc6a6ff8c89811aa920ef79f35a3b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 25 Oct 2023 13:30:19 +0100 Subject: [PATCH 47/79] Add native token burn flag rule --- tips/TIP-0038/tip-0038.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d7fde42a3..d399faf8e 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -860,6 +860,9 @@ plugin. #### Additional semantic transaction validation rules: +Whenever any Native Token Feature is present on the input or output side of a transaction, the following rule applies to +the transaction: + - The transaction is balanced in terms of native tokens, that is, the sum of native token balances in consumed outputs equals that of the created outputs. - When the transaction is **imbalanced** and there is a surplus of native tokens on the: @@ -868,7 +871,8 @@ plugin. - **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 in the foundry. - - TODO: Transaction Burn Flag. + - Burning Native Tokens is only allowed if the _Can Burn Native Tokens_ flag in the _Transaction Capabilities_ is + set, while melting is unaffected by the flag. # Migration From e0014b8c87df5f4c25f4fe42686d48a56942d9dd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 25 Oct 2023 13:31:44 +0100 Subject: [PATCH 48/79] Let protocol params point to TIP-49 --- tips/TIP-0038/tip-0038.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d399faf8e..ddb385537 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -51,10 +51,9 @@ about their tokens on-ledger, accessible to anyone. Data types and subschemas used throughout this TIP are defined in [TIP-21](../TIP-0021/tip-0021.md). -## Global Protocol Parameters +## Protocol Parameters -Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA)](../TIP-0022/tip-0022.md) and -[TIP-32 (Shimmer)](../TIP-0032/tip-0032.md). +Protocol parameters used throughout this TIP are defined in [TIP-49](../TIP-0049/tip-0049.md). ## Transaction Payload From 3e411072d8d471b5aead8aeb77f60aee5b33a429 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 25 Oct 2023 13:46:57 +0100 Subject: [PATCH 49/79] Flip native token flag logic --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ddb385537..48fc062e4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -870,8 +870,8 @@ the transaction: - **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 in the foundry. - - Burning Native Tokens is only allowed if the _Can Burn Native Tokens_ flag in the _Transaction Capabilities_ is - set, while melting is unaffected by the flag. + - The transaction is invalid if Native Tokens are burned and the _Can Burn Native Tokens_ flag in the _Transaction + Capabilities_ is **unset**. Melting is unaffected by the flag. # Migration From 6834521d87c5e08645e8a4ddb6fca66380199346 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:42:00 +0100 Subject: [PATCH 50/79] Add `Anchor Address` --- tips/TIP-0038/tip-0038.md | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 48fc062e4..71c631d46 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -130,6 +130,7 @@ The following section shows the basic supported Address Types and their serializ | Ed25519 | 0 | iota1**q**... | | Account | 8 | iota1**p**... | | NFT | 16 | iota1**z**... | +| Anchor | 24 | iota1**r**... | The Address Type byte of a raw address has an effect on the starting character of the bech32 encoded address, which is the recommended address format for user facing applications. @@ -211,8 +212,7 @@ The address is unlocked in a transaction if and only if: The address is unlocked in a transaction if and only if: -- The _Account Output_ from whose _Account ID_ the address is derived from, is **state transitioned** in the - transaction. A governance transition does not unlock the address. +- The _Account Output_ from whose _Account ID_ the address is derived from, is consumed as an input in the transaction. ### NFT Address @@ -250,6 +250,43 @@ The address is unlocked in a transaction if and only if: - The _NFT Output_ from whose _NFT ID_ the address is derived from, is consumed as an input in the transaction. +### Anchor Address + +
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor.
+
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 24 to denote an Anchor Address.
Anchor IDByteArray[32]The raw bytes of the Anchor ID which is the BLAKE2b-256 hash of the Output ID that created it.
+ +#### Unlocking + +The address is unlocked in a transaction if and only if: + +- The _Anchor Output_ from whose _Anchor ID_ the address is derived from, is **state transitioned** in the + transaction. A governance transition does not unlock the address. + ## Signatures ### Ed25519 Signature From f50de697a4f628687fb18a9a888133a8d9892025 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:48:17 +0100 Subject: [PATCH 51/79] Update `Address Unlock Condition` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 71c631d46..545c7f5e8 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -381,6 +381,10 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t NFT Address
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor. Defined in TIP-38 (Anchor Address).
+
Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From 58e9f3a0f0fb1d0e897b8103e72e52ab5770f6fd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:48:57 +0100 Subject: [PATCH 52/79] Update `Storage Deposit Return Unlock Condition` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 545c7f5e8..868542f12 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -458,6 +458,10 @@ Condition specified can only be consumed in a transaction that deposits `Ret NFT Address
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor. Defined in TIP-38 (Anchor Address).
+
Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From f1c697c7df850632fd1198b101cbef5be2501d2c Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:49:23 +0100 Subject: [PATCH 53/79] Update `Expiration Unlock Condition` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 868542f12..1d39407f6 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -617,6 +617,10 @@ is allowed to unlock the output containing the Expiration Unlock ConditionNFT Address
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor. Defined in TIP-38 (Anchor Address).
+
Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From d4700a3934975a1f1bf6740963ff9fee23a00de4 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:50:41 +0100 Subject: [PATCH 54/79] Update `Sender Feature` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 1d39407f6..66067301a 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -696,6 +696,10 @@ transaction validation. NFT Address
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor. Defined in TIP-38 (Anchor Address).
+
Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From 751739732e3368f2746cf7b7718968d5d0f87d7b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 2 Nov 2023 16:50:53 +0100 Subject: [PATCH 55/79] Update `Issuer Feature` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 66067301a..ab778bb8a 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -769,6 +769,10 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ NFT Address
An Address derived from an NFT ID which can be unlocked by unlocking the corresponding NFT. Defined in TIP-38 (NFT Address).
+
+ Anchor Address +
An Address derived from an Anchor ID which can be unlocked by unlocking the corresponding Anchor. Defined in TIP-38 (Anchor Address).
+
Multi Address
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
From e1f9228e1601cfa6be2d7a9f2043e7f4b9560b48 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 3 Nov 2023 11:02:32 +0100 Subject: [PATCH 56/79] Format Markdown --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ab778bb8a..3e2657bd9 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -284,8 +284,8 @@ The address is unlocked in a transaction if and only if: The address is unlocked in a transaction if and only if: -- The _Anchor Output_ from whose _Anchor ID_ the address is derived from, is **state transitioned** in the - transaction. A governance transition does not unlock the address. +- The _Anchor Output_ from whose _Anchor ID_ the address is derived from, is **state transitioned** in the transaction. + A governance transition does not unlock the address. ## Signatures From 1dfb03646fb521eb6925a188b80915ff05d49ffc Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 7 Nov 2023 15:49:05 +0100 Subject: [PATCH 57/79] Add backdating blocks explanation & figures --- tips/TIP-0038/assets/backdating-blocks.png | Bin 0 -> 738182 bytes .../{ => assets}/chain-constraint.png | Bin .../TIP-0038/assets/expiration-uc-example.png | Bin 0 -> 765425 bytes tips/TIP-0038/tip-0038.md | 45 ++++++++++++++++-- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tips/TIP-0038/assets/backdating-blocks.png rename tips/TIP-0038/{ => assets}/chain-constraint.png (100%) create mode 100644 tips/TIP-0038/assets/expiration-uc-example.png diff --git a/tips/TIP-0038/assets/backdating-blocks.png b/tips/TIP-0038/assets/backdating-blocks.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3b1c32c112092af187015a4ec6b27dd29cbdc9 GIT binary patch literal 738182 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

qpKzS|MHUxjlMi$2?<1jM*Aohb^FVx^6l1^b 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

ab}PL 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 literal 0 HcmV?d00001 diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 3e2657bd9..e2c585d99 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -105,7 +105,7 @@ the state forward. The **state can be updated according to the transition rules its current state**. As a consequence, each such output has a unique successor, and together they form a path or _chain_ in the graph induced by the UTXO spends. Each chain is identified by its globally unique identifier. -![](chain-constraint.png) +![](./assets/chain-constraint.png) Account outputs, foundry outputs, and NFT outputs all use this chain constraint concept and define their own unique identifiers. @@ -960,7 +960,7 @@ follows: ## Expiration Unlock Condition Index Bounds -In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and +In theory, the conditions for a successful unlock on the _Expiration Unlock Condition_ are ideal when the `Address` and `Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest (`Min Committable Age` old) one, respectively. In practice, however, it is likely that a node will provide a commitment within the range of maximum and minimum committable age. If both pick the same commitment this causes a period of time @@ -968,7 +968,12 @@ within the range of maximum and minimum committable age. If both pick the same c However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` and `Return Address` would be able to unlock the output, potentially allowing a double spend. -**Example with optimal Commitment Input choice** +![](./assets/expiration-uc-example.png) + +_In this figure, Block A and B are issued in the slot corresponding to the current Wall Clock Time respectively (which +is not globally the same in this example). It shows how the choice of the commitment affects the unlocking outcome._ + +**Example with optimal Commitment Input choices** Suppose that `Minimum Committable Age` is 3 and `Maximum Committable Age` is 10, and there is an Expiration Unlock Condition with `Slot Index` set to 20. Note the restrictions on the Commitment Input within a transaction relative to a @@ -983,6 +988,40 @@ If however, the current slot is 18, and both owners would use the same Commitmen of 8 and 15 of possible commitments, then neither one of them can unlock the output, as neither 20 > 13+10 nor 20 <= 13+3 is true. +**Backdating blocks** + +One variable that was not mentioned yet is how a client can set a block's `Issuing Time`, relative to which the chosen +commitment is validated, which allows for _backdating_ blocks. Backdating blocks by a singificant amount is only +possible when there is liveness. The most that someone can backdate a block is to +`Accepted Tangle Time - Liveness Threshold Upper Bound`, so if there is liveness (`ATT ~= Wall Clock Time`), then the +most someone could backdate their block is by `Liveness Threshold Upper Bound`. + +![](./assets/backdating-blocks.png) + +_This figure shows an example of backdating a block by one slot (which is less than `Liveness Threshold Upper Bound`). +The global Wall Clock Time is the same for both blocks and yet both transactions in their respective blocks could unlock +the output._ + +The only time that backdating has any consequence is if there is liveness. Assume some application (for example, a layer +2 chain) relies on an expired output being consumed. The application should only consider the expired output as consumed +and act on that if the output is at least accepted, but ideally until it is committed, confirmed or finalized. The +higher the level of finality the application waits for, the more difficult it is for the `Address` owner (the receiver +of the output with an _Expiration Unlock Condition_) to backdate a block and revert the consumption of the expired +output. For example, if the application waits for commitment of the expired output being consumed, then it is impossible +for the receiver address to subsequently consume it, unless it forces a chain switch, because the receiver address can +only consume the output in an earlier slot than the return address can consume it, and all such earlier slots are +already committed. If the application only waits for acceptance of the expired output consumption, a malicious owner of +the receiver address could technically issue a backdated block shortly after `ATT - Liveness Threshold Upper Bound`, but +this block would be less likely to be selected as a tip, and because the majority of online validators already accepted +the expired output consumption, they should not accept the backdated receiver consumption because it is a conflict. The +only way the receiver address could revert the other conflict is by having support of a majority of other validators to +revert it. In conclusion, it is very difficult to backdate even with just acceptance, and becomes more difficult when +waiting for higher levels of finality. This attack relates to the fundamental fact that the best approximation of time +is the block's `Issuing Time` timestamp, which is is meant to be very difficult to falsify. + +**Note**: An IOTA Smart Contract Chain is not susceptible to such a backdating attack anyway because it is the receiver +address of the expiration locked output and it is _not_ waiting for the output to expire in order to consume it. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From e7ed6a29efdd0325263b30ad49496dfa48d206c1 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 10 Nov 2023 13:57:46 +0100 Subject: [PATCH 58/79] Update Metadata Feature --- tips/TIP-0038/tip-0038.md | 53 ++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index e2c585d99..ee1b1f042 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -800,13 +800,9 @@ protocol treats this metadata as pure binary data, it has no effect on the valid increases the required storage deposit. ISC is a great example of a higher-layer protocol that makes use of Metadata Feature: smart contract request parameters are encoded in the metadata field of outputs. -#### Additional syntactic transaction validation rules: - -- An output with Metadata Feature is valid, if and only if 0 < `length(Data)` ≤ `Max Metadata Length`. -

Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output.
+
Defines a map of key-value pairs that is stored in the output.
@@ -826,12 +822,51 @@ Feature: smart contract request parameters are encoded in the metadata field - - - + + + + + + +
Set to value 2 to denote a Metadata Feature.
Data(uint16)ByteArrayBinary data. A leading uint16 denotes its length.Entries Countuint8The number of entries in the map.
Entries anyOf +
+ Metadata Entry +
A map entry consisting of a string key and an arbitrary byte value.
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Key(uint8)ByteArrayA string which may only consist of ASCII characters. A leading uint8 denotes its length.
Value(uint16)ByteArrayAn array of arbitrary binary data. A leading uint16 denotes its length.
+
+
+#### Additional syntactic transaction validation rules: + +- Each `Key` in the `Entries` must consist only of bytes that are valid ASCII characters, that is, each byte may not + exceed `127`. +- `Entries Count` must be at least `1`. +- The serialized size of the feature may not exceed `8192` bytes. + ### Tag Feature A Tag Feature makes it possible to tag outputs with an index, so they can be retrieved through an indexer API not @@ -901,7 +936,7 @@ plugin. Token ID ByteArray[38] - Identifier of the native token. Its derivation is defined in
TIP-44. + Identifier of the native token. Its derivation is defined in TIP-44 (Foundry Output). Amount From d2966a92982d18202e53042eb6da1dead4dafefd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 10 Nov 2023 17:29:34 +0100 Subject: [PATCH 59/79] Be more precise for max byte size --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ee1b1f042..59f055e57 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -865,7 +865,7 @@ Feature
: smart contract request parameters are encoded in the metadata field - Each `Key` in the `Entries` must consist only of bytes that are valid ASCII characters, that is, each byte may not exceed `127`. - `Entries Count` must be at least `1`. -- The serialized size of the feature may not exceed `8192` bytes. +- The `Entries Count` plus the serialized size of `Entries` must not exceed `8192` bytes. ### Tag Feature From 664e86a8e5fc9cdc410063dfaa62d565a2d1221a Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 20 Nov 2023 12:39:43 +0100 Subject: [PATCH 60/79] Clarify max byte size & uniquness constraint --- tips/TIP-0038/tip-0038.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 59f055e57..293eb1ed0 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -864,8 +864,10 @@ Feature: smart contract request parameters are encoded in the metadata field - Each `Key` in the `Entries` must consist only of bytes that are valid ASCII characters, that is, each byte may not exceed `127`. +- Each `Key` in the `Entries` must be unique. - `Entries Count` must be at least `1`. -- The `Entries Count` plus the serialized size of `Entries` must not exceed `8192` bytes. +- The serialized size of the map, consisting of the serialized size of `Entries Count` plus the serialized size of all + `Entries`, must not exceed `8192` bytes. ### Tag Feature From 8a9e65f27d20dd29d8a5b4ec3f7171077b630fe5 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 20 Nov 2023 12:40:59 +0100 Subject: [PATCH 61/79] Update Tag & Native Token feat type prefix --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 293eb1ed0..76782a533 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -903,7 +903,7 @@ plugin. Feature Type uint8 - Set to value 3 to denote a Tag Feature. + Set to value 4 to denote a Tag Feature. Tag @@ -933,7 +933,7 @@ plugin. Feature Type uint8 - Set to value 4 to denote a Native Token Feature. + Set to value 5 to denote a Native Token Feature. Token ID From 02f5d40db2e6fe9f9a8296f43f67431eaa257871 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 20 Nov 2023 13:10:50 +0100 Subject: [PATCH 62/79] Capitalize transaction rule headers --- tips/TIP-0038/tip-0038.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 76782a533..32f375443 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -403,14 +403,14 @@ This unlock condition is employed to achieve conditional sending. An output that Condition specified can only be consumed in a transaction that deposits `Return Amount` IOTA coins into `Return Address`. -#### Additional syntactic transaction validation rule: +#### Additional Transaction Syntactic Validation Rules - `Minimum Storage Deposit` is the storage deposit in the base currency required for a [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock conditions, no Mana and no features. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. -#### Additional semantic transaction validation rule: +#### Additional Transaction Semantic Validation Rules - An output that has Storage Deposit Return Unlock Condition specified must only be consumed and unlocked in a transaction that deposits `Return Amount` IOTA coins to `Return Address` via one or more outputs that: @@ -496,11 +496,11 @@ An output that contains a Timelock Unlock Condition can not be unlocked b The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index defined in the Timelock Unlock Condition. -#### Additional syntactic transaction validation rules: +#### Additional Transaction Syntactic Validation Rules - `Slot Index` field of a Timelock Unlock Condition must be > `0`. -#### Additional semantic transaction validation rules: +#### Additional Transaction Semantic Validation Rules - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the @@ -550,11 +550,11 @@ timelock and an expiration unlock condition. For the rationale behind the index choices for the slot index conditions in this Unlock Condition, refer to [Expiration Unlock Condition Index Bounds](#expiration-unlock-condition-index-bounds). -#### Additional syntactic transaction validation rules: +#### Additional Transaction Syntactic Validation Rules - `Slot Index` field of an Expiration Unlock Condition must be > `0`. -#### Additional semantic transaction validation rules: +#### Additional Transaction Semantic Validation Rules - A _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age`, where `Commitment Index` is the @@ -655,7 +655,7 @@ specify the validated sender of an output. Outputs that support the Sender Feature may specify a `Sender` address which is validated by the protocol during transaction validation. -#### Additional semantic transaction validation rule: +#### Additional Transaction Semantic Validation Rules - The Sender Feature, and hence the output and transaction that contain it, is valid, if and only if the `Sender` address is unlocked in the transaction. Every Address Type specifies under which conditions it is considered unlocked. @@ -724,7 +724,7 @@ minted) it is checked during transaction validation that an output corresponding every future transition of the state machine, it is instead checked that the issuer feature is still present and unchanged. -#### Additional semantic transaction validation rule: +#### Additional Transaction Semantic Validation Rules - The _Issuer Feature_, and hence the output and transaction that contain it, is valid, if and only if the `Issuer` address is unlocked in the transaction. Every Address Type specifies under which conditions it is considered unlocked. @@ -860,7 +860,7 @@ Feature: smart contract request parameters are encoded in the metadata field -#### Additional syntactic transaction validation rules: +#### Additional Transaction Syntactic Validation Rules - Each `Key` in the `Entries` must consist only of bytes that are valid ASCII characters, that is, each byte may not exceed `127`. @@ -880,7 +880,7 @@ An example use case is voting on the Tangle via the [participation](https://github.com/iota-community/treasury/blob/main/specifications/hornet-participation-plugin.md) plugin. -#### Additional syntactic transaction validation rules: +#### Additional Transaction Syntactic Validation Rules - An output with Tag Feature is valid, if and only if 0 < `length(Tag)` ≤ `Max Tag Length`. @@ -947,11 +947,11 @@ plugin. -#### Additional syntactic output validation rules: +#### Additional Transaction Syntactic Validation Rules - `Amount` must not be `0`. -#### Additional semantic transaction validation rules: +#### Additional Transaction Semantic Validation Rules Whenever any Native Token Feature is present on the input or output side of a transaction, the following rule applies to the transaction: From ec91f9e1afa506e2da25e14be4b0c99215eeecd1 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 21 Nov 2023 13:07:53 +0100 Subject: [PATCH 63/79] Add not-unlockable expiration UC condition --- tips/TIP-0038/tip-0038.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 32f375443..f458bf4c3 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -575,11 +575,12 @@ For the rationale behind the index choices for the slot index conditions in this The following table summarizes the outcome of the syntactic and semantic validation rules with respect to which address is allowed to unlock the output containing the Expiration Unlock Condition: -| Slot Index Condition | Outcome | -| ------------------------------------------ | --------------------------------------------- | -| `Slot Index` = `0` | Output and containing transaction is invalid. | -| `Slot Index` > `Past Bounded Slot Index` | Unlockable by `Address`. | -| `Slot Index` ≤ `Future Bounded Slot Index` | Unlockable by `Return Address`. | +| Slot Index Condition | Outcome | +| -------------------------------------------------------------------------------- | --------------------------------------------- | +| `Slot Index = 0` | Output and containing transaction is invalid. | +| `Slot Index > Past Bounded Slot Index` | Unlockable by `Address`. | +| `Slot Index ≤ Future Bounded Slot Index` | Unlockable by `Return Address`. | +| `Slot Index ≤ Past Bounded Slot Index && Slot Index > Future Bounded Slot Index` | Not unlockable. |
Expiration Unlock Condition From 9e696a0ba3d9914c67d3abae932d7ef62859641e Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 21 Nov 2023 15:23:01 +0100 Subject: [PATCH 64/79] Remove explicit ISC note --- tips/TIP-0038/tip-0038.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index f458bf4c3..26329ab15 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -1057,9 +1057,6 @@ revert it. In conclusion, it is very difficult to backdate even with just accept waiting for higher levels of finality. This attack relates to the fundamental fact that the best approximation of time is the block's `Issuing Time` timestamp, which is is meant to be very difficult to falsify. -**Note**: An IOTA Smart Contract Chain is not susceptible to such a backdating attack anyway because it is the receiver -address of the expiration locked output and it is _not_ waiting for the output to expire in order to consume it. - # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 88e0e3d48121f537a15211afa845c664bfe9497e Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 23 Nov 2023 16:44:03 +0100 Subject: [PATCH 65/79] Remove outdated note on restricted addrs --- tips/TIP-0038/tip-0038.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 26329ab15..7a9797149 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -713,10 +713,6 @@ transaction validation. -_Restricted Addresses_ cannot be put into _Sender Features_ because they are resolved to the underlying address during -unlocking Therefore, when using an Sender Feature with a Restricted Address, the underlying Address must be put into the -feature. - ### Issuer Feature The issuer feature is a special case of the sender feature that is only supported by outputs that implement a UTXO state From e9bb13cf375249c400b4317f1fe6782e5efd0ea8 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 23 Nov 2023 16:47:59 +0100 Subject: [PATCH 66/79] Remove other outdated note on restricted addrs --- tips/TIP-0038/tip-0038.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 7a9797149..951252e9b 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -786,10 +786,6 @@ Whenever a chain account mints an NFT on layer 1 on behalf of some user, the `Is address, since the user does not sign the layer 1 transaction. As a consequence, artists would have to mint NFTs themselves on layer 1 and then deposit it to chains if they want to place their own address in the `Issuer` field. -_Restricted Addresses_ cannot be put into _Issuer Features_ because they are resolved to the underlying address during -unlocking. Therefore, when using an Issuer Feature with a Restricted Address, the underlying Address must be put into -the feature. - ### Metadata Feature Outputs may carry additional data with them that is interpreted by higher-layer applications built on the Tangle. The From e8765c7aed36d63e5407783d2b0210e3b70305d6 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 27 Nov 2023 14:09:27 +0100 Subject: [PATCH 67/79] Apply suggestions from code review Co-authored-by: Thibault Martinez --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 951252e9b..d25e1f1af 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -964,7 +964,7 @@ the transaction: ## Native Token Migration -The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capabaility +The capability to hold Native Tokens is removed from Alias and NFT Outputs. In Basic and Foundry Outputs the capability is moved from a field to the _Native Token Feature_. Moreover, each output can only hold one Native Token instead of up to 64. This section specifies the migration. @@ -1021,7 +1021,7 @@ of 8 and 15 of possible commitments, then neither one of them can unlock the out **Backdating blocks** One variable that was not mentioned yet is how a client can set a block's `Issuing Time`, relative to which the chosen -commitment is validated, which allows for _backdating_ blocks. Backdating blocks by a singificant amount is only +commitment is validated, which allows for _backdating_ blocks. Backdating blocks by a significant amount is only possible when there is liveness. The most that someone can backdate a block is to `Accepted Tangle Time - Liveness Threshold Upper Bound`, so if there is liveness (`ATT ~= Wall Clock Time`), then the most someone could backdate their block is by `Liveness Threshold Upper Bound`. From d2af3205bf97925e38eec9f75e0f2eb18401b406 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Dec 2023 11:51:58 +0100 Subject: [PATCH 68/79] Only allow printable chars in metadata keys --- tips/TIP-0038/tip-0038.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index d25e1f1af..a69f44125 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -840,7 +840,7 @@ Feature: smart contract request parameters are encoded in the metadata field Key (uint8)ByteArray - A string which may only consist of ASCII characters. A leading uint8 denotes its length. + A string which may only consist of printable ASCII characters. A leading uint8 denotes its length. Value @@ -855,8 +855,8 @@ Feature: smart contract request parameters are encoded in the metadata field #### Additional Transaction Syntactic Validation Rules -- Each `Key` in the `Entries` must consist only of bytes that are valid ASCII characters, that is, each byte may not - exceed `127`. +- Each `Key` in the `Entries` must consist only of bytes that are printable ASCII characters, that is, for each + character `char` (interpreted as a byte) in the `Key` it must hold: `33 <= char <= 126`. - Each `Key` in the `Entries` must be unique. - `Entries Count` must be at least `1`. - The serialized size of the map, consisting of the serialized size of `Entries Count` plus the serialized size of all From c0c274abd91ea9588a4db0489cce28c472affb08 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Dec 2023 13:23:53 +0100 Subject: [PATCH 69/79] Motivate key-value pairs in metadata --- tips/TIP-0038/tip-0038.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index a69f44125..295481a96 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -1049,6 +1049,23 @@ revert it. In conclusion, it is very difficult to backdate even with just accept waiting for higher levels of finality. This attack relates to the fundamental fact that the best approximation of time is the block's `Issuing Time` timestamp, which is is meant to be very difficult to falsify. +## Metadata Feature Map + +In Stardust, the Metadata Feature was defined as an arbitrary byte array to allow applications to be built on top of the +data stored in the ledger. However, only one such feature was allowed in a given output making it practically impossible +for two independent applications to both store data in the same output. Moreover, it was hard to identify what +application has written data into the metadata, making it tough for applications, such as wallets, that read these +values, to interpret the data correctly. To address this, the feature was changed to a map of key-value pairs, where the +keys are human-readable identifiers and the keys are arbitrary byte values. This additional level of abstraction allows +multiple applications to write data into the same output, as long as they use different keys. The keys are limited to +printable ASCII characters (excluding space) such that it's easy for a human to read which keys are in a given feature +(for example in explorers or when looking at the JSON response from an API). In order for applications to avoid naming +collisions in the key, another registry TIP could be considered where applications can reserve their keys. Although not +enforced by the protocol, this would help avoid collisions and, as a side-effect, means that the data writers can define +their encoding, compression or other relevant information for the correct interpretation of the data. That allows +wallets and other data readers to detect content based on the keys, which is much more resilient than attempting to +inspect the raw bytes for magic bytes, encoding or compression markers. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From f74701264155d53dc387bc00fb9bcde664096bdd Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 8 Jan 2024 12:33:16 +0100 Subject: [PATCH 70/79] Require lexicographic ordering for metadata feat --- tips/TIP-0038/tip-0038.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 295481a96..ecc199ff0 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -858,6 +858,7 @@ Feature: smart contract request parameters are encoded in the metadata field - Each `Key` in the `Entries` must consist only of bytes that are printable ASCII characters, that is, for each character `char` (interpreted as a byte) in the `Key` it must hold: `33 <= char <= 126`. - Each `Key` in the `Entries` must be unique. +- The `Entries` must be lexicographically ordered based on the `Key`. - `Entries Count` must be at least `1`. - The serialized size of the map, consisting of the serialized size of `Entries Count` plus the serialized size of all `Entries`, must not exceed `8192` bytes. From c33788a6218e23299ee31faee8f2d1c293835c0f Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 22 Jan 2024 15:42:23 +0100 Subject: [PATCH 71/79] Clarify map ordering only applies to binary --- tips/TIP-0038/tip-0038.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index ecc199ff0..9bb8527b2 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -858,7 +858,8 @@ Feature: smart contract request parameters are encoded in the metadata field - Each `Key` in the `Entries` must consist only of bytes that are printable ASCII characters, that is, for each character `char` (interpreted as a byte) in the `Key` it must hold: `33 <= char <= 126`. - Each `Key` in the `Entries` must be unique. -- The `Entries` must be lexicographically ordered based on the `Key`. +- The `Entries` must be lexicographically ordered based on `Key`. + - Note: This requirement only applies to the binary serialization. See also the note on [map ordering](#map-ordering). - `Entries Count` must be at least `1`. - The serialized size of the map, consisting of the serialized size of `Entries Count` plus the serialized size of all `Entries`, must not exceed `8192` bytes. @@ -1055,7 +1056,7 @@ is the block's `Issuing Time` timestamp, which is is meant to be very difficult In Stardust, the Metadata Feature was defined as an arbitrary byte array to allow applications to be built on top of the data stored in the ledger. However, only one such feature was allowed in a given output making it practically impossible for two independent applications to both store data in the same output. Moreover, it was hard to identify what -application has written data into the metadata, making it tough for applications, such as wallets, that read these +application has written data into the metadata, making it tough for other applications, such as wallets, that read these values, to interpret the data correctly. To address this, the feature was changed to a map of key-value pairs, where the keys are human-readable identifiers and the keys are arbitrary byte values. This additional level of abstraction allows multiple applications to write data into the same output, as long as they use different keys. The keys are limited to @@ -1067,6 +1068,15 @@ their encoding, compression or other relevant information for the correct interp wallets and other data readers to detect content based on the keys, which is much more resilient than attempting to inspect the raw bytes for magic bytes, encoding or compression markers. +### Map Ordering + +The map's `Entries` are required to be lexicographically ordered, in order to produce a deterministic binary +serialization, on which identifiers like the Transaction ID or the signing message of a transaction depend on. Map +implementations often don't retain an order like lists/arrays do, which requires this sorting. However, this requirement +only applies to the binary serialization, since it must be deterministic. Other data exchange formats, like JSON used in +REST APIs are not signed or hashed. JSON in particular also does not require or guarantee a map order. Hence, the +ordering is not strictly required for any other format than the binary one. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 0585f4b0d892bd5c2e1455382627157ff098e1f0 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 25 Jan 2024 09:58:22 +0100 Subject: [PATCH 72/79] Properly space `Pub Key Hash` --- tips/TIP-0038/tip-0038.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 9bb8527b2..584cddf51 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -165,7 +165,7 @@ A user can identify by looking at the address whether it is a signature-backed a Set to value 0 to denote an Ed25519 Address. - PubKeyHash + Pub Key Hash ByteArray[32] The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key. From d02b54babcf93ea267c28b10788555454bf95821 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 25 Jan 2024 15:40:02 +0100 Subject: [PATCH 73/79] Add Work Score for `Ed25519 Signature` --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 584cddf51..0b0b6a2f4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -326,6 +326,10 @@ The _Ed25519 Signature_ is supported and it is serialized as follows: +#### Work Score + +The Work Score of an _Ed25519 Signature_ is `Work Score Parameters::Signature Ed25519`. + ## Unlock Conditions New output features that introduce unlocking conditions, that is, they define constraints on how the output can be From a794b5bdf5f6457f89067039f8367c92b2beb347 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 2 Feb 2024 12:19:20 +0100 Subject: [PATCH 74/79] Point links to GitHub TIPs --- tips/TIP-0038/tip-0038.md | 51 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 0b0b6a2f4..a62e58409 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -53,11 +53,13 @@ Data types and subschemas used throughout this TIP are defined in [TIP-21](../TI ## Protocol Parameters -Protocol parameters used throughout this TIP are defined in [TIP-49](../TIP-0049/tip-0049.md). +Protocol parameters used throughout this TIP are defined in +[TIP-49](https://github.com/iotaledger/tips/blob/tip49/tips/TIP-0049/tip-0049.md). ## Transaction Payload -[TIP-45](../TIP-0045/tip-0045.md) is the basis for output validation in this TIP. +[TIP-45](https://github.com/iotaledger/tips/blob/tip45/tips/TIP-0045/tip-0045.md) is the basis for output validation in +this TIP. # Output Design Primitives @@ -347,7 +349,8 @@ validation rules are detailed in [TIP-20](../TIP-0020/tip-0020.md). New additions are the Account Address and NFT Address types, which have to be unlocked with their corresponding unlocks, as defined in [Unlocking Chain Script Locked Outputs](#unlocking-chain-script-locked-outputs), -and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/tip-0043.md) TIPs. +and the [Account Output](https://github.com/iotaledger/tips/blob/tip42/tips/TIP-0042/tip-0042.md) and +[NFT Output](https://github.com/iotaledger/tips/blob/tip43/tips/TIP-0043/tip-0043.md) TIPs.
Address Unlock Condition @@ -391,11 +394,11 @@ and the [Account Output](../TIP-0042/tip-0042.md) and [NFT Output](../TIP-0043/t
Multi Address -
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
Restricted Address -
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -410,8 +413,8 @@ Condition specified can only be consumed in a transaction that deposits `Ret #### Additional Transaction Syntactic Validation Rules - `Minimum Storage Deposit` is the storage deposit in the base currency required for a - [Basic Output](../TIP-0041/tip-0041.md) that only has an Address Unlock Condition, no additional unlock - conditions, no Mana and no features. + [Basic Output](https://github.com/iotaledger/tips/blob/tip41/tips/TIP-0041/tip-0041.md) that only has an + Address Unlock Condition, no additional unlock conditions, no Mana and no features. - It must hold true, that `Minimum Storage Deposit` ≤ `Return Amount` ≤ `Amount`. #### Additional Transaction Semantic Validation Rules @@ -468,11 +471,11 @@ Condition specified can only be consumed in a transaction that deposits `Ret
Multi Address -
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
Restricted Address -
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -494,7 +497,8 @@ expiration. Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment carries an index. When using any feature related to time, a -[_Commitment Input_](../TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. +[_Commitment Input_](https://github.com/iotaledger/tips/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is needed +as a reference of time. An output that contains a Timelock Unlock Condition can not be unlocked before the specified lock has expired. The lock is expired when the index of the slot to which the transaction belongs is equal to or past the slot index @@ -628,11 +632,11 @@ is allowed to unlock the output containing the Expiration Unlock Condition
Multi Address -
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
Restricted Address -
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -707,11 +711,11 @@ transaction validation.

iL7=1MtXBpw#wL9DcmPj3Xy#>qab1DxJpOn^rlZ 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 z zuLxc|`Hs8j+#Kg;AI`)(buyM48l*Mcmhf2L*E**<-1MX2XC*Zt#+9{K?2i!#PrACp zy>kyS=v@s;?CP=^pPEBL9k3qfMG1&YF&Qb;v{8M&5^$@BPu8Xq`FAizOXeE7(%2%YlefdrD& zf0vsClN&P*kmFNY5P1phb|hR7NN+_)CXvvm<9iceKH+BY<>2an{3ZWFr`!Rrgvxl1 w9|kb~ejf@c1hRP3^5X9wJbWMjg8}$@xN`2YAX&F8h6w&`()(4HqiqxXUy#u4Z2$lO literal 0 HcmV?d00001 diff --git a/tips/TIP-0038/chain-constraint.png b/tips/TIP-0038/assets/chain-constraint.png similarity index 100% rename from tips/TIP-0038/chain-constraint.png rename to tips/TIP-0038/assets/chain-constraint.png diff --git a/tips/TIP-0038/assets/expiration-uc-example.png b/tips/TIP-0038/assets/expiration-uc-example.png new file mode 100644 index 0000000000000000000000000000000000000000..a739d66e57e82fee81d7ce8bfcf8eb809f1008db GIT binary patch literal 765425 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 z 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

Multi Address -
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
Restricted Address -
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -776,11 +780,11 @@ disclose their addresses to prove the authenticity of the NFT once it is in circ
Multi Address -
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
+
Defines a Multi Address that consists of addresses with weights and a threshold value. The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the threshold. Defined in TIP-52 (Multi Address).
Restricted Address -
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -937,7 +941,7 @@ plugin. Token ID ByteArray[38] - Identifier of the native token. Its derivation is defined in TIP-44 (Foundry Output). + Identifier of the native token. Its derivation is defined in TIP-44 (Foundry Output). Amount @@ -1013,12 +1017,13 @@ is not globally the same in this example). It shows how the choice of the commit Suppose that `Minimum Committable Age` is 3 and `Maximum Committable Age` is 10, and there is an Expiration Unlock Condition with `Slot Index` set to 20. Note the restrictions on the Commitment Input within a transaction relative to a -[Block's `Issuing Time`](../TIP-0046/tip-0046.md#syntactic-validation). If the current slot is 19, the oldest Commitment -the Address owner can pick as the Commitment Input is the one with index = 19-10 = 9 and can therefore unlock the -output, because 20 > 9+10. The newest Commitment the Return Address owner can pick is the one with index 19-3 = 16, and -because 20 <= 16+3 is not true, they cannot unlock. If the current slot is 20, the oldest Commitment the Address owner -can pick is the one with index = 20-10 = 10, but since 20 > 10+10 is not true, they cannot unlock. Now the newest -Commitment the Return Address owner can pick is 20-3 = 17, and because 20 <= 17+3 is true, they can unlock. +[Block's `Issuing Time`](https://github.com/iotaledger/tips/blob/tip46/tips/TIP-0046/tip-0046.md#syntactic-validation). +If the current slot is 19, the oldest Commitment the Address owner can pick as the Commitment Input is the one with +index = 19-10 = 9 and can therefore unlock the output, because 20 > 9+10. The newest Commitment the Return Address owner +can pick is the one with index 19-3 = 16, and because 20 <= 16+3 is not true, they cannot unlock. If the current slot is +20, the oldest Commitment the Address owner can pick is the one with index = 20-10 = 10, but since 20 > 10+10 is not +true, they cannot unlock. Now the newest Commitment the Return Address owner can pick is 20-3 = 17, and because 20 <= +17+3 is true, they can unlock. If however, the current slot is 18, and both owners would use the same Commitment Input with index 13, within the range of 8 and 15 of possible commitments, then neither one of them can unlock the output, as neither 20 > 13+10 nor 20 <= From 089fa07bc620813f35ff50c749b4c75f6f9493a2 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 2 Feb 2024 13:58:56 +0100 Subject: [PATCH 75/79] Clarify need for Commitment Input for time --- tips/TIP-0038/tip-0038.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index a62e58409..de3d38f46 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -496,7 +496,7 @@ expiration. ### Timelock Unlock Condition Slot indices in the Tangle are introduced via slot commitments and represent a notion of time. Each such commitment -carries an index. When using any feature related to time, a +carries an index. When consuming a Timelock Unlock Condition, a [_Commitment Input_](https://github.com/iotaledger/tips/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is needed as a reference of time. @@ -553,7 +553,9 @@ The expiration feature can be viewed as an opt-in receive feature, because the r funds after the output expires, while the return address specified by the sender regains control over them. This feature is a big help for on-chain smart contract requests. Those that have expiration set and are sent to dormant smart contract chains can be recovered by their senders, not to mention the possibility of time requests by specifying both a -timelock and an expiration unlock condition. +timelock and an expiration unlock condition. When consuming an Expiration Unlock Condition, a +[_Commitment Input_](https://github.com/iotaledger/tips/blob/tip45/tips/TIP-0045/tip-0045.md#commitment-input) is needed +as a reference of time. For the rationale behind the index choices for the slot index conditions in this Unlock Condition, refer to [Expiration Unlock Condition Index Bounds](#expiration-unlock-condition-index-bounds). From c002930d4248de167be001acc75c29a4b080657b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 1 Mar 2024 11:10:11 +0800 Subject: [PATCH 76/79] Define _Signer UID_ for _Ed25519 Signature_ --- tips/TIP-0038/tip-0038.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index de3d38f46..62c3f2a84 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -328,6 +328,10 @@ The _Ed25519 Signature_ is supported and it is serialized as follows: +#### Signer UID + +The Signer UID of an _Ed25519 Signature_ is the BLAKE2b-256 hash of `Public Key`. + #### Work Score The Work Score of an _Ed25519 Signature_ is `Work Score Parameters::Signature Ed25519`. From 235b9386857ad4c9a9a4a9fde1bb69fe8a0293c2 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 1 Mar 2024 15:08:09 +0800 Subject: [PATCH 77/79] Add Signer UID for _Ed25519 Address_ --- tips/TIP-0038/tip-0038.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 62c3f2a84..b6f606ef4 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -173,12 +173,16 @@ A user can identify by looking at the address whether it is a signature-backed a +#### Signer UID + +The Signer UID of an _Ed25519 Address_ is the `Pub Key Hash`. + #### Unlocking -The address is unlocked in a transaction if and only if: +The address `Address` in a given input at index `Input Index` is unlocked in a transaction if and only if: -- The _Unlock_ of the first output in the transaction that contains the address is a valid _Signature Unlock_ with - respect to the address. +- The `Unlock` in `Unlocks` at `Input Index` is a semantically valid _Unlock_ and is itself or points to a _Signature + Unlock_ whose _Signer UID_ matches the _Signer UID_ of the `Address`. ### Account Address From 7d7cbf0bb15711f6421cd5ec419bf6db17f95615 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 1 Mar 2024 16:31:00 +0800 Subject: [PATCH 78/79] Rephrase Unlocking conditions for addresses --- tips/TIP-0038/tip-0038.md | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index b6f606ef4..40dea5a09 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -179,10 +179,8 @@ The Signer UID of an _Ed25519 Address_ is the `Pub Key Hash`. #### Unlocking -The address `Address` in a given input at index `Input Index` is unlocked in a transaction if and only if: - -- The `Unlock` in `Unlocks` at `Input Index` is a semantically valid _Unlock_ and is itself or points to a _Signature - Unlock_ whose _Signer UID_ matches the _Signer UID_ of the `Address`. +The address `Address` in a given input at index `Input Index` is unlocked in a transaction if and only if the +corresponding Unlock at `Input Index` is a semantically valid _Reference Unlock_ or _Signature Unlock_. ### Account Address @@ -216,9 +214,8 @@ The address `Address` in a given input at index `Input Index` is unlocked in a t #### Unlocking -The address is unlocked in a transaction if and only if: - -- The _Account Output_ from whose _Account ID_ the address is derived from, is consumed as an input in the transaction. +The _Account Address_ in a given input at index `Input Index` is unlocked in a transaction if and only if the +corresponding Unlock at `Input Index` is a semantically valid _Account Unlock_. ### NFT Address @@ -252,9 +249,8 @@ The address is unlocked in a transaction if and only if: #### Unlocking -The address is unlocked in a transaction if and only if: - -- The _NFT Output_ from whose _NFT ID_ the address is derived from, is consumed as an input in the transaction. +The _NFT Address_ in a given input at index `Input Index` is unlocked in a transaction if and only if the corresponding +Unlock at `Input Index` is a semantically valid _NFT Unlock_. ### Anchor Address @@ -288,10 +284,9 @@ The address is unlocked in a transaction if and only if: #### Unlocking -The address is unlocked in a transaction if and only if: - -- The _Anchor Output_ from whose _Anchor ID_ the address is derived from, is **state transitioned** in the transaction. - A governance transition does not unlock the address. +The _Anchor Address_ in a given input at index `Input Index` is unlocked in a transaction if and only if the +corresponding Unlock at `Input Index` is a semantically valid Anchor Unlock and the corresponding _Anchor Output_ is +**state transitioned**. Hence, a governance transition does not unlock the address. ## Signatures From 84dad0eaff8867951b197e5aaad6388eb3141085 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 5 Mar 2024 08:31:56 +0800 Subject: [PATCH 79/79] Clarify need for Commitment Input on input side --- tips/TIP-0038/tip-0038.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 40dea5a09..1d7d82976 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -513,7 +513,7 @@ defined in the Timelock Unlock Condition. #### Additional Transaction Semantic Validation Rules -- A _Commitment Input_ must be present. +- If an input of a transaction contains a _Timelock Unlock Condition_ a _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the slot index of the commitment input. - An output that has a Timelock Unlock Condition specified must only be consumed and unlocked in a transaction if @@ -569,7 +569,7 @@ For the rationale behind the index choices for the slot index conditions in this #### Additional Transaction Semantic Validation Rules -- A _Commitment Input_ must be present. +- If an input of a transaction contains an _Expiration Unlock Condition_ a _Commitment Input_ must be present. - Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age`, where `Commitment Index` is the slot index of the commitment input. - Let `Past Bounded Slot Index` be given by `Commitment Index + Max Committable Age`, where `Commitment Index` is the