diff --git a/tips/TIP-0042/tip-0042.md b/tips/TIP-0042/tip-0042.md new file mode 100644 index 000000000..33dff9c92 --- /dev/null +++ b/tips/TIP-0042/tip-0042.md @@ -0,0 +1,1225 @@ +--- +tip: 42 +title: Account Output Type +description: Defines the IOTA 2.0 Account used to issue blocks onto the network and stake IOTA coins +author: + Philipp Gackstatter (@PhilippGackstatter) , Andrew Cullen (@cyberphysic4l) + +discussions-to: TODO +status: Draft +type: Standards +layer: Core +created: 2023-05-03 +requires: TIP-21, TIP-22, TIP-38, TIP-45 and TIP-47 +replaces: TIP-18 +--- + +# Summary + +The account is the central component of the IOTA 2.0 ledger that enables: + +- Issuance of blocks by burning Mana. +- Staking IOTA coins for the validation of the network. +- Secure ownership of all digital assets on the ledger. + +Its predecessor is the Alias Output, defined in [TIP-18](../TIP-0018/tip-0018.md). However, its functionality is +effectively split between the Account Output and the [Anchor Output](../TIP-0054/tip-0054.md). + +## Summary of changes compared to TIP-18 + +- Add `Mana` field to the `Account`. +- Remove `Native Tokens` field. See [TIP-38 (Native Token Migration)](../TIP-0038/tip-0038.md#native-token-migration) + for migration details. +- Add _Block Issuer Feature_. + - Mana owned by an account with a _Block Issuer Feature_ is bound to that account and can only be moved out with a + delay. + - Accounts with a Block Issuance Credit of less than zero cannot be unlocked until the balance is non-negative. + - The block issuer keys in such a feature have a higher storage deposit. +- Add _Staking Feature_. + - Locks a certain amount of tokens to an account which makes the staker eligible to be selected into the validator + committee. + - The feature has a higher storage deposit than regular features. + +# Motivation + +The goal of IOTA 2.0 is digital autonomy for everyone. Its incentivization model broadly consists of Mana and Staking. +Mana is needed to write to the ledger, while staking is required for the protocol's security. Both of these mechanisms +should follow the principle of Digital Autonomy, and the account is a manifestation of that principle on the IOTA +ledger. + +Accounts are the central component of the IOTA 2.0 ledger and are central to the goal of digital autonomy. In DLTs, one +can distinguish between natural and synthetic actors. Natural actors are those that directly benefit from utilizing the +ledger and thus have a natural incentive to participate, while synthetic actors do not and instead need to be +artificially incentivized to participate. Accounts enable natural actors to accumulate Mana from their IOTA coins and +burn it to issue blocks, making the network feeless for token holders. Account owners can therefore be their own block +issuers rather than having to depend on a synthetic actor to publish their block, thus contributing to digital autonomy. + +Next to block issuance, accounts are used for staking and delegation. Users can stake tokens from their account to +become a validator in the protocol. Other users increase a validator's consensus weight by delegating to a staking +account of their choice. Staking and delegation have low barriers to entry, as anyone can participate in the validation +and no minimum stake is required. Stakers need to lock their tokens in order to become validators, increasing the +commitment to the security of the network. + +The account's keys in unlock conditions can be rotated, while its Account ID stays the same. With its ability to own +other outputs, this means an improvement for both the security as well as the user experience, as a single account can +be used to control all of a user's assets on the ledger. + +In summary, the account is the central component that enables the issuance of blocks, staking for validation and secure +ownership of digital assets. + +# Building Blocks + +## Data Types & Subschema Notation + +Data types and subschemas used throughout this TIP are defined in [TIP-21](../TIP-0021/tip-0021.md). + +## Protocol Parameters + +Protocol parameters used throughout this TIP are defined in [TIP-49](../TIP-0049/tip-0049.md). + +## Transaction Payload + +[TIP-45](../TIP-0045/tip-0045.md) is the basis for output validation in this TIP. + +# Account Locking & Unlocking + +A transaction may consume an output that belongs to an Account Address by transitioning the account output with +the matching `Account ID`. This serves the exact same purpose as providing a signature to unlock an output locked under +a private key backed address, such as Ed25519 Addresses. + +On protocol level, account unlocking is done using a new unlock type, called **Account Unlock**. + +
+ Account Unlock +
Points to the unlock of a consumed Account Output.
+
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Unlock Typeuint8Set to value 2 to denote an Account Unlock.
Account Reference Unlock Indexuint16Index of input and unlock corresponding to an Account Output.
+ +This unlock is similar to the Reference Unlock. However, it is valid if and only if the input of the transaction +at index `Account Reference Unlock Index` is an account output with the same `Account ID` as the one derived from the +`Address` field of the to-be unlocked output. + +Additionally, the Account Unlocks must also be ordered to prevent circular dependencies: + +If the i-th _Unlock_ of a transaction is an _Account Unlock_ and has `Account Reference Unlock Index` set to k, it must +hold that i > k. Hence, an Account Unlock can only reference an _Unlock_ (unlocking the corresponding account) at +a smaller index. + +For example the scenario where `Account A` is locked to the address of `Account B` while `Account B` is in locked to the +address of `Account A` introduces a circular dependency and is not well-defined. By requiring the _Unlocks_ to be +ordered as described above, a transaction consuming `Account A` as well as `Account B` can never be valid as there would +always need to be one _Account Unlock_ referencing a greater index. + +#### Account Unlock Syntactic Validation + +- It must hold that 0 ≤ `Account Reference Unlock Index` < `Max Inputs Count - 1`. + +#### Account Unlock Semantic Validation + +- The address of the unlocking condition of the input being unlocked must be an Account Address. +- The index `i` of the _Account Unlock_ is the index of the input in the transaction that it unlocks. + `Account Reference Unlock Index` must be < `i`. +- `Account Reference Unlock Index` defines a previous input of the transaction and its unlock. This input must be an + _Account Output_ with `Account ID` that refers to the _Account Address_ being unlocked. +- The referenced _Account Output_ must be unlocked. + +# Features + +## Block Issuer Feature + +The presence of a _Block Issuer Feature_ on an account signals that this account can issue blocks - it is a _block +issuer account_. This feature defines the public keys or key hashes which must match the public keys or their hashes +provided in block signatures. A block issued from a block issuer account with a matching block issuer key and a verified +signature will cause Mana to be burned from the account's Block Issuance Credit (BIC) balance. If the balance becomes +negative, the account is locked, meaning its output cannot be spent and it can no longer be used to issue blocks. Once +locked, an account can only be unlocked by allotting enough Mana to the account's BIC balance for it to become +non-negative again. Because the account itself cannot issue such a transaction, the block containing the allotting +transaction must be issued by another account. The feature can only be removed with an expiration mechanism in order to +disincentivize malicious behavior when issuing blocks. Any Mana generated or stored by an issuer account is locked to +that account and can only be transferred by moving it into an Output owned by that account with a sufficiently long +Timelock Unlock Condition. Once that expires, the Mana can be moved anywhere. This two-step process is needed such that +accounts with a large amount of Mana, who can issue a high number of blocks, do not overspend their BIC balance and move +the Mana out of the account before the account would be locked. The account-bound Mana is thus used as a collateral to +disincentivize account owners to overspend their BIC. + +
+ Block Issuer Feature +
Contains the keys with which the account can create block signatures.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 6 to denote a Block Issuer Feature.
Expiry Slotuint32The slot index at which the Block Issuer Feature expires and can be removed.
Block Issuer Keys Countuint8The number of Block Issuer Keys.
Block Issuer Keys anyOf +
+ Ed25519 Public Key Hash Block Issuer Key +
A Block Issuer Key backed by an Ed25519 Public Key.
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Block Issuer Key Typeuint8Set to value 0 to denote an Ed25519 Public Key Hash Block Issuer Key.
Pub Key HashByteArray[32]The raw bytes of the BLAKE2b-256 hash of the corresponding Ed25519 public key.
+
+
+ +### Additional Transaction Syntactic Validation Rules + +- The following conditions must all hold: + - `Block Issuer Keys Count >= 1`. + - `Block Issuer Keys Count <= 128`. + - The `Block Issuer Keys` must be lexically ordered and unique, both based on the following comparison criteria: + - `Block Issuer Key Type` as the first criteria for all Block Issuer Keys. + - `Pub Key Hash` as the second criteria for _Ed25519 Public Key Hash Block Issuer Keys_. + - A _Commitment Input_ must be present in the transaction. + +### Additional Transaction Semantic Validation Rules + +- When a _Block Issuer Feature_ is present in an account on the input or output side of a transaction, the transaction + is valid only if: + - A _Commitment Input_ is present. +- When a _Block Issuer Feature_ is present in an account on the input side of a transaction, the transaction is valid + only if: + - A _Block Issuance Credit Input_ is present whose `Account ID` equals that of the account being transitioned. +- Let `Commitment Index` be the slot index of the _Commitment Input_. +- Let `Past Bounded Slot Index` be given by `Commitment Index + Max Committable Age`. +- When a Block Issuer Feature is present in an account input, the transaction is invalid if that account has + negative Block Issuance Credit. + - The BIC of the account is obtained by resolving the _Account ID_ in the _Block Issuance Credit Input_ to the + account's BIC balance at the time of the commitment identified by _Commitment ID_ from the _Commitment Input_. +- When a Block Issuer Feature is present in an account output and it was not present in the account input, or the + account output represents the initial state of its UTXO state machine, the transaction that contains the account + output is valid, if the following condition holds: + - `Expiry Slot >= Past Bounded Slot Index`. +- When a Block Issuer Feature is present in an account output, the transaction that contains this output is + valid, only if the following condition for Mana in the transaction holds for the account containing the feature: + `Total Mana In - Account In >= Total Mana Out - Account Out`, where: + - `Total Mana In` is the sum of all Mana on the input side of the transaction. + - `Total Mana Out` is the sum of all Mana on the output side of the transaction. + - Both `Total Mana In` and `Total Mana Out` are calculated as defined in + [TIP-39 (Mana Transaction Validation Rules)](../TIP-0039/tip-0039.md#mana-transaction-validation-rules). + - `Account In = Account In_potential + Account In_stored`. + - `Account Out = Account Out_allotted + Account Out_stored + Account Out_locked`. + - `Account In_potential` is the decayed potential Mana generated by the `Amount` of the account input. + - `Account In_stored` is the decayed stored Mana of the account input. + - `Account Out_allotted` is the amount of Mana allotted to the account. + - `Account Out_stored` is the amount of Mana stored in the account. + - `Account Out_locked` is the amount of Mana locked into outputs for which each output satisfies all of the following + conditions: + - The output has a Timelock Unlock Condition containing a + `Slot Index >= Past Bounded Slot Index + Maximum Committable Age`. + - The output has an Address Unlock Condition with the `Account Address` variant containing the input + account's address. +- When a Block Issuer Feature is present in an account input containing `Expiry Slot >= Commitment Index` the + transaction that contains the account output is valid, if all of the following conditions for the account output hold: + - The account is not destroyed on the output side and retains its Block Issuer Feature. + - If either of the following conditions hold: + - The value of `Expiry Slot` on the account output matches the value of `Expiry Slot` on the account input. + - `Expiry Slot >= Past Bounded Slot Index` +- When a Block Issuer Feature is present in an account input with `Expiry Slot < Commitment Index`, the + transaction that contains the corresponding account output is valid, if either of the following conditions hold: + - `Expiry Slot >= Past Bounded Slot Index` + - The Block Issuer Feature is removed in the account output or the account is destroyed. + +### Storage Score + +A Block Issuer Feature incurs additional computational cost in order to maintain the block issuer keys of an account and +due to having to keep them in memory. Due to this, such a feature has an additional storage score offset. The offset of +the feature is the sum of offsets of each contained key: + +- If the contained key is of type `Ed25519 Public Key Hash Block Issuer Key`, the offset is + `Storage Score Parameters::Offset Ed25519 Block Issuer Key`. + +`Storage Score Parameters` are defined in [TIP-49](../TIP-0049/tip-0049.md). + +## Staking Feature + +The presence of a Staking Feature on an account signals that this account wants to participate in the validation +of the network. Accounts with this feature are also referred to as _stakers_ or _registered validators_ and are eligible +to be selected into the validator committee. Refer to [TIP-40](../TIP-0040/tip-0040.md) for details on Committee +Selection and Staking in general. + +The user-chosen amount of IOTA coins in the `Staked Amount` field of the feature is locked until `End Epoch`. The latter +can also be chosen freely, with the constraint that the locked funds must be _unbonded_ before they can be unlocked. +Since a staker has significant control over the rewards of the validator pool, formed by itself and its delegators, this +unbonding period is in place to protect delegators from stakers changing the rules without prior notice. Once a staker +goes into its unbonding period, delegators can be notified that a change is upcoming. Once an account has a Staking +Feature whose `End Epoch` is the current one or has passed, it is no longer considered for validator selection and the +Feature can be removed or updated. In the same transaction, the staker may claim their Mana Rewards for all epochs in +which they were selected to participate in the validator committee. + +
+ Staking Feature +
Stakes IOTA coins to become eligible for committee selection, validate the network and receive Mana rewards.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 7 to denote a Staking Feature.
Staked Amountuint64The amount of IOTA coins that are locked and staked in the containing account.
Fixed Costuint64The fixed cost of the validator, which it receives as part of its Mana rewards.
Start Epochuint64The epoch index in which the staking started.
End Epochuint64The epoch index in which the staking ends.
+ +### Additional Transaction Syntactic Validation Rules + +- The `Amount` in the containing account output satisfies `Amount >= Staked Amount`. +- A _Block Issuer Feature_ must be present in the account. +- A _Commitment Input_ must be present in the transaction. + +### Additional Transaction Semantic Validation Rules + +- Let `Future Bounded Epoch Index` be the epoch index corresponding to the slot index given by + `Commitment Index + Min Committable Age` where `Commitment Index` is the slot index of the commitment input. +- Let `Past Bounded Epoch Index` be the epoch index corresponding to the slot index given by + `Commitment Index + Max Committable Age` where `Commitment Index` is the slot index of the commitment input. +- When a _Staking Feature_ is present in an account output on the input side of a transaction, the transaction that + contains this output is valid only if: + - A _Commitment Input_ is present. +- When a _Staking Feature_ is present in an account output on the output side of a transaction and the feature was not + present on the input side, the transaction that contains this output is valid only if all of the following conditions + hold: + - `Start Epoch` must be set to `Past Bounded Epoch Index`. + - `End Epoch` satisfies `End Epoch >= Past Bounded Epoch Index + Staking Unbonding Period`. +- When a _Staking Feature_ is present in an account output on the input side of a transaction, the transaction that + contains this input is valid only if all of the following conditions hold: + - If `Future Bounded Epoch Index <= End Epoch`, all of the following conditions must hold: + - A _Staking Feature_ must be present on the corresponding account on the output side of the transaction. + - The fields `Staked Amount`, `Start Epoch` and `Fixed Cost` on the feature on the input and the feature on the + output side match. + - One of the following conditions hold: + - `End Epoch` in the _Staking Feature_ on the output is equal to `End Epoch` in the _Staking Feature_ on the + input. + - `End Epoch` satisfies `End Epoch >= Past Bounded Epoch Index + Staking Unbonding Period`. + - If `Future Bounded Epoch Index > End Epoch`, either of the following conditions must hold: + - A _Staking Feature_ is present on the output side and the fields `Staked Amount`, `Start Epoch`, `End Epoch` and + `Fixed Cost` on the feature on the input side and the feature on the output side match. + - One of the following conditions must hold: + - All of the following conditions hold: + - The _Staking Feature_ is removed on the output side of the transaction or the account is destroyed. + - A _Reward Input_ must be present whose `Index` references the account input. + - The Mana amount on the input side of the transaction is increased by at most the amount defined in + [TIP-40 (Validator Rewards)](../TIP-0040/tip-0040.md#validator-rewards). + - All of the following conditions hold: + - A _Staking Feature_ must be present on the corresponding account on the output side of the transaction. + - `Start Epoch` is set to `Past Bounded Epoch Index`. + - `End Epoch` satisfies `End Epoch >= Past Bounded Epoch Index + Staking Unbonding Period`. + - A _Reward Input_ must be present whose `Index` references the account input. + - The Mana amount on the input side of the transaction is increased by at most the amount defined in + [TIP-40 (Validator Rewards)](../TIP-0040/tip-0040.md#validator-rewards). + +### Storage Score + +A Staking Feature incurs additional computational cost in order to compute the total stake of a validator. Due to this, +such a feature has an additional storage score offset, the `Storage Score Parameters::Offset Staking Feature` as defined +in [TIP-49](../TIP-0049/tip-0049.md). + +# Account Output + +The _Account Output_ is a specific implementation of a UTXO state machine. `Account ID`, the unique identifier of an +instance of the deployed state machine, is generated deterministically by the protocol and is not allowed to change in +any future transitions. + +An _Account Output_ represents an account in the ledger with a permanent _Account Address_. The account owns other +outputs that are locked under _Account Address_ and it keeps track of controlled foundries (`Foundry Counter`). + +
+ Account Output +
Describes an account in the ledger which can be used to issue blocks or stake for validation.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Output Typeuint8Set to value 1 to denote an Account Output.
Amountuint64The amount of IOTA coins held by the output.
Manauint64The amount of Stored Mana held by the output.
Account IDByteArray[32]Unique identifier of the account, which is the BLAKE2b-256 hash of the Output ID that created it. Account Address = Account Address Type || Account ID.
Foundry Counteruint32A counter that denotes the number of foundries created by this account.
Unlock Conditions Countuint8The 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. Defined in TIP-38 (Address Unlock Condition).
+ + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Unlock Condition Typeuint8Set to value 0 to denote an Address Unlock Condition.
Address oneOf +
+ Ed25519 Address +
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
+
+
+ Account Address +
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
+
+
+ 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).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
+
+
+
Features Countuint8The number of features following.
Features atMostOneOfEach +
+ Sender Feature +
Identifies the validated sender of the output. Defined in TIP-38 (Sender Feature).
+ + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 0 to denote a Sender Feature.
Sender oneOf +
+ Ed25519 Address +
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
+
+
+ Account Address +
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
+
+
+ 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).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
+
+
+
+ Metadata Feature +
Defines a map of key-value pairs that is stored in the output. Defined in TIP-38 (Metadata Feature).
+ + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 2 to denote a Metadata Feature.
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 printable ASCII characters. A leading uint8 denotes its length.
Value(uint16)ByteArrayAn array of arbitrary binary data. A leading uint16 denotes its length.
+
+
+
+
+ Block Issuer Feature +
Contains the keys with which the account can create block signatures. Defined in TIP-42 (Block Issuer Feature).
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 6 to denote a Block Issuer Feature.
Expiry Slotuint32The slot index at which the Block Issuer Feature expires and can be removed.
Block Issuer Keys Countuint8The number of Block Issuer Keys.
Block Issuer Keys anyOf +
+ Ed25519 Public Key Hash Block Issuer Key +
A Block Issuer Key backed by an Ed25519 Public Key.
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Block Issuer Key Typeuint8Set to value 0 to denote an Ed25519 Public Key Hash Block Issuer Key.
Pub Key HashByteArray[32]The raw bytes of the BLAKE2b-256 hash of the corresponding Ed25519 public key.
+
+
+
+
+ Staking Feature +
Stakes IOTA coins to become eligible for committee selection, validate the network and receive Mana rewards. Defined in TIP-42 (Staking Feature).
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 7 to denote a Staking Feature.
Staked Amountuint64The amount of IOTA coins that are locked and staked in the containing account.
Fixed Costuint64The fixed cost of the validator, which it receives as part of its Mana rewards.
Start Epochuint64The epoch index in which the staking started.
End Epochuint64The epoch index in which the staking ends.
+
+
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. Defined in TIP-38 (Issuer Feature).
+ + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 1 to denote a Issuer Feature.
Issuer oneOf +
+ Ed25519 Address +
An Address derived from an Ed25519 Public Key. Defined in TIP-38 (Ed25519 Address).
+
+
+ Account Address +
An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).
+
+
+ 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).
+
+
+ Restricted Address +
An address that contains another address and allows for configuring its capabilities. Defined in TIP-50 (Restricted Address).
+
+
+
+
+ Metadata Feature +
Defines a map of key-value pairs that is stored in the output. Defined in TIP-38 (Metadata Feature).
+ + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Feature Typeuint8Set to value 2 to denote a Metadata Feature.
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 printable ASCII characters. A leading uint8 denotes its length.
Value(uint16)ByteArrayAn array of arbitrary binary data. A leading uint16 denotes its length.
+
+
+
+
+ +## Additional Transaction Syntactic Validation Rules + +### Output Syntactic Validation + +- It must hold true that `Unlock Conditions Count = 1`. +- `Unlock Condition Type` of an Unlock Condition must define one of the following types: + - Address 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. +- It must hold true that `0` ≤ `Features Count` ≤ `4`. +- `Feature Type` of a Feature in `Features` must define one of the following types: + - Sender Feature + - Metadata Feature + - Block Issuer Feature + - Staking Feature +- It must hold true that `0` ≤ `Immutable Features Count` ≤ `2`. +- `Feature Type` of a Feature in `Immutable Features` must define on 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. +- When `Account ID` is zeroed out `Foundry Counter` must be `0`. +- `Address` of _Address Unlock Condition_ must be different from the account address derived from `Account ID`. + +## Additional Transaction Semantic Validation Rules + +- Explicit `Account ID`: `Account ID` is taken as the value of the `Account ID` field in the account output. +- Implicit `Account ID`: When an account output is consumed as an input in a transaction and the `Account ID` field is + zeroed out, take the BLAKE2b-256 hash of the `Output ID` of the input as `Account ID`. Note that _implicit_ here only + refers to the account ID and has no relationship to the implicit account concept. +- For every non-zero explicit `Account ID` on the output side there must be a corresponding account on the input side. + The corresponding account has the explicit or implicit `Account ID` equal to that of the account on the output side. + +### Consumed Outputs + +Whenever an account output is consumed in a transaction, it means that the account is transitioned into its next state. +The **current state** is defined as the **consumed account output**, while the **next state** is defined as the +**account output with the same explicit `AccountID` on the output side**. + +A transaction that transitions an account is only valid if all of the following conditions hold: + +- `Foundry Counter` field must increase by the number of foundry outputs created in the transaction that map to + `Account ID`. The `Serial Number` fields of the created foundries must be the set of natural numbers that cover the + open-ended interval between the previous and next values of the `Foundry Counter` field in the account output. +- The created foundry outputs must be sorted in the list of outputs by their `Serial Number`. Note, that any foundry + that maps to `Account ID` and has a `Serial Number` that is less or equal to the `Foundry Counter` of the input + account is ignored when it comes to sorting. +- Newly created foundries in the transaction that map to different accounts can be interleaved when it comes to sorting. +- When a consumed account output has _Features_ defined in `Immutable Features` and a corresponding account output on + the output side, `Immutable Features` is not allowed to change. +- If there is no corresponding Account Output with the same _Account ID_ on the output side, the Account is being + destroyed. The transaction is invalid if an Account Output is burned and the _Can destroy Account Outputs_ flag in the + _Transaction Capabilities_ is **unset**. + +### Created Outputs + +- When Issuer Feature is present in an output and explicit `Account ID` is zeroed out, an input with `Address` + field that corresponds to `Issuer` must be unlocked in the transaction. + +### Notes + +- Indexers and node plugins shall map the account address of the output derived with `Account ID` to the regular + address -> output mapping table, so that given an Account Address, its most recent unspent account + output can be retrieved. + +## Implicit Account + +Accounts face a bootstrapping problem since users need to own an Account with a _Block Issuer Feature_ in order to issue +blocks, but cannot create it themselves, since they cannot issue blocks yet. While users are always reliant on +third-parties onboarding users into the network, an implicit account simplifies this onboarding. An _Implicit Account_ +is defined as a Basic Output owned by a special address type, the _Implicit Account Creation Address_. The implicit +accounts only purpose and functionality is to be converted to a regular account. + +Firstly, most third-parties sending funds to users use the simplest possible way to do so, that is, Basic Outputs, be it +exchanges or users creation a simple value transaction in a wallet. Secondly, even if third parties are willing to +create regular accounts for users, they would additionally have to request block issuer keys from the user, which they +would add to a Block Issuer Feature in the newly created Account, in order for the new owner to be able to issue blocks +with it. + +Implicit Accounts address both of these issues. Third-parties can easily create implicit accounts for a user, without +even being aware of it, if that user simply hands them an _Implicit Account Creation Address_ instead of another address +type. An implicit account has an implicitly defined Block Issuer Key, corresponding to the address itself. Thus implicit +accounts can issue blocks by signing them with the private key corresponding to the public key from which the _Implicit +Account Creation Address_ was derived. + +Thus, since implicit accounts are much easier to create than a regular account, and are sufficient to create a full +account from, without having to rely on a third party, the barrier to entry for the network is lowered. + +### Implicit Account Creation Address + +The following table shows the mapping from the address type of the **first byte** to the address type: + +| Address | Type Byte as `uint8` | Bech32 Encoded | +| --------------------------------- | -------------------- | -------------- | +| Implicit Account Creation Address | 32 | iota1**y**... | + +The following table shows the serialization of an _Implicit Account Creation Address_: + +
+ Implicit Account Creation Address +
Defines an address on which an Implicit Account is created when it receives a Basic Output.
+
+ + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 32 to denote an Implicit Account Creation Address.
Pub Key HashByteArray[32]The raw bytes of the Implicit Account Creation Address which is the BLAKE2b-256 hash of the Ed25519 public key.
+ +An _Implicit Account Creation Address_ is structurally the same as an _Ed25519 Address_, except for the _Address Type_, +and thus also backed by an Ed25519 key pair. + +#### Signer UID + +The Signer UID of an _Implicit Account Creation Address_ is the `Pub Key Hash`. + +#### Unlocking + +The address `Address` in a given input at index `Input Index` is unlocked in a transaction if and only if: + +- The `Unlock` in `Unlocks` at `Input Index` is a semantically valid _Unlock_ and is itself or points to a _Signature + Unlock_ whose _Signer UID_ matches the _Signer UID_ of the `Address`. + +#### Storage Score + +- The storage deposit of an _Implicit Account Creation Address_ defines a dedicated Storage Score Offset: + `Storage Score Offset Implicit Account Creation Address`. It is designed to match the Storage Score required for a + minimal Account Output that contains a Block Issuer Feature when contained in a Basic Output. To calculate this + offset, the following Storage Scores are calculated: + - Let `Storage Score Offset Implicit Account Creation Address` be + `Account Output Score - Basic Output Score + Ed25519 Address Score`, where: + - Let `Account Output Score` be the storage score of an Account Output which fulfills the following conditions: + - `Address Unlock Condition` must contain an _Ed25519 Address_. + - `Features Count == 1`. + - A _Block Issuer Feature_ must be present with `Block Issuer Keys Count == 1` and a block issuer key of type + _Block Issuer Key Ed25519_. + - `Immutable Features Count == 0`. + - Let `Basic Output Score` be the storage score of a Basic Output which fulfills the following conditions: + - `Unlock Conditions Count == 1`. + - The unlock condition is of type `Address Unlock Condition` and contains an `Ed25519 Address`. + - `Features Count == 0`. + - Let `Ed25519 Address Score` be the storage score of an `Ed25519 Address`. + - Note: This is currently `0` but is added here for completeness in case this value changes in the future. + +### Creation Syntactic Transaction Validation Rules + +To create an implicit account, a Basic Output is created on the output side of a transaction and the `Address` in the +`Address Unlock Condition` is set to an address of type _Implicit Account Creation Address_. + +- If an output in a transaction contains an unlock condition with an _Implicit Account Creation Address_, that output is + referred to as an `Implicit Account`, and the transaction is valid only if all of the following conditions hold: + - The `Implicit Account` is of type `Basic Output`. + - The `Implicit Account`'s `Unlock Conditions Count == 1`. + - The unlock condition on the `Implicit Account` is of type `Address Unlock Condition`. + +### Conversion Semantic Transaction Validation Rules + +To convert an implicit account to an account, a block can be issued using the implicit account as the block issuer, +containing a transaction that consumes the implicit account on the input side and creates an account output on the +output side. Since an implicit account can issue blocks, some of the requirements of a block issuer account apply to +implicit accounts as well, as defined below. The conversion of an implicit account is a combination of regular account +creation and block issuer feature transition. + +- The account ID of an `Implicit Account` is referred to as `Implicit Account ID` and is the BLAKE2b-256 hash of the + Output ID of the Basic Output that represents the `Implicit Account`. +- If a transaction contains an input with an address unlock condition containing an implicit account address, the + transaction is only valid if all of the following conditions hold: + - A valid `Account` Output is created on the output side, for which all of the following conditions hold: + - The account must be a valid account creation, except that the `Account ID` of the `Account` must be set to the + `Implicit Account ID` instead of being zeroed out. + - The `Account` must have a Block Issuer Feature and it must pass semantic validation as if the implicit account + contained a Block Issuer Feature with its `Expiry Slot` set to the maximum value of slot indices and the feature + was transitioned. + - No other Implicit Account Creation Address is present on the input side of the transaction. + +### Implicit Account Block Issuance + +An implicit account can issue blocks by using the `Pub Key Hash` of the _Implicit Account Creation Address_ itself as an +_Ed25519 Public Key Hash Block Issuer Key_. Therefore, the block's signature must contain the public key from which the +`Pub Key Hash` was derived from and the signature must be computed from the corresponding private key. + +# Migration + +## Alias to Account Conversion + +TODO: Describe when Alias Outputs are converted to Accounts and Anchor Outputs, respectively. + +~~_Alias Outputs_ in Stardust-based networks are converted to _Account Outputs_. Account Outputs' BIC balance is set to +`0`.~~ + +## Block Issuer Accounts + +Since IOTA 2.0 requires Accounts with a Block Issuer Feature to issue blocks and Stardust-based networks do not have +these, a migration procedure is required so the network can be bootstrapped. Users can add a serialized Block Issuer +Feature to an _Alias Output_ which is converted to an _Account Output_ with a Block Issuer Feature and the Metadata +Feature is removed from the output. This transition is only done if all of the following conditions hold: + +- The _Alias Output_'s `Amount` is at least `Storage Score Parameters::Storage Cost * Account Output Score`, with the + latter defined in [Implicit Account (Storage Score)](#storage-score-2), except that the `Block Issuer Keys Count` of + the output for the deposit calculation must be set to the value of the `Block Issuer Keys Count` read from the + serialized Block Issuer Feature in the to-be-converted _Alias Output_. +- The serialized Block Issuer Feature is prefixed with the ascii-encoded string `BlockIssuerFeature`, which is + `[0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65]` in hex + encoding, expressed as a list in JSON. +- The Block Issuer Feature must pass syntactic validation. + +If not all conditions hold, the converted Account Output will contain the Metadata Feature untouched. + +Note: It is recommended to set the `Expiry Slot` to the maximum value of a `uint32`. + +# Rationale & Alternatives + +## Implicit Accounts + +The rationale for having implicit accounts is that first-time users in a network usually receive funds in Basic Outputs +rather than Account Outputs. This leaves them unable to issue blocks since an Account with a Block Issuer Feature is +required to do so. Implicit Accounts give those users a permissionless way to create their account with the only +requirement being owned funds in an output. + +Implicit Account Creation Address is a separate type of address rather than a +[capability](../TIP-0050/tip-0050.md#capability-flags) because it implies many of the capability flags but also has +additional non-trivial transaction validation rules that don't fit together with the other boolean flags that are only +concerned about one aspect of transaction validity. It would also have implications for address validity. For instance, +it would be invalid for an NFT Address to have the flag for implicit account creation set. Other capability flags do not +have implications for address validity. Moreover, the implicit account creation address can only be used in a very +limited context, i.e. within an Address Unlock Condition in a Basic Output. These reasons warrant a separate address +type. + +### Allowed Unlock Conditions and Features + +Features in implicit accounts are allowed to enable more seamless implicit account creation. The more permutations of +Unlock Conditions and Features are allowed in Implicit Accounts, the more seamless implicit account creation becomes. +None of the Basic Output features are problematic in implicit accounts, hence they are allowed. + +On the other hand, Storage Deposit Return, Timelock and Expiration Unlock Conditions are not useful for implicit account +creation, so they are disallowed: + +- Storage Deposit Return: Having to return the funds on an implicit account to the sender means the full account that + needs to be transitioned to, must be funded by other means. In a typical onboarding scenario these funds do not exist, + so SDRUC would only make it more complicated to create the full account. +- Timelock: Would be harmless, but timelocks are not permitted on full accounts either. It would be odd to be able to + use the implicit account to issue blocks (because the accounts ledger does not respect the timelock) but not be able + to do the implicit account conversion until the timelock expires. +- Expiration: To fulfil syntactic rules, the `Return Address` would not be an implicit account creation address, but + some other regular address. Then for the `Address`, the Basic Output would be an implicit account, but for the + `Return Address` it would be a regular output, which is very undesirable behavior, since the `Return Address` would + not have to respect the account-locked mana rules, which would open an attack vector. + +## Expiry Slot and End Epoch + +One recurring pattern that applies to Staking and Block Issuer Features is the use of the maximum value of slot or epoch +indices. The max value can be used to express that such features do not have an expiration set, applying to the +`End Epoch` and `Expiry Slot`, respectively. + +Typically, one would want to set these features to not expire and only reduce the value to the closest possible one, +once removal of the feature is desired. + +# 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). + +Account Output (json-encoded): + +```json +{ + "type": 1, + "amount": "200000000", + "mana": "333000000", + "accountId": "0xe8494fe353f99783d3771c78798e1e839e649310513770fc6dc974fe53cf1a86", + "foundryCounter": 0, + "unlockConditions": [ + { + "type": 0, + "address": { + "type": 0, + "pubKeyHash": "0xed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a" + } + } + ], + "features": [ + { + "type": 0, + "address": { + "type": 0, + "pubKeyHash": "0xed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a" + } + }, + { + "type": 6, + "expirySlot": 888, + "blockIssuerKeys": [ + { + "type": 0, + "pubKeyHash": "0x295409de79016133647d4078cb01618a4ba018eb74ff613138d8ff8dc05de73c" + }, + { + "type": 0, + "pubKeyHash": "0x868f4c6ef7b5b1d55838cbfb8ae4f3a9776c53cdd3e3d33000094d72acab5a2f" + } + ] + }, + { + "type": 7, + "stakedAmount": "150000000", + "fixedCost": "400", + "startEpoch": 25, + "endEpoch": 4294967295 + } + ], + "immutableFeatures": [ + { + "type": 2, + "entries": { + "iota": "0x322e30" + } + } + ] +} +``` + +Account Output (hex-encoded binary serialization): + +``` +0x0100c2eb0b00000000402dd91300000000e8494fe353f99783d3771c78798e1e839e649310513770fc6dc974fe53cf1a8600000000010000ed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a030000ed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a06780300000200295409de79016133647d4078cb01618a4ba018eb74ff613138d8ff8dc05de73c00868f4c6ef7b5b1d55838cbfb8ae4f3a9776c53cdd3e3d33000094d72acab5a2f0780d1f00800000000900100000000000019000000ffffffff01020104696f74610300322e30 +``` + +Account Output Storage Score: `621`. + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).