From a56c955ec2c3b0f27e6c79bcb1dd9868f2d85f87 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 5 May 2023 10:31:24 +0200 Subject: [PATCH 01/46] Add TIP-43 skeleton --- tips/TIP-0043/tip-0043.md | 885 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 885 insertions(+) create mode 100644 tips/TIP-0043/tip-0043.md diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md new file mode 100644 index 000000000..1a7cfb741 --- /dev/null +++ b/tips/TIP-0043/tip-0043.md @@ -0,0 +1,885 @@ +--- +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. [Building Blocks](#building-blocks) +4. [Unlock Conditions](#unlock-conditions) + - [Account Locking & Unlocking](#account-locking--unlocking) +5. [Outputs](#outputs) +6. [Copyright](#copyright) + +# Summary + +TODO: Adapt from TIP-18 summary. + +# Motivation + +TODO: Adapt from TIP-18 motivation. + +# 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. + +# Outputs + +In the following, we define four new output types. They are all designed with specific use cases in mind: +- **Basic Output**: transfer of funds with attached metadata and optional spending restrictions. Main use cases are + on-ledger ISC requests, native asset transfers and indexed data storage in the UTXO ledger. +- **Alias Output**: representing ISC chain accounts on L1 that can process requests and transfer funds. +- **Foundry Output**: supply control of user defined native tokens. A vehicle for cross-chain asset transfers and asset + wrapping. +- **NFT Output**: an output that represents a Non-fungible token with attached metadata and proof-of-origin. A NFT is + represented as an output so that the token and metadata are transferred together, for example as a smart contract + requests. NFTs are possible to implement with native tokens as well, but then ownership of the token does not mean + ownership of the foundry that holds its metadata. + +The validation of outputs is part of the transaction validation process. There are two levels of validation for +transactions: syntactic and semantic validation. The former validates the structure of the transaction (and outputs), +while the latter validates whether protocol rules are respected in the semantic context of the transaction. Outputs +hence are validated on both levels: +1. **Transaction Syntactic Validation**: validates the structure of each output created by the transaction. +2. **Transaction Semantic Validation**: + - **For consumed outputs**: validates whether the output can be unlocked in a transaction given the semantic + transaction context. + - **For created outputs**: validates whether the output can be created in a transaction given the semantic + transaction context. + +Each new output type may add its own validation rules which become part of the transaction validation rules if the +output is placed inside a transaction. Unlock Conditions and Features described previously also add +constraints to transaction validation when they are placed in outputs. + +## NFT Output + +Non-fungible tokens in the ledger are implemented with a special output type, the so-called NFTOutput. + +Each NFT output gets assigned a unique identifier `NFT ID` upon creation by the protocol. `NFT ID` is BLAKE2b-256 hash +of the Output ID that created the NFT. The address of the NFT is the concatenation of `NFT Address Type` || +`NFT ID`. + +The NFT may contain immutable metadata set upon creation, and a verified `Issuer`. The output type supports all +non-alias specific (state controller, governor) unlock conditions and optional features so that the output can be +sent as a request to smart contract chain accounts. + + +
+ NFT Output +
+ Describes an NFT output, a globally unique token with metadata attached. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
Output Typeuint8 + Set to value 6 to denote a NFT Output. +
Amountuint64The amount of IOTA coins held by the output.
Native Tokens Countuint8The number of native tokens held by the output.
Native Tokens optAnyOf +
+ Native Token + + + + + + + + + + + + + + + + +
NameTypeDescription
Token IDByteArray[38] + Identifier of the native token. +
Amountuint256 + Amount of native tokens of the given Token ID. +
+
+
NFT IDByteArray[32]Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID
Unlock Conditions Countuint8The number of unlock conditions following.
Unlock Conditions atMostOneOfEach +
+ 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.
+
+
+ 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.
+
+
+
+
+ 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 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.
+
+
Return Amountuint64 + Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address. +
+
+
+ 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 +
+ 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 or 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 Countuint8The number of features following.
Features atMostOneOfEach +
+ 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.
+
+
+
+
+ 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 +
+ 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 data. A leading uint8 denotes its length.
+
+
Immutable Features Countuint8The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach +
+ 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.
+
+
+
+
+ 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.
+
+
+ + + +### Additional Transaction Syntactic Validation Rules + +#### Output Syntactic Validation + +- `Amount` field must fulfill the dust protection requirements and must not be `0`. +- `Amount` field must be ≤ `Max IOTA Supply`. +- `Native Tokens Count` must not be greater than `Max Native Tokens Count`. +- `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`. +- It must hold true that `1` ≤ `Unlock Conditions Count` ≤ `4`. +- `Unlock Condition Type` of an Unlock Condition must define one of the following types: + - Address Unlock Condition + - Storage Deposit Return Unlock Condition + - Timelock Unlock Condition + - Expiration Unlock Condition +- Unlock Conditions must be sorted in ascending order based on their `Unlock Condition Type`. +- Syntactic validation of all present unlock conditions must pass. +- Address Unlock Condition must be present. +- It must hold true that `0` ≤ `Features Count` ≤ `3`. +- `Feature Type` of a Feature in `Features` must define one of the following types: + - Sender Feature + - Metadata Feature + - Tag Feature +- It must hold true that `0` ≤ `Immutable Features Count` ≤ `2`. +- `Feature Type` of a Feature in `Immutable Features` must define one of the following types: + - Issuer Feature + - Metadata Feature +- Features must be sorted in ascending order based on their `Feature Type` both in `Features` and `Immutable Features` + fields. +- Syntactic validation of all present features must pass. +- `Address` field of the Address Unlock Condition must not be the same as the NFT address derived from `NFT ID`. + +### Additional Transaction Semantic Validation Rules + +- Explicit `NFT ID`: `NFT ID` is taken as the value of the `NFT ID` field in the NFT output. +- Implicit `NFT ID`: When an NFT output is consumed as an input in a transaction and `NFT ID` field is zeroed out, take + the BLAKE2b-256 hash of the `Output ID` of the input as `NFT ID`. +- For every non-zero explicit `NFT ID` on the output side there must be a corresponding NFT on the input side. The + corresponding NFT has the explicit or implicit `NFT ID` equal to that of the NFT on the output side. + +#### Consumed Outputs +- The unlock of the input corresponds to `Address` field of the Address Unlock Condition and the unlock is + valid. +- The unlock is valid if and only if all unlock conditions and features present in the output validate. +- When a consumed NFT output has a corresponding NFT output on the output side, `Immutable Features` field must not + change. +- When a consumed NFT output has no corresponding NFT output on the output side, the NFT it is being burned. Funds + and assets inside the burned NFT output must be redistributed to other outputs in the burning transaction. + +| :bangbang: Careful with NFT burning :bangbang: | +|-------------------------------------------------| + +_Other outputs in the ledger that are locked to the address of the NFT can only be unlocked by including the NFT itself +in the transaction. If the NFT is burned, such funds are locked forever. It is strongly advised to always check and +sweep what the NFT owns in the ledger before burning it._ + +#### Created Outputs +- When `Issuer Feature` is present in an output and explicit `NFT ID` is zeroed out, an input with `Address` field that + corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Alias Address or + NFT Address, their corresponding outputs (defined by `Alias ID` and `NFT ID`) must be unlocked in the transaction. +- All Unlock Condition imposed transaction validation criteria must be fulfilled. +- All Feature imposed transaction validation criteria must be fulfilled. + +### Notes +- It would be possible to have two-step issuer verification: First NFT is minted, and then metadata can be immutably + locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way + a smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. + + + +### NFT Locking & Unlocking + +`NFT ID` field is functionally equivalent to `Alias ID` of an alias output. It is generated the same way, but it can +only exist in NFT outputs. Following the same analogy as for alias addresses, NFT addresses are iota addresses that are +controlled by whoever owns the NFT output itself. + +Outputs that are locked under `NFT Address` can be unlocked by unlocking the NFT output in the same transaction that +defines `NFT Address`, that is, the NFT output where `NFT Address Type Byte || NFT ID = NFT Address`. + +An NFT Unlock looks and behaves like an Alias Unlock, but the referenced input at the index must +be an NFT output with the matching `NFT ID`. + +
+ NFT Unlock +
+ Points to the unlock of a consumed NFT output. +
+
+ + + + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Typeuint8 + Set to value 3 to denote a NFT Unlock. +
NFT Reference Unlock Indexuint16 + Index of input and unlock corresponding to an NFT output. +
+ +An *NFT Unlock* is only valid if the input in the transaction at index `NFT Reference Unlock Index` is the NFT +output with the same `NFT ID` as the one derived from the `Address` field of the to-be unlocked output. + +If the i-th *Unlock* of a transaction is an *NFT Unlock* and has `NFT Reference Unlock Index` set to k, it +must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* at a smaller index. + +#### NFT Unlock Syntactic Validation + +- It must hold that 0 ≤ `NFT Reference Unlock Index` < `Max Inputs Count`. + +#### NFT Unlock Semantic Validation + +- The address of the input being unlocked must be an NFT Address. +- The index `i` of the NFT Unlock is the index of the input in the transaction that it unlocks. + `NFT Reference Unlock Index` must be < `i`. +- `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must + be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From cfa76ed7178f222938671ecbba918bec0a9460b7 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 15 May 2023 10:46:30 +0200 Subject: [PATCH 02/46] Rename alias to account --- tips/TIP-0043/tip-0043.md | 56 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 1a7cfb741..f45d55786 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -48,7 +48,7 @@ Global protocol parameters used throughout this TIP are defined in [TIP-22 (IOTA In the following, we define four new output types. They are all designed with specific use cases in mind: - **Basic Output**: transfer of funds with attached metadata and optional spending restrictions. Main use cases are on-ledger ISC requests, native asset transfers and indexed data storage in the UTXO ledger. -- **Alias Output**: representing ISC chain accounts on L1 that can process requests and transfer funds. +- **Account Output**: representing ISC chain accounts on L1 that can process requests and transfer funds. - **Foundry Output**: supply control of user defined native tokens. A vehicle for cross-chain asset transfers and asset wrapping. - **NFT Output**: an output that represents a Non-fungible token with attached metadata and proof-of-origin. A NFT is @@ -80,7 +80,7 @@ of the Output ID that created the NFT. The address of the NFT is the conc `NFT ID`. The NFT may contain immutable metadata set upon creation, and a verified `Issuer`. The output type supports all -non-alias specific (state controller, governor) unlock conditions and optional features so that the output can be +non-account specific (state controller, governor) unlock conditions and optional features so that the output can be sent as a request to smart contract chain accounts. @@ -195,7 +195,7 @@ sent as a request to smart contract chain accounts.
- Alias Address + Account Address @@ -206,13 +206,13 @@ sent as a request to smart contract chain accounts. - + - +
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.
@@ -286,7 +286,7 @@ sent as a request to smart contract chain accounts.
- Alias Address + Account Address @@ -297,13 +297,13 @@ sent as a request to smart contract chain accounts. - + - +
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.
@@ -412,7 +412,7 @@ sent as a request to smart contract chain accounts.
- Alias Address + Account Address @@ -423,13 +423,13 @@ sent as a request to smart contract chain accounts. - + - +
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.
@@ -520,7 +520,7 @@ sent as a request to smart contract chain accounts.
- Alias Address + Account Address @@ -531,13 +531,13 @@ sent as a request to smart contract chain accounts. - + - +
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.
@@ -671,7 +671,7 @@ sent as a request to smart contract chain accounts.
- Alias Address + Account Address @@ -682,13 +682,13 @@ sent as a request to smart contract chain accounts. - + - +
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.
@@ -809,8 +809,8 @@ sweep what the NFT owns in the ledger before burning it._ #### Created Outputs - When `Issuer Feature` is present in an output and explicit `NFT ID` is zeroed out, an input with `Address` field that - corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Alias Address or - NFT Address, their corresponding outputs (defined by `Alias ID` and `NFT ID`) must be unlocked in the transaction. + corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Account Address or + NFT Address, their corresponding outputs (defined by `Account ID` and `NFT ID`) must be unlocked in the transaction. - All Unlock Condition imposed transaction validation criteria must be fulfilled. - All Feature imposed transaction validation criteria must be fulfilled. @@ -819,18 +819,16 @@ sweep what the NFT owns in the ledger before burning it._ locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way a smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. - - ### NFT Locking & Unlocking -`NFT ID` field is functionally equivalent to `Alias ID` of an alias output. It is generated the same way, but it can -only exist in NFT outputs. Following the same analogy as for alias addresses, NFT addresses are iota addresses that are +The `NFT ID` field is functionally equivalent to `Account ID` of an account output. It is generated the same way, but it can +only exist in NFT outputs. Following the same analogy as for account addresses, NFT addresses are iota addresses that are controlled by whoever owns the NFT output itself. Outputs that are locked under `NFT Address` can be unlocked by unlocking the NFT output in the same transaction that defines `NFT Address`, that is, the NFT output where `NFT Address Type Byte || NFT ID = NFT Address`. -An NFT Unlock looks and behaves like an Alias Unlock, but the referenced input at the index must +An NFT Unlock looks and behaves like an Account Unlock, but the referenced input at the index must be an NFT output with the matching `NFT ID`.
From 0e9139bb06acd724f2d1eac9b3c968b271f6aa8b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 16 May 2023 10:27:34 +0200 Subject: [PATCH 03/46] Add summary & motivation --- tips/TIP-0043/tip-0043.md | 41 ++++++++------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index f45d55786..4977983ab 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -16,18 +16,21 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 1. [Summary](#summary) 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) -4. [Unlock Conditions](#unlock-conditions) - - [Account Locking & Unlocking](#account-locking--unlocking) +4. [NFT Output](#nft-output) 5. [Outputs](#outputs) 6. [Copyright](#copyright) # Summary -TODO: Adapt from TIP-18 summary. +This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 native **non-fungible tokens** (unique tokens with attached metadata). It was originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the NFT output of TIP-18. # Motivation -TODO: Adapt from TIP-18 motivation. +The aim of this TIP is to define an NFT output type for the use cases of seamless interoperability between layer 1 and layer 2 tokenization concepts. Such non-fungible tokens on layer 1 can be minted and transferred with zero fees. The validated issuers of such NFTs are immutably attached to the tokens, making it impossible to counterfeit them. + +In combination with the other layer 1 output types, users will be able to interact with smart contracts by posting requests through the Tangle. Requests can carry commands to smart contracts and can additionally also transfer native tokens and NFTs. + +The proposal in this TIP makes it possible for tokens that originate from layer 2 smart contract chains to also be wrapped into their layer 1 representation. Smart contract chains may transfer tokens between themselves through this mechanism, and they can also post requests to other chains. # Building Blocks @@ -43,35 +46,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. -# Outputs - -In the following, we define four new output types. They are all designed with specific use cases in mind: -- **Basic Output**: transfer of funds with attached metadata and optional spending restrictions. Main use cases are - on-ledger ISC requests, native asset transfers and indexed data storage in the UTXO ledger. -- **Account Output**: representing ISC chain accounts on L1 that can process requests and transfer funds. -- **Foundry Output**: supply control of user defined native tokens. A vehicle for cross-chain asset transfers and asset - wrapping. -- **NFT Output**: an output that represents a Non-fungible token with attached metadata and proof-of-origin. A NFT is - represented as an output so that the token and metadata are transferred together, for example as a smart contract - requests. NFTs are possible to implement with native tokens as well, but then ownership of the token does not mean - ownership of the foundry that holds its metadata. - -The validation of outputs is part of the transaction validation process. There are two levels of validation for -transactions: syntactic and semantic validation. The former validates the structure of the transaction (and outputs), -while the latter validates whether protocol rules are respected in the semantic context of the transaction. Outputs -hence are validated on both levels: -1. **Transaction Syntactic Validation**: validates the structure of each output created by the transaction. -2. **Transaction Semantic Validation**: - - **For consumed outputs**: validates whether the output can be unlocked in a transaction given the semantic - transaction context. - - **For created outputs**: validates whether the output can be created in a transaction given the semantic - transaction context. - -Each new output type may add its own validation rules which become part of the transaction validation rules if the -output is placed inside a transaction. Unlock Conditions and Features described previously also add -constraints to transaction validation when they are placed in outputs. - -## NFT Output +# NFT Output Non-fungible tokens in the ledger are implemented with a special output type, the so-called NFTOutput. From 75fdfa7c9fbc328dcf823ca43a452c4b5de51797 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 16 May 2023 10:30:48 +0200 Subject: [PATCH 04/46] Fix header indentation --- tips/TIP-0043/tip-0043.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 4977983ab..f27b6c283 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -8,7 +8,7 @@ status: Draft type: Standards layer: Core created: 2023-05-03 -requires: TIP-19, TIP-20, TIP-21 and TIP-22 +requires: TIP-19, TIP-20, TIP-21, TIP-22 and TIP-38 --- # Table of Contents @@ -17,8 +17,7 @@ requires: TIP-19, TIP-20, TIP-21 and TIP-22 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) 4. [NFT Output](#nft-output) -5. [Outputs](#outputs) -6. [Copyright](#copyright) +5. [Copyright](#copyright) # Summary @@ -724,9 +723,9 @@ sent as a request to smart contract chain accounts.
-### Additional Transaction Syntactic Validation Rules +## Additional Transaction Syntactic Validation Rules -#### Output Syntactic Validation +### Output Syntactic Validation - `Amount` field must fulfill the dust protection requirements and must not be `0`. - `Amount` field must be ≤ `Max IOTA Supply`. @@ -758,7 +757,7 @@ sent as a request to smart contract chain accounts. - Syntactic validation of all present features must pass. - `Address` field of the Address Unlock Condition must not be the same as the NFT address derived from `NFT ID`. -### Additional Transaction Semantic Validation Rules +## Additional Transaction Semantic Validation Rules - Explicit `NFT ID`: `NFT ID` is taken as the value of the `NFT ID` field in the NFT output. - Implicit `NFT ID`: When an NFT output is consumed as an input in a transaction and `NFT ID` field is zeroed out, take @@ -766,7 +765,7 @@ sent as a request to smart contract chain accounts. - For every non-zero explicit `NFT ID` on the output side there must be a corresponding NFT on the input side. The corresponding NFT has the explicit or implicit `NFT ID` equal to that of the NFT on the output side. -#### Consumed Outputs +### Consumed Outputs - The unlock of the input corresponds to `Address` field of the Address Unlock Condition and the unlock is valid. - The unlock is valid if and only if all unlock conditions and features present in the output validate. @@ -782,19 +781,19 @@ _Other outputs in the ledger that are locked to the address of the NFT can only in the transaction. If the NFT is burned, such funds are locked forever. It is strongly advised to always check and sweep what the NFT owns in the ledger before burning it._ -#### Created Outputs +### Created Outputs - When `Issuer Feature` is present in an output and explicit `NFT ID` is zeroed out, an input with `Address` field that corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Account Address or NFT Address, their corresponding outputs (defined by `Account ID` and `NFT ID`) must be unlocked in the transaction. - All Unlock Condition imposed transaction validation criteria must be fulfilled. - All Feature imposed transaction validation criteria must be fulfilled. -### Notes +## Notes - It would be possible to have two-step issuer verification: First NFT is minted, and then metadata can be immutably locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way a smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. -### NFT Locking & Unlocking +## NFT Locking & Unlocking The `NFT ID` field is functionally equivalent to `Account ID` of an account output. It is generated the same way, but it can only exist in NFT outputs. Following the same analogy as for account addresses, NFT addresses are iota addresses that are @@ -841,11 +840,11 @@ output with the same `NFT ID` as the one derived from the `Address` field of the If the i-th *Unlock* of a transaction is an *NFT Unlock* and has `NFT Reference Unlock Index` set to k, it must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* at a smaller index. -#### NFT Unlock Syntactic Validation +### NFT Unlock Syntactic Validation - It must hold that 0 ≤ `NFT Reference Unlock Index` < `Max Inputs Count`. -#### NFT Unlock Semantic Validation +### NFT Unlock Semantic Validation - The address of the input being unlocked must be an NFT Address. - The index `i` of the NFT Unlock is the index of the input in the transaction that it unlocks. From 1eef9d166be16c5560b169da51811b5800576560 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 16 May 2023 10:32:16 +0200 Subject: [PATCH 05/46] Fill out header --- tips/TIP-0043/tip-0043.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index f27b6c283..52f9701ce 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1,7 +1,7 @@ --- -tip: TODO -title: TODO -description: TODO +tip: 43 +title: Non-fungible Token Output Type +description: Support for layer 1 native non-fungible tokens author: TODO discussions-to: TODO status: Draft From 96cca3bc9616ff198ef75641ef3f444ed0af12a0 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 16 May 2023 10:48:26 +0200 Subject: [PATCH 06/46] Add storage deposit calculation --- tips/TIP-0043/tip-0043.md | 917 +++++++++++++++++++++++++++++++++++++- 1 file changed, 916 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 52f9701ce..72b48a9ae 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -17,7 +17,8 @@ requires: TIP-19, TIP-20, TIP-21, TIP-22 and TIP-38 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) 4. [NFT Output](#nft-output) -5. [Copyright](#copyright) +5. [Storage Deposit](#storage-deposit) +6. [Copyright](#copyright) # Summary @@ -852,6 +853,920 @@ must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* - `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. +# Storage Deposit + +The following table shows the NFT output including the possible fields and their specific weight. + + +
+ NFT Output +
+ Describes an NFT output, a globally unique token with metadata attached. +
+
+ + + + + + + + + + + + + + + + +
Offset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldField typeLength MinimumLength MaximumDescription
OutputIDkey3434The ID of the output.
Block ID (included)data3232The ID of the block in which the transaction payload that created this output was included.
Confirmation Milestone Indexdata44The index of the milestone which confirmed the transaction that created the output.
Confirmation Unix Timestampdata44The unix timestamp of the milestone which confirmed the transaction that created the output.
+
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Output Typedata11 + Set to value 6 to denote a NFT Output. +
Amountdata88The amount of IOTA coins held by the output.
Native Tokens Countdata11The number of native tokens held by the output.
Native Tokens optAnyOf +
+ Native Token + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Token IDdata3838 + Identifier of the native token. +
Amountdata3232 + Amount of native tokens of the given Token ID. +
+
+
NFT IDdata3232Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID
Unlock Conditions Countdata11The number of unlock conditions following.
Unlock Conditions atMostOneOfEach +
+ Address Unlock Condition + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 0 to denote an Address Unlock Condition. +
Address +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Alias Address. +
Alias IDdata3232The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Storage Deposit Return Unlock Condition +
+ Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 1 to denote a Storage Deposit Return Unlock Condition. +
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Alias Address. +
Alias IDdata3232The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Return Amountdata88 + Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address. +
+
+
+ Timelock Unlock Condition +
+ Defines a unix timestamp until which the output can not be unlocked. +
+ + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 2 to denote a Timelock Unlock Condition. +
Unix Timedata44 + Unix time (seconds since Unix epoch) starting from which the output can be consumed. +
+
+
+ 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. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 3 to denote a Expiration Unlock Condition. +
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Alias Address. +
Alias IDdata3232The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Unix Timedata44 + Before this unix time, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. +
+
+
Features Countdata11The number of features following.
Features atMostOneOfEach +
+ Sender Feature +
+ Identifies the validated sender of the output. +
+ + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 0 to denote a Sender Feature. +
Sender oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Alias Address. +
Alias IDdata3232The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Metadata Feature +
+ Defines metadata (arbitrary binary data) that will be stored in the output. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 2 to denote a Metadata Feature. +
Data Lengthdata22 + Length of the following data field in bytes. +
Datadata18192Binary data.
+
+
+ Tag Feature +
+ Defines an indexation tag to which the output can be indexed by additional node plugins. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 3 to denote a Tag Feature. +
Tag Lengthdata11 + Length of the following tag field in bytes. +
Tagdata1255Binary indexation data.
+
+
Immutable Features Countdata11The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach +
+ Issuer Feature +
+ Identifies the validated issuer of the UTXO state machine. +
+ + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 1 to denote an Issuer Feature. +
Issuer oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Alias Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Alias Address. +
Alias IDdata3232The raw bytes of the Alias ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Metadata Feature +
+ Defines metadata (arbitrary binary data) that will be stored in the output. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 2 to denote a Metadata Feature. +
Data Lengthdata22 + Length of the following data field in bytes. +
Datadata18192Binary data.
+
+
+
v_byte Minimum459
v_byte Maximum21739
+ + + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 38f198095bbd0b83e2e3d7d9388c18e03fac186a Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Wed, 17 May 2023 17:56:44 +0200 Subject: [PATCH 07/46] Added mana_amount, storage deposit calc --- ...it_miota_NFTOutput_(max_functionality).jpg | Bin 0 -> 53897 bytes ...it_miota_NFTOutput_(min_functionality).jpg | Bin 0 -> 51746 bytes tips/TIP-0043/tip-0043.md | 930 +++++++++++++++++- 3 files changed, 929 insertions(+), 1 deletion(-) create mode 100644 tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg create mode 100644 tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg diff --git a/tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg b/tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg new file mode 100644 index 0000000000000000000000000000000000000000..caf59f15d1c4535093200ddf94554c28ac1f80f2 GIT binary patch literal 53897 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

^kaf$bvj!_ zP4>g38VE&hU$>4F>gr+PmxjP8|7I2RkjVkffgxzt5?02cAn!FW_G8f|HsccU#F4;u zmRJtkCSRqozJ@=N0>-^9{OtZ48PMhqNUZziGeWP-s1_0nrHk!B-pmdFNXNYzdd*v4KGqQNrYmqDFkQ4$(N(2t7$XSQX{Pf*(boVhz}WlKX9|>!#SK15sb}ET zYos*yy?ROY65hVqaE{WdSPqajKIeWnC028nM&qP=drc## zK#hE)b)5Lf+QsRu2hCPdBpAIT^99*+!>jA1WW3ycu0|=()dFYIEnSY!=HG4UELob2lV`%NG?YBvP06h4cysdd$@K z)hw+-r1)bpWD4awXf@`$m@hGvEOG2^>*^srrt-H221AE)i+FGLGI*1Yec!n}1C<4; zH?oFxmTp7$8p@nGt4pT)_=3&7@NLVQ9)0ZqMxEHb0)nzNl?nAUNy#bm7)*dyE?{od zUoO?&i`9WH%lkv2QLLyWN{7~Xv`iD~g#1nxx;6i5!=_Qy#)c{>vxv8{$>0G?A+I+c zD@Fw;)Np!?MzJ`AFgy0Tp>IdCy)|12Pf)fb zjc@t$NuhP65?hp9@VcJawDLGhdEb-!1CToFJHhUBzWs!`qm*ye0?x2)=8=R?+760} z#%84;BO2*QI(#li5)lz03cg*(C1?M5@#@ZtG+~#(e4KH0!AbZ5FbYO;>PlFkr#a(^ zs*hUawT4hv6N}4GVO_2KDW5o^D~8+rolewT(oPPF`)bMe()4`{tiDs94j_IgsftuQ zz<5|zt=ED?*eUD>>Zbp0RE$_1Cx&fb+gO)1!`YkfHs~{09rov(H1huy?Dz}pTq274 zoEhpqkYs=hbJ5s?_b=<#21fDFqwsGLWcLYi!qnDbgOiKpv~VnjnvVsK)>

C?-$bzxf`Q$TAnhbTe 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 He;W8RY+kq> literal 0 HcmV?d00001 diff --git a/tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg b/tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg new file mode 100644 index 0000000000000000000000000000000000000000..c83c4035785fefca00f0205616c9f3b3e467f9f5 GIT binary patch literal 51746 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 AH~;_u literal 0 HcmV?d00001 diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index f45d55786..fdf41670b 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -107,6 +107,11 @@ sent as a request to smart contract chain accounts. uint64 The amount of IOTA coins held by the output. + + Mana Amount mana_output + uint64 + The amount of (stored) Mana held by the output. + Native Tokens Count uint8 @@ -752,9 +757,9 @@ sent as a request to smart contract chain accounts. ### Additional Transaction Syntactic Validation Rules #### Output Syntactic Validation - - `Amount` field must fulfill the dust protection requirements and must not be `0`. - `Amount` field must be ≤ `Max IOTA Supply`. +- Mana Amount `mana_amount` field must be ≥ 0 and ≤ `TOTAL_MANA`. - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 @@ -878,6 +883,929 @@ must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* - `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. +### Storage Deposit Calculation + + +
+ NFT Output +
+ Describes an NFT output, a globally unique token with metadata attached. +
+
+ + + + + + + + + + + + + + + + +
Offset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldField typeLength MinimumLength MaximumDescription
OutputIDkey3434The ID of the output.
Block ID (included)data3232The ID of the block in which the transaction payload that created this output was included.
Confirmation Milestone Indexdata44The index of the milestone which confirmed the transaction that created the output.
Confirmation Unix Timestampdata44The unix timestamp of the milestone which confirmed the transaction that created the output.
+
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Output Typedata11 + Set to value 6 to denote a NFT Output. +
Amountdata88The amount of IOTA coins held by the output.
Mana Amount mana_amountdata88The amount of (stored) Mana held by the output.
Native Tokens Countdata11The number of native tokens held by the output.
Native Tokens optAnyOf +
+ Native Token + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Token IDdata3838 + Identifier of the native token. +
Amountdata3232 + Amount of native tokens of the given Token ID. +
+
+
NFT IDdata3232Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID
Unlock Conditions Countdata11The number of unlock conditions following.
Unlock Conditions atMostOneOfEach +
+ Address Unlock Condition + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 0 to denote an Address Unlock Condition. +
Address +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Account Address. +
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Storage Deposit Return Unlock Condition +
+ Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 1 to denote a Storage Deposit Return Unlock Condition. +
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Account Address. +
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Return Amountdata88 + Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address. +
+
+
+ Timelock Unlock Condition +
+ Defines a unix timestamp until which the output can not be unlocked. +
+ + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 2 to denote a Timelock Unlock Condition. +
Unix Timedata44 + Unix time (seconds since Unix epoch) starting from which the output can be consumed. +
+
+
+ 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. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 + Set to value 3 to denote a Expiration Unlock Condition. +
Return Address oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Account Address. +
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
Unix Timedata44 + Before this unix time, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. +
+
+
Features Countdata11The number of features following.
Features atMostOneOfEach +
+ Sender Feature +
+ Identifies the validated sender of the output. +
+ + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 0 to denote a Sender Feature. +
Sender oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Account Address. +
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Metadata Feature +
+ Defines metadata (arbitrary binary data) that will be stored in the output. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 2 to denote a Metadata Feature. +
Data Lengthdata22 + Length of the following data field in bytes. +
Datadata18192Binary data.
+
+
+ Tag Feature +
+ Defines an indexation tag to which the output can be indexed by additional node plugins. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 3 to denote a Tag Feature. +
Tag Lengthdata11 + Length of the following tag field in bytes. +
Tagdata1255Binary indexation data.
+
+
Immutable Features Countdata11The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach +
+ Issuer Feature +
+ Identifies the validated issuer of the UTXO state machine. +
+ + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 1 to denote an Issuer Feature. +
Issuer oneOf +
+ Ed25519 Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 0 to denote an Ed25519 Address. +
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
+
+
+ Account Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 8 to denote an Account Address. +
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+ NFT Address + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 + Set to value 16 to denote an NFT Address. +
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
+
+
+
+
+ Metadata Feature +
+ Defines metadata (arbitrary binary data) that will be stored in the output. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 + Set to value 2 to denote a Metadata Feature. +
Data Lengthdata22 + Length of the following data field in bytes. +
Datadata18192Binary data.
+
+
+
v_byte Minimum459
v_byte Maximum21739
+ + + +![](assets/deposit_miota_NFTOutput_(min_functionality).jpg) + +![](assets/deposit_miota_NFTOutput_(max_functionality).jpg) + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 083442b8878d1fec20dda324bbe3e4db6288f4a8 Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Fri, 19 May 2023 12:03:45 +0200 Subject: [PATCH 08/46] Minor correction to storage deposit calc --- tips/TIP-0043/tip-0043.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index fdf41670b..ffdd67af7 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -885,6 +885,8 @@ must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* ### Storage Deposit Calculation +The following table shows the NFT output including the possible fields and their specific weight. +
NFT Output From 54afb33b39456a92f358d6c05703a208ab6bc9d2 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 23 May 2023 17:48:30 +0200 Subject: [PATCH 09/46] Remove storage deposit figures --- ...osit_miota_NFTOutput_(max_functionality).jpg | Bin 53897 -> 0 bytes ...osit_miota_NFTOutput_(min_functionality).jpg | Bin 51746 -> 0 bytes tips/TIP-0043/tip-0043.md | 4 ---- 3 files changed, 4 deletions(-) delete mode 100644 tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg delete mode 100644 tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg diff --git a/tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg b/tips/TIP-0043/assets/deposit_miota_NFTOutput_(max_functionality).jpg deleted file mode 100644 index caf59f15d1c4535093200ddf94554c28ac1f80f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53897 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

^kaf$bvj!_ zP4>g38VE&hU$>4F>gr+PmxjP8|7I2RkjVkffgxzt5?02cAn!FW_G8f|HsccU#F4;u zmRJtkCSRqozJ@=N0>-^9{OtZ48PMhqNUZziGeWP-s1_0nrHk!B-pmdFNXNYzdd*v4KGqQNrYmqDFkQ4$(N(2t7$XSQX{Pf*(boVhz}WlKX9|>!#SK15sb}ET zYos*yy?ROY65hVqaE{WdSPqajKIeWnC028nM&qP=drc## zK#hE)b)5Lf+QsRu2hCPdBpAIT^99*+!>jA1WW3ycu0|=()dFYIEnSY!=HG4UELob2lV`%NG?YBvP06h4cysdd$@K z)hw+-r1)bpWD4awXf@`$m@hGvEOG2^>*^srrt-H221AE)i+FGLGI*1Yec!n}1C<4; zH?oFxmTp7$8p@nGt4pT)_=3&7@NLVQ9)0ZqMxEHb0)nzNl?nAUNy#bm7)*dyE?{od zUoO?&i`9WH%lkv2QLLyWN{7~Xv`iD~g#1nxx;6i5!=_Qy#)c{>vxv8{$>0G?A+I+c zD@Fw;)Np!?MzJ`AFgy0Tp>IdCy)|12Pf)fb zjc@t$NuhP65?hp9@VcJawDLGhdEb-!1CToFJHhUBzWs!`qm*ye0?x2)=8=R?+760} z#%84;BO2*QI(#li5)lz03cg*(C1?M5@#@ZtG+~#(e4KH0!AbZ5FbYO;>PlFkr#a(^ zs*hUawT4hv6N}4GVO_2KDW5o^D~8+rolewT(oPPF`)bMe()4`{tiDs94j_IgsftuQ zz<5|zt=ED?*eUD>>Zbp0RE$_1Cx&fb+gO)1!`YkfHs~{09rov(H1huy?Dz}pTq274 zoEhpqkYs=hbJ5s?_b=<#21fDFqwsGLWcLYi!qnDbgOiKpv~VnjnvVsK)>

C?-$bzxf`Q$TAnhbTe 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 He;W8RY+kq> diff --git a/tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg b/tips/TIP-0043/assets/deposit_miota_NFTOutput_(min_functionality).jpg deleted file mode 100644 index c83c4035785fefca00f0205616c9f3b3e467f9f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51746 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 AH~;_u diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 31d9bbaff..4a32a1462 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1780,10 +1780,6 @@ The following table shows the NFT output including the possible fields and their

-![](assets/deposit_miota_NFTOutput_(min_functionality).jpg) - -![](assets/deposit_miota_NFTOutput_(max_functionality).jpg) - # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 0d70497c8ef9e768c5bdcc6611e0cc28ffa08e93 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 23 May 2023 17:50:24 +0200 Subject: [PATCH 10/46] Use `Mana Amount` field name --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 4a32a1462..74f788635 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -83,7 +83,7 @@ sent as a request to smart contract chain accounts. The amount of IOTA coins held by the output. - Mana Amount mana_output + Mana Amount uint64 The amount of (stored) Mana held by the output. @@ -940,7 +940,7 @@ The following table shows the NFT output including the possible fields and their The amount of IOTA coins held by the output. - Mana Amount mana_amount + Mana Amount data 8 8 From c35a3caba3a782d17e2c5cd0bfc8a4012f19952d Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 23 May 2023 17:57:05 +0200 Subject: [PATCH 11/46] Make `Mana Amount` rule consistent --- tips/TIP-0043/tip-0043.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 74f788635..98586d707 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -735,7 +735,7 @@ sent as a request to smart contract chain accounts. - `Amount` field must fulfill the dust protection requirements and must not be `0`. - `Amount` field must be ≤ `Max IOTA Supply`. -- Mana Amount `mana_amount` field must be ≥ 0 and ≤ `TOTAL_MANA`. +- Mana Amount field must be ≤ `Total Mana`. - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 From 455ff47e4a356a7ac89c387339c7e690a6c37e0e Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 23 May 2023 18:22:04 +0200 Subject: [PATCH 12/46] Update v_byte min & max --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 98586d707..937c1e936 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1770,11 +1770,11 @@ The following table shows the NFT output including the possible fields and their v_byte Minimum - 459 + 467 v_byte Maximum - 21739 + 21747 From b3ab0a0c93a1a323c613467e0259652a03a12429 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 14:06:37 +0200 Subject: [PATCH 13/46] Update Timelock & Expiration UC --- tips/TIP-0043/tip-0043.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 937c1e936..dcc0a9116 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -8,7 +8,8 @@ status: Draft type: Standards layer: Core created: 2023-05-03 -requires: TIP-19, TIP-20, TIP-21, TIP-22 and TIP-38 +requires: TIP-21, TIP-22, TIP-38, TIP-41, TIP-45 and TIP-47 +replaces: TIP-18 --- # Table of Contents @@ -44,7 +45,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. # NFT Output @@ -323,7 +324,7 @@ sent as a request to smart contract chain accounts.

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.
@@ -339,10 +340,10 @@ sent as a request to smart contract chain accounts. - - + + +
Unix Timeuint32Slot Indexuint64 - Unix time (seconds since Unix epoch) starting from which the output can be consumed. + Slot index starting from which the output can be consumed.
@@ -350,8 +351,9 @@ sent as a request to smart contract chain accounts.
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 or 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.
@@ -363,7 +365,7 @@ sent as a request to smart contract chain accounts. @@ -438,10 +440,10 @@ sent as a request to smart contract chain accounts. - - + +
Unlock Condition Type uint8 - Set to value 3 to denote a Expiration Unlock Condition. + Set to value 3 to denote an Expiration Unlock Condition.
Unix Timeuint32Slot Indexuint64 - 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 0e0d81ad686a7ebe6d2692dabf21a00a693d3b38 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 14:10:15 +0200 Subject: [PATCH 14/46] Update header --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index dcc0a9116..2305c73d7 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -2,13 +2,13 @@ tip: 43 title: Non-fungible Token Output Type description: Support for layer 1 native non-fungible tokens -author: TODO +author: Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards layer: Core created: 2023-05-03 -requires: TIP-21, TIP-22, TIP-38, TIP-41, TIP-45 and TIP-47 +requires: TIP-21, TIP-22, TIP-38, TIP-45 and TIP-47 replaces: TIP-18 --- From 3bc9b793201fb2568d8dbaa0d43ae315e6b94929 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Sat, 27 May 2023 14:28:05 +0200 Subject: [PATCH 15/46] Update storage deposit calculation --- tips/TIP-0043/tip-0043.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 2305c73d7..fda646d1a 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -341,7 +341,7 @@ sent as a request to smart contract chain accounts. Slot Index - uint64+ + uint64 Slot index starting from which the output can be consumed. @@ -1242,7 +1242,7 @@ The following table shows the NFT output including the possible fields and their
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.
@@ -1262,12 +1262,12 @@ The following table shows the NFT output including the possible fields and their - - - - + + + +
Unix Timedata44Slot Indexdata88 - Unix time (seconds since Unix epoch) starting from which the output can be consumed. + Slot index starting from which the output can be consumed.
@@ -1275,8 +1275,9 @@ The following table shows the NFT output including the possible fields and their
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.
@@ -1385,12 +1386,12 @@ The following table shows the NFT output including the possible fields and their - - - - + + + +
Unix Timedata44Slot Indexdata88 - Before this unix time, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address. + Slot index starting from which the output can be consumed.
@@ -1772,11 +1773,11 @@ The following table shows the NFT output including the possible fields and their v_byte Minimum - 467 + 475 v_byte Maximum - 21747 + 21755
From cec71ebc7bbb6d562a2516ba8380967f99897051 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 31 May 2023 09:57:16 +0200 Subject: [PATCH 16/46] Format markdown --- tips/TIP-0043/tip-0043.md | 77 +++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index fda646d1a..911a0b296 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -2,7 +2,8 @@ tip: 43 title: Non-fungible Token Output Type description: Support for layer 1 native non-fungible tokens -author: Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) +author: + Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards @@ -23,15 +24,24 @@ replaces: TIP-18 # Summary -This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 native **non-fungible tokens** (unique tokens with attached metadata). It was originally introduced in [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the NFT output of TIP-18. +This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 +native **non-fungible tokens** (unique tokens with attached metadata). It was originally introduced in +[TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the NFT output +of TIP-18. # Motivation -The aim of this TIP is to define an NFT output type for the use cases of seamless interoperability between layer 1 and layer 2 tokenization concepts. Such non-fungible tokens on layer 1 can be minted and transferred with zero fees. The validated issuers of such NFTs are immutably attached to the tokens, making it impossible to counterfeit them. +The aim of this TIP is to define an NFT output type for the use cases of seamless interoperability between layer 1 and +layer 2 tokenization concepts. Such non-fungible tokens on layer 1 can be minted and transferred with zero fees. The +validated issuers of such NFTs are immutably attached to the tokens, making it impossible to counterfeit them. -In combination with the other layer 1 output types, users will be able to interact with 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, users will be able to interact with smart contracts by posting +requests through the Tangle. Requests can carry commands to smart contracts and can additionally also transfer native +tokens and NFTs. -The proposal in this TIP makes it possible for tokens that originate from layer 2 smart contract chains to also be wrapped into their layer 1 representation. Smart contract chains may transfer tokens between themselves through this mechanism, and they can also post requests to other chains. +The proposal in this TIP makes it possible for tokens that originate from layer 2 smart contract chains to also be +wrapped into their layer 1 representation. Smart contract chains may transfer tokens between themselves through this +mechanism, and they can also post requests to other chains. # Building Blocks @@ -41,7 +51,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 @@ -56,8 +67,8 @@ of the Output ID that created the NFT. The address of the NFT is the conc `NFT ID`. The NFT may contain immutable metadata set upon creation, and a verified `Issuer`. The output type supports all -non-account specific (state controller, governor) unlock conditions and optional features so that the output can be -sent as a request to smart contract chain accounts. +non-account specific (state controller, governor) unlock conditions and optional features so that the output can be sent +as a request to smart contract chain accounts.
@@ -761,8 +772,8 @@ sent as a request to smart contract chain accounts. - `Feature Type` of a Feature in `Immutable Features` must define one of the following types: - Issuer Feature - Metadata Feature -- Features must be sorted in ascending order based on their `Feature Type` both in `Features` and `Immutable Features` - fields. +- Features must be sorted in ascending order based on their `Feature Type` both in `Features` and + `Immutable Features` fields. - Syntactic validation of all present features must pass. - `Address` field of the Address Unlock Condition must not be the same as the NFT address derived from `NFT ID`. @@ -775,44 +786,46 @@ sent as a request to smart contract chain accounts. corresponding NFT has the explicit or implicit `NFT ID` equal to that of the NFT on the output side. ### Consumed Outputs -- The unlock of the input corresponds to `Address` field of the Address Unlock Condition and the unlock is - valid. + +- The unlock of the input corresponds to `Address` field of the Address Unlock Condition and the unlock is valid. - The unlock is valid if and only if all unlock conditions and features present in the output validate. - When a consumed NFT output has a corresponding NFT output on the output side, `Immutable Features` field must not change. -- When a consumed NFT output has no corresponding NFT output on the output side, the NFT it is being burned. Funds - and assets inside the burned NFT output must be redistributed to other outputs in the burning transaction. +- When a consumed NFT output has no corresponding NFT output on the output side, the NFT it is being burned. Funds and + assets inside the burned NFT output must be redistributed to other outputs in the burning transaction. -| :bangbang: Careful with NFT burning :bangbang: | -|-------------------------------------------------| +| :bangbang: Careful with NFT burning :bangbang: | +| ---------------------------------------------- | _Other outputs in the ledger that are locked to the address of the NFT can only be unlocked by including the NFT itself in the transaction. If the NFT is burned, such funds are locked forever. It is strongly advised to always check and sweep what the NFT owns in the ledger before burning it._ ### Created Outputs + - When `Issuer Feature` is present in an output and explicit `NFT ID` is zeroed out, an input with `Address` field that - corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Account Address or - NFT Address, their corresponding outputs (defined by `Account ID` and `NFT ID`) must be unlocked in the transaction. + corresponds to `Issuer` must be unlocked in the transaction. If `Address` is either Account Address or NFT + Address, their corresponding outputs (defined by `Account ID` and `NFT ID`) must be unlocked in the transaction. - All Unlock Condition imposed transaction validation criteria must be fulfilled. - All Feature imposed transaction validation criteria must be fulfilled. ## Notes + - It would be possible to have two-step issuer verification: First NFT is minted, and then metadata can be immutably - locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way - a smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. + locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way a + smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. ## NFT Locking & Unlocking -The `NFT ID` field is functionally equivalent to `Account ID` of an account output. It is generated the same way, but it can -only exist in NFT outputs. Following the same analogy as for account addresses, NFT addresses are iota addresses that are -controlled by whoever owns the NFT output itself. +The `NFT ID` field is functionally equivalent to `Account ID` of an account output. It is generated the same way, but it +can only exist in NFT outputs. Following the same analogy as for account addresses, NFT addresses are iota addresses +that are controlled by whoever owns the NFT output itself. Outputs that are locked under `NFT Address` can be unlocked by unlocking the NFT output in the same transaction that defines `NFT Address`, that is, the NFT output where `NFT Address Type Byte || NFT ID = NFT Address`. -An NFT Unlock looks and behaves like an Account Unlock, but the referenced input at the index must -be an NFT output with the matching `NFT ID`. +An NFT Unlock looks and behaves like an Account Unlock, but the referenced input at the index must be an +NFT output with the matching `NFT ID`.
NFT Unlock @@ -843,11 +856,11 @@ be an NFT output with the matching `NFT ID`.
-An *NFT Unlock* is only valid if the input in the transaction at index `NFT Reference Unlock Index` is the NFT -output with the same `NFT ID` as the one derived from the `Address` field of the to-be unlocked output. +An _NFT Unlock_ is only valid if the input in the transaction at index `NFT Reference Unlock Index` is the NFT output +with the same `NFT ID` as the one derived from the `Address` field of the to-be unlocked output. -If the i-th *Unlock* of a transaction is an *NFT Unlock* and has `NFT Reference Unlock Index` set to k, it -must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* at a smaller index. +If the i-th _Unlock_ of a transaction is an _NFT Unlock_ and has `NFT Reference Unlock Index` set to k, it must hold +that i > k. Hence, an NFT Unlock can only reference an _Unlock_ at a smaller index. ### NFT Unlock Syntactic Validation @@ -857,9 +870,9 @@ must hold that i > k. Hence, an NFT Unlock can only reference an *Unlock* - The address of the input being unlocked must be an NFT Address. - The index `i` of the NFT Unlock is the index of the input in the transaction that it unlocks. - `NFT Reference Unlock Index` must be < `i`. -- `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must - be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. + `NFT Reference Unlock Index` must be < `i`. +- `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an NFT + Output with `NFT ID` that refers to the NFT Address being unlocked. # Storage Deposit From 4ea0ffb9d45071d920307ec3d5ad39026f5eac21 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 4 Jul 2023 11:59:37 +0200 Subject: [PATCH 17/46] Rename `Mana Amount` -> `Mana` --- tips/TIP-0043/tip-0043.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 911a0b296..df846872f 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -29,6 +29,11 @@ native **non-fungible tokens** (unique tokens with attached metadata). It was or [TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the NFT output of TIP-18. +## Summary of changes compared to TIP-18 + +- Rename "Alias" to "Account". +- Add `Mana` field. + # Motivation The aim of this TIP is to define an NFT output type for the use cases of seamless interoperability between layer 1 and @@ -95,7 +100,7 @@ as a request to smart contract chain accounts. The amount of IOTA coins held by the output. - Mana Amount + Mana uint64 The amount of (stored) Mana held by the output. @@ -748,7 +753,6 @@ as a request to smart contract chain accounts. - `Amount` field must fulfill the dust protection requirements and must not be `0`. - `Amount` field must be ≤ `Max IOTA Supply`. -- Mana Amount field must be ≤ `Total Mana`. - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 @@ -955,7 +959,7 @@ The following table shows the NFT output including the possible fields and their The amount of IOTA coins held by the output. - Mana Amount + Mana data 8 8 From 7dd1123cc9ca1dadd804bc9a13d73f92a8834ad9 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 27 Jul 2023 15:23:56 +0200 Subject: [PATCH 18/46] Catch nft ref unlock in syntactic validation --- tips/TIP-0043/tip-0043.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index df846872f..d984d0d87 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -868,7 +868,7 @@ that i > k. Hence, an NFT Unlock can only reference an _Unlock_ at a smal ### NFT Unlock Syntactic Validation -- It must hold that 0 ≤ `NFT Reference Unlock Index` < `Max Inputs Count`. +- It must hold that 0 ≤ `NFT Reference Unlock Index` < `Max Inputs Count - 1`. ### NFT Unlock Semantic Validation From 1059075dbf28d98a55557fd32bf03e05bfd85e4b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 15 Aug 2023 10:45:59 +0200 Subject: [PATCH 19/46] Update storage deposit calculation offset --- tips/TIP-0043/tip-0043.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index d984d0d87..eea0e7c5f 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -910,23 +910,23 @@ The following table shows the NFT output including the possible fields and their Block ID (included) data - 32 - 32 + 40 + 40 The ID of the block in which the transaction payload that created this output was included. - Confirmation Milestone Index + Slot Booked data - 4 - 4 - The index of the milestone which confirmed the transaction that created the output. + 8 + 8 + The index of the slot in which the transaction that created it was booked. - Confirmation Unix Timestamp + Slot Created data - 4 - 4 - The unix timestamp of the milestone which confirmed the transaction that created the output. + 8 + 8 + The index of the slot in which the transaction was created. @@ -1789,12 +1789,12 @@ The following table shows the NFT output including the possible fields and their - v_byte Minimum - 475 + v_byte Minimum (TODO: Recalculate) + 0 - v_byte Maximum - 21755 + v_byte Maximum (TODO: Recalculate) + 0
From 9778490ea6b3b98ef42b20b9d0f3753c09711236 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 11 Sep 2023 08:50:15 +0200 Subject: [PATCH 20/46] Apply suggestions from code review Co-authored-by: Thibault Martinez --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index eea0e7c5f..348532407 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1280,7 +1280,7 @@ The following table shows the NFT output including the possible fields and their Slot Index - data + data 8 8 @@ -1404,7 +1404,7 @@ The following table shows the NFT output including the possible fields and their Slot Index - data + data 8 8 From 33392bfa1f397e87bc75352cbc0193d8cb1e0740 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 11 Sep 2023 08:52:01 +0200 Subject: [PATCH 21/46] Add v_byte min/max --- tips/TIP-0043/tip-0043.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 348532407..0fb28d283 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1789,12 +1789,12 @@ The following table shows the NFT output including the possible fields and their - v_byte Minimum (TODO: Recalculate) - 0 + v_byte Minimum + 483 - v_byte Maximum (TODO: Recalculate) - 0 + v_byte Maximum + 21771
From a4e99c2bfff756d21695927fce491a5ddac0e6a7 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 11 Sep 2023 09:01:30 +0200 Subject: [PATCH 22/46] Revert "Add v_byte min/max" This reverts commit 33392bfa1f397e87bc75352cbc0193d8cb1e0740. --- tips/TIP-0043/tip-0043.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 0fb28d283..348532407 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1789,12 +1789,12 @@ The following table shows the NFT output including the possible fields and their - v_byte Minimum - 483 + v_byte Minimum (TODO: Recalculate) + 0 - v_byte Maximum - 21771 + v_byte Maximum (TODO: Recalculate) + 0
From 7778ddd76e92cb245647d22de9e208a34e5b39a4 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Sep 2023 14:36:55 +0200 Subject: [PATCH 23/46] Format schema tables (no content changes) --- tips/TIP-0043/tip-0043.md | 3684 +++++++++++++++++++++---------------- 1 file changed, 2106 insertions(+), 1578 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 348532407..e3ae9f30e 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -75,676 +75,750 @@ The NFT may contain immutable metadata set upon creation, and a verified `Issuer non-account specific (state controller, governor) unlock conditions and optional features so that the output can be sent as a request to smart contract chain accounts. +
+ NFT Output +
Describes an NFT output, a globally unique token with metadata attached.
+
-
- NFT Output -
- Describes an NFT output, a globally unique token with metadata attached. -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Output Typeuint8Set to value 6 to denote a NFT Output.
Amountuint64The amount of IOTA coins held by the output.
Manauint64The amount of (stored) Mana held by the output.
Native Tokens Countuint8The number of native tokens held by the output.
Native Tokens optAnyOf +
+ Native Token - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
NameTypeDescription
Output Typeuint8 - Set to value 6 to denote a NFT Output. -
Amountuint64The amount of IOTA coins held by the output.
Manauint64The amount of (stored) Mana held by the output.
Native Tokens Countuint8The number of native tokens held by the output.
Native Tokens optAnyOf -
- Native Token - - - - - - - - - - - - - - - - -
NameTypeDescription
Token IDByteArray[38] - Identifier of the native token. -
Amountuint256 - Amount of native tokens of the given Token ID. -
-
-
NFT IDByteArray[32]Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID
Unlock Conditions Countuint8The number of unlock conditions following.
Unlock Conditions atMostOneOfEach -
- 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.
-
-
-
-
- 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 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.
-
-
Return Amountuint64 - Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address. -
-
-
- 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. -
-
-
- 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. -
-
-
Features Countuint8The number of features following.
Features atMostOneOfEach -
- 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.
-
-
-
-
- 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 -
- 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 data. A leading uint8 denotes its length.
-
-
Immutable Features Countuint8The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach -
- 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.
-
-
-
-
- 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 +
Token IDByteArray[38]Identifier of the native token.
Amountuint256Amount of native tokens of the given Token ID.
+
+
NFT IDByteArray[32]Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID.
Unlock Conditions Countuint8The number of unlock conditions following.
Unlock Conditions atMostOneOfEach +
+ Address Unlock Condition + + + + + + + + + + + + + + + +
+ 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 Output ID 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 Output ID that created it.
+
+
+
+
+ Storage Deposit Return Unlock Condition +
Defines the amount of IOTAs used as storage deposit that have to be returned 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 Output ID 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 Output ID that created it.
+
+
Return Amountuint64Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address.
-
+ +
+ Timelock Unlock Condition +
Defines a slot index until which the output can not be unlocked.
+ + + + + + + + + + + + + + + + +
+ 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 +
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.
+ + + + + + + + + + + + + + + + + + + + +
+ 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 Output ID 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 Output ID 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 Countuint8The number of features following.
Features atMostOneOfEach +
+ Sender Feature +
Identifies the validated sender of the output.
+ + + + + + + + + + + + + + + +
+ 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 Output ID 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 Output ID that created it.
+
+
+
+
+ Metadata Feature +
Defines metadata (arbitrary binary data) that will be stored in the output.
+ + + + + + + + + + + + + + + + +
+ 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 +
Defines an indexation tag to which the output can be indexed by additional node plugins.
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 3 to denote a Tag Feature.
Tag(uint8)ByteArrayBinary indexation data. A leading uint8 denotes its length.
+
+
Immutable Features Countuint8The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach +
+ Issuer Feature +
Identifies the validated issuer of the UTXO state machine.
+ + + + + + + + + + + + + + + +
+ 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 Output ID 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 Output ID that created it.
+
+
+
+
+ Metadata Feature +
Defines metadata (arbitrary binary data) that will be stored in the output.
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 2 to denote a Metadata Feature.
Data(uint16)ByteArrayBinary data. A leading uint16 denotes its length.
+
+
## Additional Transaction Syntactic Validation Rules @@ -882,922 +956,1376 @@ that i > k. Hence, an NFT Unlock can only reference an _Unlock_ at a smal The following table shows the NFT output including the possible fields and their specific weight. +
+ NFT Output +
Describes an NFT output, a globally unique token with metadata attached.
+
-
- NFT Output -
- Describes an NFT output, a globally unique token with metadata attached. -
-
- - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Offset +
Offset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
OutputID + key + 3434The ID of the output.
Block ID (included) + data + 4040The ID of the block in which the transaction payload that created this output was included.
Slot Booked + data + 88The index of the slot in which the transaction that created it was booked.
Slot Created + data + 88The index of the slot in which the transaction was created.
+
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Output Type + data + 11Set to value 6 to denote a NFT Output.
Amount + data + 88The amount of IOTA coins held by the output.
Mana + data + 88The amount of (stored) Mana held by the output.
Native Tokens Count + data + 11The number of native tokens held by the output.
Native Tokens optAnyOf +
+ Native Token + + + + - - - - + +
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + +
FieldField typeLength MinimumLength MaximumDescription
OutputIDkey3434The ID of the output.
Block ID (included)data4040The ID of the block in which the transaction payload that created this output was included.
Slot Bookeddata88The index of the slot in which the transaction that created it was booked.
Slot Createddata88The index of the slot in which the transaction was created.
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Token ID + data + 3838Identifier of the native token.
Amount + data + 3232Amount of native tokens of the given Token ID.
-
Fields +
+
+
NFT ID + data + 3232Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID.
Unlock Conditions Count + data + 11The number of unlock conditions following.
Unlock Conditions atMostOneOfEach +
+ Address Unlock Condition + + + + - - - - - - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
NameField typeLength MinimumLength MaximumDescription
Output Typedata11 - Set to value 6 to denote a NFT Output. -
Amountdata88The amount of IOTA coins held by the output.
Manadata88The amount of (stored) Mana held by the output.
Native Tokens Countdata11The number of native tokens held by the output.
Native Tokens optAnyOf -
- Native Token - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Token IDdata3838 - Identifier of the native token. -
Amountdata3232 - Amount of native tokens of the given Token ID. -
-
-
NFT IDdata3232Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID
Unlock Conditions Countdata11The number of unlock conditions following.
Unlock Conditions atMostOneOfEach -
- Address Unlock Condition - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 - Set to value 0 to denote an Address Unlock Condition. -
Address -
- Ed25519 Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 8 to denote an Account Address. -
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 16 to denote an NFT Address. -
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
-
-
- Storage Deposit Return Unlock Condition -
- Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 - Set to value 1 to denote a Storage Deposit Return Unlock Condition. -
Return Address oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 8 to denote an Account Address. -
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 16 to denote an NFT Address. -
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
Return Amountdata88 - Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address. -
-
-
- Timelock Unlock Condition -
- Defines a slot index until which the output can not be unlocked. -
- - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 - Set to value 2 to denote a Timelock Unlock Condition. -
Slot Indexdata88 - Slot index starting from which the output can be consumed. -
-
-
- 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. -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Unlock Condition Typedata11 - Set to value 3 to denote a Expiration Unlock Condition. -
Return Address oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 8 to denote an Account Address. -
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 16 to denote an NFT Address. -
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
Slot Indexdata88 - Slot index starting from which the output can be consumed. -
-
-
Features Countdata11The number of features following.
Features atMostOneOfEach -
- Sender Feature -
- Identifies the validated sender of the output. -
- - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 - Set to value 0 to denote a Sender Feature. -
Sender oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 8 to denote an Account Address. -
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 16 to denote an NFT Address. -
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
-
-
- Metadata Feature -
- Defines metadata (arbitrary binary data) that will be stored in the output. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 - Set to value 2 to denote a Metadata Feature. -
Data Lengthdata22 - Length of the following data field in bytes. -
Datadata18192Binary data.
-
-
- Tag Feature -
- Defines an indexation tag to which the output can be indexed by additional node plugins. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 - Set to value 3 to denote a Tag Feature. -
Tag Lengthdata11 - Length of the following tag field in bytes. -
Tagdata1255Binary indexation data.
-
-
Immutable Features Countdata11The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach -
- Issuer Feature -
- Identifies the validated issuer of the UTXO state machine. -
- - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 - Set to value 1 to denote an Issuer Feature. -
Issuer oneOf -
- Ed25519 Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 0 to denote an Ed25519 Address. -
PubKeyHashdata3232The raw bytes of the Ed25519 address which is a BLAKE2b-256 hash of the Ed25519 public key.
-
-
- Account Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 8 to denote an Account Address. -
Account IDdata3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
- NFT Address - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Address Typedata11 - Set to value 16 to denote an NFT Address. -
NFT IDdata3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the outputID that created it.
-
-
-
-
- Metadata Feature -
- Defines metadata (arbitrary binary data) that will be stored in the output. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameField typeLength MinimumLength MaximumDescription
Feature Typedata11 - Set to value 2 to denote a Metadata Feature. -
Data Lengthdata22 - Length of the following data field in bytes. -
Datadata18192Binary data.
-
-
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Unlock Condition Type + data + 11Set to value 0 to denote an Address Unlock Condition.
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 0 to denote an Ed25519 Address.
PubKeyHash + data + 3232The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 8 to denote an Account Address.
Account ID + data + 3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 16 to denote an NFT Address.
NFT ID + data + 3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
-
v_byte Minimum (TODO: Recalculate)0
v_byte Maximum (TODO: Recalculate)0
-
+
+ +
+ Storage Deposit Return Unlock Condition +
Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Unlock Condition Type + data + 11Set to value 1 to denote a Storage Deposit Return Unlock Condition.
Return Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 0 to denote an Ed25519 Address.
PubKeyHash + data + 3232The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 8 to denote an Account Address.
Account ID + data + 3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 16 to denote an NFT Address.
NFT ID + data + 3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
Return Amount + data + 88Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address.
+
+
+
+ Timelock Unlock Condition +
Defines a slot index until which the output can not be unlocked.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Unlock Condition Type + data + 11Set to value 2 to denote a Timelock Unlock Condition.
Slot Index + data + 88Slot index starting from which the output can be consumed.
+
+
+
+ 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.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Unlock Condition Type + data + 11Set to value 3 to denote an Expiration Unlock Condition.
Return Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 0 to denote an Ed25519 Address.
PubKeyHash + data + 3232The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 8 to denote an Account Address.
Account ID + data + 3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 16 to denote an NFT Address.
NFT ID + data + 3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
Slot Index + data + 88Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address.
+
+
+
Features Count + data + 11The number of features following.
Features atMostOneOfEach +
+ Sender Feature +
Identifies the validated sender of the output.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Feature Type + data + 11Set to value 0 to denote a Sender Feature.
Sender oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 0 to denote an Ed25519 Address.
PubKeyHash + data + 3232The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 8 to denote an Account Address.
Account ID + data + 3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 16 to denote an NFT Address.
NFT ID + data + 3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+
+
+
+ Metadata Feature +
Defines metadata (arbitrary binary data) that will be stored in the output.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Feature Type + data + 11Set to value 2 to denote a Metadata Feature.
Data + data + 38194Binary data. A leading uint16 denotes its length.
+
+
+
+ Tag Feature +
Defines an indexation tag to which the output can be indexed by additional node plugins.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Feature Type + data + 11Set to value 3 to denote a Tag Feature.
Tag + data + 2256Binary indexation data. A leading uint8 denotes its length.
+
+
+
Immutable Features Count + data + 11The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition.
Immutable Features atMostOneOfEach +
+ Issuer Feature +
Identifies the validated issuer of the UTXO state machine.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Feature Type + data + 11Set to value 1 to denote a Issuer Feature.
Issuer oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 0 to denote an Ed25519 Address.
PubKeyHash + data + 3232The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 8 to denote an Account Address.
Account ID + data + 3232The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Address Type + data + 11Set to value 16 to denote an NFT Address.
NFT ID + data + 3232The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it.
+
+
+
+
+
+
+ Metadata Feature +
Defines metadata (arbitrary binary data) that will be stored in the output.
+ + + + + +
Fields + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum + + Description +
Feature Type + data + 11Set to value 2 to denote a Metadata Feature.
Data + data + 38194Binary data. A leading uint16 denotes its length.
+
+
+
+ + + + v_byte Minimum + TODO + + + v_byte Maximum + TODO + # Copyright From 4feeda28c66836a27caca350a961a18cc186714a Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Sep 2023 14:38:59 +0200 Subject: [PATCH 24/46] Format schema tables (no content changes) --- tips/TIP-0043/tip-0043.md | 47 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index e3ae9f30e..3c2939070 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -906,32 +906,31 @@ An NFT Unlock looks and behaves like an Account Unlock, but the re NFT output with the matching `NFT ID`.
- NFT Unlock -
- Points to the unlock of a consumed NFT output. -
+ NFT Unlock +
Points to the unlock of a consumed account output.
- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
NameTypeDescription
Unlock Typeuint8 - Set to value 3 to denote a NFT Unlock. -
NFT Reference Unlock Indexuint16 - Index of input and unlock corresponding to an NFT output. -
+ Name + + Type + + Description +
Unlock Typeuint8Set to value 3 to denote an NFT Unlock.
NFT Reference Unlock Indexuint16Index of input and unlock corresponding to an NFT Output.
An _NFT Unlock_ is only valid if the input in the transaction at index `NFT Reference Unlock Index` is the NFT output From 3aa6c864d7ac59ccbfcd075b3bdbd6f758a953db Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Sep 2023 14:40:58 +0200 Subject: [PATCH 25/46] Fix typo --- tips/TIP-0043/tip-0043.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 3c2939070..1a5b571fd 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -907,7 +907,7 @@ NFT output with the matching `NFT ID`.
NFT Unlock -
Points to the unlock of a consumed account output.
+
Points to the unlock of a consumed NFT Output.
From 279a7dbaf2f6f2f189ce168aede96d6847211360 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 22 Sep 2023 13:51:11 +0200 Subject: [PATCH 26/46] Add new address types --- tips/TIP-0043/tip-0043.md | 1114 ++++++++++++++++++++++++++++++++++++- 1 file changed, 1111 insertions(+), 3 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 1a5b571fd..cb8f21371 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -104,12 +104,12 @@ as a request to smart contract chain accounts. - + - + @@ -131,7 +131,7 @@ as a request to smart contract chain accounts. - + @@ -157,6 +157,7 @@ as a request to smart contract chain accounts.
Mana uint64The amount of (stored) Mana held by the output.The amount of Stored Mana held by the output.
Native Tokens Count uint8The number of native tokens held by the output.The number of different native tokens held by the output.
Native Tokens optAnyOf
Token ID ByteArray[38]Identifier of the native token.Identifier of the native token. Its derivation is defined in TIP-44.
Amount
Address Unlock Condition +
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction.
@@ -255,6 +256,375 @@ as a request to smart contract chain accounts.
+
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
+ Restricted Address + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
+
+
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
@@ -360,6 +730,375 @@ as a request to smart contract chain accounts. +
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
+ Restricted Address + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
+
+
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
@@ -497,6 +1236,375 @@ as a request to smart contract chain accounts. +
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
+ Restricted Address + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
+
+
+ Multi Address + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf +
+ Address with Weight + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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 Output ID 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 Output ID that created it.
+
+
Weightuint8The weight of the unlocked address.
+
+
+
+
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
From a9ea1d1f5c2bc15e716b1b8dad2311990ce3ddf8 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 22 Sep 2023 13:52:22 +0200 Subject: [PATCH 27/46] Update deposit with new address types --- tips/TIP-0043/tip-0043.md | 1946 ++++++++++++++++++++++++++++++++++--- 1 file changed, 1799 insertions(+), 147 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index cb8f21371..7cc28aeed 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -2085,9 +2085,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - OutputID @@ -2096,7 +2093,6 @@ The following table shows the NFT output including the possible fields and their 34 34 - The ID of the output. Block ID (included) @@ -2105,7 +2101,6 @@ The following table shows the NFT output including the possible fields and their 40 40 - The ID of the block in which the transaction payload that created this output was included. Slot Booked @@ -2114,7 +2109,6 @@ The following table shows the NFT output including the possible fields and their 8 8 - The index of the slot in which the transaction that created it was booked. Slot Created @@ -2123,7 +2117,6 @@ The following table shows the NFT output including the possible fields and their 8 8 - The index of the slot in which the transaction was created. @@ -2145,9 +2138,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Output Type @@ -2156,7 +2146,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 6 to denote a NFT Output. Amount @@ -2165,7 +2154,6 @@ The following table shows the NFT output including the possible fields and their 8 8 - The amount of IOTA coins held by the output. Mana @@ -2174,7 +2162,6 @@ The following table shows the NFT output including the possible fields and their 8 8 - The amount of (stored) Mana held by the output. Native Tokens Count @@ -2183,7 +2170,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - The number of native tokens held by the output. Native Tokens optAnyOf @@ -2208,9 +2194,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Token ID @@ -2219,7 +2202,6 @@ The following table shows the NFT output including the possible fields and their 38 38 - Identifier of the native token. Amount @@ -2228,7 +2210,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - Amount of native tokens of the given Token ID. @@ -2244,7 +2225,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it. NFT Address = NFT Address Type || NFT ID. Unlock Conditions Count @@ -2253,13 +2233,13 @@ The following table shows the NFT output including the possible fields and their 1 1 - The number of unlock conditions following. Unlock Conditions atMostOneOfEach
Address Unlock Condition +
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction.
@@ -2278,9 +2258,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2289,7 +2266,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2314,9 +2290,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2325,7 +2298,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2334,7 +2306,6 @@ The following table shows the NFT output including the possible fields and their -
Fields Length Maximum - Description -
Unlock Condition Type 1 1Set to value 0 to denote an Address Unlock Condition.
Address oneOf Length Maximum - Description -
Address Type 1 1Set to value 0 to denote an Ed25519 Address.
PubKeyHash 32 32The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
@@ -2361,9 +2332,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2372,7 +2340,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 8 to denote an Account Address. Account ID @@ -2381,7 +2348,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -2408,9 +2374,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2419,7 +2382,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 16 to denote an NFT Address. NFT ID @@ -2428,7 +2390,595 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it. + + + + + +
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
+ Restricted Address + + + + @@ -2463,9 +3013,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2474,7 +3021,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2499,9 +3045,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2510,7 +3053,6 @@ The following table shows the NFT output including the possible fields and their - @@ -2519,7 +3061,6 @@ The following table shows the NFT output including the possible fields and their -
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
Allowed Capabilities Length + data + 11
Allowed Capabilities + data + 01
Length Maximum - Description -
Unlock Condition Type 1 1Set to value 1 to denote a Storage Deposit Return Unlock Condition.
Return Address oneOf Length Maximum - Description -
Address Type 1 1Set to value 0 to denote an Ed25519 Address.
PubKeyHash 32 32The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key.
@@ -2546,9 +3087,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2557,7 +3095,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 8 to denote an Account Address. Account ID @@ -2566,7 +3103,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -2593,9 +3129,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2604,7 +3137,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 16 to denote an NFT Address. NFT ID @@ -2613,7 +3145,595 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it. + + + + + +
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
+ Restricted Address + + + + @@ -2629,7 +3749,6 @@ The following table shows the NFT output including the possible fields and their -
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
Allowed Capabilities Length + data + 11
Allowed Capabilities + data + 01
8 8Amount of IOTA coins the consuming transaction should deposit to the address defined in Return Address.
@@ -2657,9 +3776,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Unlock Condition Type @@ -2668,7 +3784,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 2 to denote a Timelock Unlock Condition. Slot Index @@ -2677,7 +3792,6 @@ The following table shows the NFT output including the possible fields and their 8 8 - Slot index starting from which the output can be consumed. @@ -2705,9 +3819,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Unlock Condition Type @@ -2716,7 +3827,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 3 to denote an Expiration Unlock Condition. Return Address oneOf @@ -2741,9 +3851,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2752,7 +3859,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 0 to denote an Ed25519 Address. PubKeyHash @@ -2761,7 +3867,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key. @@ -2788,9 +3893,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2799,7 +3901,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 8 to denote an Account Address. Account ID @@ -2808,7 +3909,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -2835,9 +3935,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2846,7 +3943,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 16 to denote an NFT Address. NFT ID @@ -2855,7 +3951,595 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it. + + + + + +
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
+ Restricted Address + + + + @@ -2871,7 +4555,6 @@ The following table shows the NFT output including the possible fields and their -
Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
+ Multi Address + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Addresses anyOf +
+ Address with Weight + + + + + +
Fields + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address oneOf +
+ Ed25519 Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
PubKeyHash + data + 3232
+
+
+
+ Account Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
Account ID + data + 3232
+
+
+
+ NFT Address + + + + + +
Fields + + + + + + + + + + + + + + + + + + + +
+ Field + + Field type + + Length Minimum + + Length Maximum +
Address Type + data + 11
NFT ID + data + 3232
+
+
+
Weight + data + 11
+
+
+
+
+
+
Allowed Capabilities Length + data + 11
Allowed Capabilities + data + 01
8 8Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address.
@@ -2887,7 +4570,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - The number of features following. Features atMostOneOfEach @@ -2913,9 +4595,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Feature Type @@ -2924,7 +4603,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 0 to denote a Sender Feature. Sender oneOf @@ -2949,9 +4627,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -2960,7 +4635,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 0 to denote an Ed25519 Address. PubKeyHash @@ -2969,7 +4643,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key. @@ -2996,9 +4669,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -3007,7 +4677,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 8 to denote an Account Address. Account ID @@ -3016,7 +4685,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -3043,9 +4711,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -3054,7 +4719,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 16 to denote an NFT Address. NFT ID @@ -3063,7 +4727,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -3098,9 +4761,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Feature Type @@ -3109,16 +4769,22 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 2 to denote a Metadata Feature. + + + Data Length + + data + + 2 + 2 Data data - 3 - 8194 - Binary data. A leading uint16 denotes its length. + 1 + 8192 @@ -3146,27 +4812,30 @@ The following table shows the NFT output including the possible fields and their Length Maximum + + + Feature Type - Description + data + 1 + 1 - Feature Type + Tag Length data 1 1 - Set to value 3 to denote a Tag Feature. Tag data - 2 - 256 - Binary indexation data. A leading uint8 denotes its length. + 1 + 255 @@ -3182,7 +4851,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - The number of immutable features following. Immutable features are defined upon deployment of the UTXO state machine and are not allowed to change in any future state transition. Immutable Features atMostOneOfEach @@ -3208,9 +4876,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Feature Type @@ -3219,7 +4884,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 1 to denote a Issuer Feature. Issuer oneOf @@ -3244,9 +4908,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -3255,7 +4916,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 0 to denote an Ed25519 Address. PubKeyHash @@ -3264,7 +4924,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Ed25519 address which is the BLAKE2b-256 hash of the Ed25519 public key. @@ -3291,9 +4950,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -3302,7 +4958,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 8 to denote an Account Address. Account ID @@ -3311,7 +4966,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the Account ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -3338,9 +4992,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Address Type @@ -3349,7 +5000,6 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 16 to denote an NFT Address. NFT ID @@ -3358,7 +5008,6 @@ The following table shows the NFT output including the possible fields and their 32 32 - The raw bytes of the NFT ID which is the BLAKE2b-256 hash of the Output ID that created it. @@ -3393,9 +5042,6 @@ The following table shows the NFT output including the possible fields and their Length Maximum - - Description - Feature Type @@ -3404,16 +5050,22 @@ The following table shows the NFT output including the possible fields and their 1 1 - Set to value 2 to denote a Metadata Feature. + + + Data Length + + data + + 2 + 2 Data data - 3 - 8194 - Binary data. A leading uint16 denotes its length. + 1 + 8192 @@ -3427,11 +5079,11 @@ The following table shows the NFT output including the possible fields and their v_byte Minimum - TODO + 483 v_byte Maximum - TODO + 22704 From ddbc95ce590e1af9d882ae6b546abf8fa618d1c2 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 29 Sep 2023 17:30:41 +0200 Subject: [PATCH 28/46] Use protocol parameter Token Supply in amount rule --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 7cc28aeed..8aad4f86f 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1933,8 +1933,8 @@ as a request to smart contract chain accounts. ### Output Syntactic Validation -- `Amount` field must fulfill the dust protection requirements and must not be `0`. -- `Amount` field must be ≤ `Max IOTA Supply`. +- `Amount` field must fulfill the [storage deposit requirements](../TIP-0047/tip-0047.md) and must not be `0`. +- `Amount` field must be ≤ `Token Supply`. - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 From 278945444366337558e6923ff743c1e86776c554 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 4 Oct 2023 15:43:26 +0200 Subject: [PATCH 29/46] Remove Native Tokens --- tips/TIP-0043/tip-0043.md | 1529 ++----------------------------------- 1 file changed, 48 insertions(+), 1481 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 8aad4f86f..0a65d2b6e 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -1,6 +1,6 @@ --- tip: 43 -title: Non-fungible Token Output Type +title: Non-Fungible Token Output Type description: Support for layer 1 native non-fungible tokens author: Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) @@ -26,7 +26,7 @@ replaces: TIP-18 This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 native **non-fungible tokens** (unique tokens with attached metadata). It was originally introduced in -[TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is a strict extension of the NFT output +[TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the NFT Output of TIP-18. ## Summary of changes compared to TIP-18 @@ -106,42 +106,6 @@ as a request to smart contract chain accounts. uint64 The amount of Stored Mana held by the output. - - Native Tokens Count - uint8 - The number of different native tokens held by the output. - - - Native Tokens optAnyOf - -
- Native Token - - - - - - - - - - - - - - - - -
- 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.
-
- - NFT ID ByteArray[32] @@ -157,7 +121,7 @@ as a request to smart contract chain accounts.
Address Unlock Condition -
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction.
+
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction. Defined in TIP-38 (Address Unlock Condition).
@@ -631,7 +168,7 @@ as a request to smart contract chain accounts.
Storage Deposit Return Unlock Condition -
Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address.
+
Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address. Defined in TIP-38 (Storage Deposit Return Unlock Condition).
@@ -180,450 +144,23 @@ as a request to smart contract chain accounts.
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 Output ID 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 Output ID 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 - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked 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 - - - - - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
-
-
- Multi Address - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked address.
-
-
-
-
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -1110,7 +220,7 @@ as a request to smart contract chain accounts.
Timelock Unlock Condition -
Defines a slot index until which the output can not be unlocked.
+
Defines a slot index until which the output can not be unlocked. Defined in TIP-38 (Timelock Unlock Condition).
@@ -654,450 +191,23 @@ as a request to smart contract chain accounts.
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 Output ID 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 Output ID 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 - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked 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 - - - - - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
-
-
- Multi Address - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked address.
-
-
-
-
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
@@ -1137,7 +247,7 @@ as a request to smart contract chain accounts.
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 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. Defined in TIP-38 (Expiration Unlock Condition).
@@ -1626,7 +309,7 @@ as a request to smart contract chain accounts. - + @@ -555,7 +555,7 @@ as a request to smart contract chain accounts. - +
@@ -1160,450 +270,23 @@ as a request to smart contract chain accounts.
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 Output ID 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 Output ID 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 - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked 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 - - - - - - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 40 to denote a Restricted Address.
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 Output ID 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 Output ID that created it.
-
-
- Multi Address - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
Address Typeuint8Set to value 32 to denote a Multi Address.
Addresses anyOf -
- Address with Weight - - - - - - - - - - - - - - - -
- Name - - Type - - Description -
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 Output ID 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 Output ID that created it.
-
-
Weightuint8The weight of the unlocked address.
-
-
-
-
Allowed Capabilities(uint8)ByteArrayBitflags expressed as a series of bytes. A leading uint8 denotes its length.
+
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
Sender Feature -
Identifies the validated sender of the output.
+
Identifies the validated sender of the output. Defined in TIP-38 (Sender Feature).
@@ -1731,7 +356,7 @@ as a request to smart contract chain accounts.
Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output.
+
Defines metadata (arbitrary binary data) that will be stored in the output. Defined in TIP-38 (Metadata Feature).
@@ -1649,81 +332,23 @@ as a request to smart contract chain accounts.
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 Output ID 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 Output ID 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).
- + @@ -479,7 +511,7 @@ as a request to smart contract chain accounts.
Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output. Defined in TIP-38 (Metadata Feature).
+
Defines a map of key-value pairs that is stored in the output. Defined in TIP-38 (Metadata Feature).
@@ -1758,7 +383,7 @@ as a request to smart contract chain accounts.
Tag Feature -
Defines an indexation tag to which the output can be indexed by additional node plugins.
+
Defines an indexation tag to which the output can be indexed by additional node plugins. Defined in TIP-38 (Tag Feature).
- + @@ -146,6 +146,10 @@ as a request to smart contract chain accounts. 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).
@@ -193,6 +197,10 @@ as a request to smart contract chain accounts. 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).
@@ -272,6 +280,10 @@ as a request to smart contract chain accounts. 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).
@@ -334,6 +346,10 @@ as a request to smart contract chain accounts. 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).
@@ -445,6 +461,10 @@ as a request to smart contract chain accounts. 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).
@@ -587,7 +607,7 @@ NFT output with the matching `NFT ID`.
- + From a63f4c44a392b4b9576523e7f19b074b4c8c874b Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 8 Nov 2023 13:42:44 +0100 Subject: [PATCH 40/46] Remove `Amount <= Token Supply` check --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index e8818dad2..4303f61a1 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -512,8 +512,8 @@ as a request to smart contract chain accounts. ### Output Syntactic Validation -- `Amount` field must fulfill the [storage deposit requirements](../TIP-0047/tip-0047.md) and must not be `0`. -- `Amount` field must be ≤ `Token Supply`. +- `Amount` field must not be `0`. +- `Amount` field must fulfill the [storage deposit requirements](../TIP-0047/tip-0047.md). - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 From 18c549aa25b36b048890e010fc4ffc23ba363040 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Wed, 8 Nov 2023 15:43:28 +0100 Subject: [PATCH 41/46] Remove `Amount` rules (moved to TIP-45) --- tips/TIP-0043/tip-0043.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 4303f61a1..b14436b02 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -512,8 +512,6 @@ as a request to smart contract chain accounts. ### Output Syntactic Validation -- `Amount` field must not be `0`. -- `Amount` field must fulfill the [storage deposit requirements](../TIP-0047/tip-0047.md). - `Native Tokens Count` must not be greater than `Max Native Tokens Count`. - `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 From ca1f9a4b4aab633ec787aede624a89bc2b9e7016 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 20 Nov 2023 09:33:14 +0100 Subject: [PATCH 42/46] Remove outdated Native Token rules --- tips/TIP-0043/tip-0043.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index b14436b02..5c2e03e68 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -512,11 +512,6 @@ as a request to smart contract chain accounts. ### Output Syntactic Validation -- `Native Tokens Count` must not be greater than `Max Native Tokens Count`. -- `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`. - It must hold true that `1` ≤ `Unlock Conditions Count` ≤ `4`. - `Unlock Condition Type` of an Unlock Condition must define one of the following types: - Address Unlock Condition From 2c4e789494f052dc6e43c8e9759dcc0596b49b9a Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 20 Nov 2023 12:50:16 +0100 Subject: [PATCH 43/46] Update feat type prefixes, replace metadata feat --- tips/TIP-0043/tip-0043.md | 82 ++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 5c2e03e68..e112e02a4 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -364,7 +364,7 @@ as a request to smart contract chain accounts.
Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output. Defined in TIP-38 (Metadata Feature).
+
Defines a map of key-value pairs that is stored in the output. Defined in TIP-38 (Metadata Feature).
@@ -1795,7 +420,7 @@ as a request to smart contract chain accounts.
Issuer Feature -
Identifies the validated issuer of the UTXO state machine.
+
Identifies the validated issuer of the UTXO state machine. Defined in TIP-38 (Issuer Feature).
@@ -1900,7 +467,7 @@ as a request to smart contract chain accounts.
Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output.
+
Defines metadata (arbitrary binary data) that will be stored in the output. Defined in TIP-38 (Metadata Feature).
@@ -1818,81 +443,23 @@ as a request to smart contract chain accounts.
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 Output ID 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 Output ID 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).
- + @@ -242,14 +242,14 @@ as a request to smart contract chain accounts. - +
From 7e24ac90d05ce0f1ec9eb49277ef01a09b2bcf9c Mon Sep 17 00:00:00 2001 From: Roman Overko Date: Mon, 16 Oct 2023 10:41:18 +0200 Subject: [PATCH 30/46] Add Roman as author --- tips/TIP-0043/tip-0043.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 0a65d2b6e..187c8588b 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -3,7 +3,9 @@ tip: 43 title: Non-Fungible Token Output Type description: Support for layer 1 native non-fungible tokens author: - Philipp Gackstatter (@PhilippGackstatter) , Levente Pap (@lzpap) + Philipp Gackstatter (@PhilippGackstatter) , + Roman Overko (@roman1e2f5p8s) , + Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards From 0ba49929e05ad9464d8583510ce0d57fdc65bf2f Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 16 Oct 2023 13:15:58 +0100 Subject: [PATCH 31/46] Add Native Token migration notice --- tips/TIP-0043/tip-0043.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 187c8588b..79d6ad222 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -35,6 +35,7 @@ of TIP-18. - Rename "Alias" to "Account". - Add `Mana` field. +- Remove `Native Tokens` field. See [TIP-38 (Native Token Migration)](../TIP-0038/tip-0038.md#native-token-migration) for migration details. # Motivation From dcfe9ba8cd20a5ac41f6a7cdb89779e0a042468c Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 16 Oct 2023 13:16:53 +0100 Subject: [PATCH 32/46] Remove storage deposit table --- tips/TIP-0043/tip-0043.md | 3031 +------------------------------------ 1 file changed, 1 insertion(+), 3030 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 79d6ad222..c9f0ae9aa 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -21,8 +21,7 @@ replaces: TIP-18 2. [Motivation](#motivation) 3. [Building Blocks](#building-blocks) 4. [NFT Output](#nft-output) -5. [Storage Deposit](#storage-deposit) -6. [Copyright](#copyright) +5. [Copyright](#copyright) # Summary @@ -629,3034 +628,6 @@ that i > k. Hence, an NFT Unlock can only reference an _Unlock_ at a smal - `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. -# Storage Deposit - -The following table shows the NFT output including the possible fields and their specific weight. - -
- NFT Output -
Describes an NFT output, a globally unique token with metadata attached.
-
- - - - - - - - - - - - - - - - - -
Offset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
OutputID - key - 3434
Block ID (included) - data - 4040
Slot Booked - data - 88
Slot Created - data - 88
-
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Output Type - data - 11
Amount - data - 88
Mana - data - 88
Native Tokens Count - data - 11
Native Tokens optAnyOf -
- Native Token - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Token ID - data - 3838
Amount - data - 3232
-
-
-
NFT ID - data - 3232
Unlock Conditions Count - data - 11
Unlock Conditions atMostOneOfEach -
- Address Unlock Condition -
Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction.
- - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Unlock Condition Type - data - 11
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
- Restricted Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
Allowed Capabilities Length - data - 11
Allowed Capabilities - data - 01
-
-
-
-
-
-
- Storage Deposit Return Unlock Condition -
Defines the amount of IOTAs used as storage deposit that have to be returned to Return Address.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Unlock Condition Type - data - 11
Return Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
- Restricted Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
Allowed Capabilities Length - data - 11
Allowed Capabilities - data - 01
-
-
-
Return Amount - data - 88
-
-
-
- Timelock Unlock Condition -
Defines a slot index until which the output can not be unlocked.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Unlock Condition Type - data - 11
Slot Index - data - 88
-
-
-
- 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.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Unlock Condition Type - data - 11
Return Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
- Restricted Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
- Multi Address - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Addresses anyOf -
- Address with Weight - - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
Weight - data - 11
-
-
-
-
-
-
Allowed Capabilities Length - data - 11
Allowed Capabilities - data - 01
-
-
-
Slot Index - data - 88
-
-
-
Features Count - data - 11
Features atMostOneOfEach -
- Sender Feature -
Identifies the validated sender of the output.
- - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Feature Type - data - 11
Sender oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
-
-
-
- Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Feature Type - data - 11
Data Length - data - 22
Data - data - 18192
-
-
-
- Tag Feature -
Defines an indexation tag to which the output can be indexed by additional node plugins.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Feature Type - data - 11
Tag Length - data - 11
Tag - data - 1255
-
-
-
Immutable Features Count - data - 11
Immutable Features atMostOneOfEach -
- Issuer Feature -
Identifies the validated issuer of the UTXO state machine.
- - - - - -
Fields - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Feature Type - data - 11
Issuer oneOf -
- Ed25519 Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
PubKeyHash - data - 3232
-
-
-
- Account Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
Account ID - data - 3232
-
-
-
- NFT Address - - - - - -
Fields - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Address Type - data - 11
NFT ID - data - 3232
-
-
-
-
-
-
- Metadata Feature -
Defines metadata (arbitrary binary data) that will be stored in the output.
- - - - - -
Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Field - - Field type - - Length Minimum - - Length Maximum -
Feature Type - data - 11
Data Length - data - 22
Data - data - 18192
-
-
-
-
v_byte Minimum483
v_byte Maximum22704
- # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 813e8d708bfd59ff5db7d4a2e979eb1831801aba Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 17 Oct 2023 14:50:16 +0100 Subject: [PATCH 33/46] Set new NFT Output type prefix (+slot index u32) --- tips/TIP-0043/tip-0043.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index c9f0ae9aa..c31cef5cb 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -96,7 +96,7 @@ as a request to smart contract chain accounts.
Output Type uint8Set to value 6 to denote a NFT Output.Set to value 3 to denote a NFT Output.
Amount
Slot Indexuint64uint32 Slot index starting from which the output can be consumed.
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. Defined in TIP-38 (Expiration Unlock Condition).
+
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. Defined in TIP-38 (Expiration Unlock Condition).
- +
@@ -294,7 +294,7 @@ as a request to smart contract chain accounts.
Slot Indexuint64uint32 Before this slot index, Address Unlock Condition is allowed to unlock the output, after that only the address defined in Return Address.
From a3f16d1e9958c12b87468d4e1297218995624561 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 12:51:49 +0100 Subject: [PATCH 34/46] Remove manually added Table of Contents GitHub and the Wiki both auto-generate a ToC, so it's unnecessary to maintain it. --- tips/TIP-0043/tip-0043.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index c31cef5cb..a26eca4d9 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -15,14 +15,6 @@ requires: TIP-21, TIP-22, TIP-38, TIP-45 and TIP-47 replaces: TIP-18 --- -# Table of Contents - -1. [Summary](#summary) -2. [Motivation](#motivation) -3. [Building Blocks](#building-blocks) -4. [NFT Output](#nft-output) -5. [Copyright](#copyright) - # Summary This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 From fb8da241cd72a715a6eb7df9bfbeb088fd8a9d19 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 12:55:20 +0100 Subject: [PATCH 35/46] Point proto params to TIP-49 --- tips/TIP-0043/tip-0043.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index a26eca4d9..95d30e315 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -24,7 +24,6 @@ of TIP-18. ## Summary of changes compared to TIP-18 -- Rename "Alias" to "Account". - Add `Mana` field. - Remove `Native Tokens` field. See [TIP-38 (Native Token Migration)](../TIP-0038/tip-0038.md#native-token-migration) for migration details. @@ -48,10 +47,9 @@ mechanism, and they can also post requests to other chains. 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 204d7dcce3e9a4c128665165d00f118c2a64a0f1 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 12:59:27 +0100 Subject: [PATCH 36/46] Format Markdown --- tips/TIP-0043/tip-0043.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 95d30e315..ec6e8b378 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -3,9 +3,8 @@ tip: 43 title: Non-Fungible Token Output Type description: Support for layer 1 native non-fungible tokens author: - Philipp Gackstatter (@PhilippGackstatter) , - Roman Overko (@roman1e2f5p8s) , - Levente Pap (@lzpap) + Philipp Gackstatter (@PhilippGackstatter) , Roman Overko (@roman1e2f5p8s) + , Levente Pap (@lzpap) discussions-to: TODO status: Draft type: Standards @@ -19,13 +18,14 @@ replaces: TIP-18 This document defines the NFT output type and transaction validation rules for the IOTA protocol to support Layer 1 native **non-fungible tokens** (unique tokens with attached metadata). It was originally introduced in -[TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the NFT Output -of TIP-18. +[TIP-18](../TIP-0018/tip-0018.md) and the functionality defined in this document is an extension of the NFT Output of +TIP-18. ## Summary of changes compared to TIP-18 - Add `Mana` field. -- Remove `Native Tokens` field. See [TIP-38 (Native Token Migration)](../TIP-0038/tip-0038.md#native-token-migration) for migration details. +- Remove `Native Tokens` field. See [TIP-38 (Native Token Migration)](../TIP-0038/tip-0038.md#native-token-migration) + for migration details. # Motivation From 32214de6484696569ef10c1be04b1fa392b6f043 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 23 Oct 2023 18:11:42 +0100 Subject: [PATCH 37/46] Remove notes --- tips/TIP-0043/tip-0043.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index ec6e8b378..270ad2daa 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -554,12 +554,6 @@ sweep what the NFT owns in the ledger before burning it._ - All Unlock Condition imposed transaction validation criteria must be fulfilled. - All Feature imposed transaction validation criteria must be fulfilled. -## Notes - -- It would be possible to have two-step issuer verification: First NFT is minted, and then metadata can be immutably - locked into the output. The metadata contains an issuer public key plus a signature of the unique `NFT ID`. This way a - smart contract chain can mint on behalf of the user, and then push the issuer signature in a next step. - ## NFT Locking & Unlocking The `NFT ID` field is functionally equivalent to `Account ID` of an account output. It is generated the same way, but it From 0d7cebe2f701fbcfde6f4af414ae8080cd9e0a11 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 26 Oct 2023 11:16:04 +0100 Subject: [PATCH 38/46] Add can destroy nft outputs tx capability rule --- tips/TIP-0043/tip-0043.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 270ad2daa..3e4fe9daa 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -536,8 +536,10 @@ as a request to smart contract chain accounts. - The unlock is valid if and only if all unlock conditions and features present in the output validate. - When a consumed NFT output has a corresponding NFT output on the output side, `Immutable Features` field must not change. -- When a consumed NFT output has no corresponding NFT output on the output side, the NFT it is being burned. Funds and +- When a consumed NFT output has no corresponding NFT output on the output side, the NFT is being burned. Funds and assets inside the burned NFT output must be redistributed to other outputs in the burning transaction. + - The transaction is invalid if an NFT is burned and the _Can destroy NFT Outputs_ flag in the _Transaction + Capabilities_ is **unset**. | :bangbang: Careful with NFT burning :bangbang: | | ---------------------------------------------- | From 60b696c5ef2776a54c7d7cdfbdd09280a79a31c5 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Fri, 3 Nov 2023 09:57:41 +0100 Subject: [PATCH 39/46] Add Anchor Address & update output and unlock type --- tips/TIP-0043/tip-0043.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 3e4fe9daa..e8818dad2 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -86,7 +86,7 @@ as a request to smart contract chain accounts.
Output Type uint8Set to value 3 to denote a NFT Output.Set to value 4 to denote an NFT Output.
Amount
Unlock Type uint8Set to value 3 to denote an NFT Unlock.Set to value 4 to denote an NFT Unlock.
NFT Reference Unlock Index
- - - + + + + + + +
@@ -383,9 +383,41 @@ as a request to smart contract chain accounts. 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.
+
+
@@ -407,7 +439,7 @@ as a request to smart contract chain accounts.
Feature Type uint8Set to value 3 to denote a Tag Feature.Set to value 4 to denote a Tag Feature.
Tag
- - - + + + + + + +
@@ -498,9 +530,41 @@ as a request to smart contract chain accounts. 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.
+
+
From 54b7bed6f199f0d819403cfaaa9baf4ebe2f1482 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 28 Nov 2023 09:23:51 +0100 Subject: [PATCH 44/46] Update tips/TIP-0043/tip-0043.md Co-authored-by: Thibault Martinez --- tips/TIP-0043/tip-0043.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index e112e02a4..683feb20c 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -64,7 +64,7 @@ of the Output ID that created the NFT. The address of the NFT is the conc `NFT ID`. The NFT may contain immutable metadata set upon creation, and a verified `Issuer`. The output type supports all -non-account specific (state controller, governor) unlock conditions and optional features so that the output can be sent +non-anchor specific (state controller, governor) unlock conditions and optional features so that the output can be sent as a request to smart contract chain accounts.
From 39e1ec49af5a5c8e7ee394e1a5777a6ff3dcd9a9 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 21 Dec 2023 14:04:54 +0100 Subject: [PATCH 45/46] Add storage score test vector --- tips/TIP-0043/tip-0043.md | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index 683feb20c..bbc695f4c 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -691,6 +691,67 @@ that i > k. Hence, an NFT Unlock can only reference an _Unlock_ at a smal - `NFT Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an NFT Output with `NFT ID` that refers to the NFT Address being unlocked. +# Test Vectors + +The protocol parameters used in the following test vectors are the same as in +[TIP-49 (Protocol Parameters Hash)](../TIP-0049/tip-0049.md#protocol-parameters-hash). + +## Storage Score + +The following test vector shows the calculation of the storage score according to [TIP-47](../TIP-0047/tip-0047.md). + +NFT Output (json-encoded): + +```json +{ + "type": 4, + "amount": "421000000", + "mana": "0", + "nftId": "0x3163482ff326658dd1bfead468a609bc6b3e74cb2e5094e0da9b63eae7e0166c", + "unlockConditions": [ + { + "type": 0, + "address": { + "type": 8, + "accountId": "0x17432c5a7a672503480241125e3952414a7a320441080c624c264b004e09614a" + } + }, + { + "type": 1, + "returnAddress": { + "type": 0, + "pubKeyHash": "0xed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a" + }, + "amount": "4000000" + } + ], + "features": [ + { + "type": 2, + "entries": { + "iota": "0x322e30" + } + } + ], + "immutableFeatures": [ + { + "type": 2, + "entries": { + "nft": "0x696f7461" + } + } + ] +} +``` + +NFT Output (hex-encoded binary serialization): + +``` +0x0440f317190000000000000000000000003163482ff326658dd1bfead468a609bc6b3e74cb2e5094e0da9b63eae7e0166c02000817432c5a7a672503480241125e3952414a7a320441080c624c264b004e09614a0100ed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a00093d000000000001020104696f74610300322e30010201036e66740400696f7461 +``` + +NFT Output Storage Score: `240`. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From c270107c0e47ad7afa8cd8429bd5fbeb3240cd4d Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Thu, 25 Jan 2024 10:00:17 +0100 Subject: [PATCH 46/46] Update metadata feature description --- tips/TIP-0043/tip-0043.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/TIP-0043/tip-0043.md b/tips/TIP-0043/tip-0043.md index bbc695f4c..b1e6bf009 100644 --- a/tips/TIP-0043/tip-0043.md +++ b/tips/TIP-0043/tip-0043.md @@ -408,7 +408,7 @@ as a request to smart contract chain accounts.
Key (uint8)ByteArrayA 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
Key (uint8)ByteArrayA 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