diff --git a/tips/TIP-0052/tip-0052.md b/tips/TIP-0052/tip-0052.md new file mode 100644 index 000000000..ab1ef913d --- /dev/null +++ b/tips/TIP-0052/tip-0052.md @@ -0,0 +1,354 @@ +--- +tip: 52 +title: Multi Address +description: Defines an Address that is owned by multiple other addresses. +author: + Eike Haß (@eike-hass ) , Max Hase (@muXxer) , Philipp Gackstatter + (@PhilippGackstatter) +discussions-to: TODO +status: Draft +type: Standards +layer: Core +created: 2023-09-07 +--- + +# Summary + +This TIP proposes a new Address type to allow multiple addresses to create complex multi-signature-like unlock +conditions for outputs. The address is considered unlocked as soon as the cumulative weight of all unlocked contained +addresses matches or exceeds the configured threshold, where each of the addresses has an assigned weight. + +# Motivation + +The current outputs in Stardust can be unlocked by single addresses, which does not allow outputs to be unlocked by +multiple different entities, except with Ed25519 Threshold Signatures. The latter allows to model multi-control +structures, but it is not transparent who the underlying controlling addresses are and in particular, they do not allow +different Account or NFT Addresses to control an output. The _Multi Address_ introduced in this TIP allows for any other +address type to control an output in a multi-control structure, in various configurations. The W3C DID Specification +distinguishes between [independent control](https://www.w3.org/TR/did-core/#independent-control) and +[group control](https://www.w3.org/TR/did-core/#group-control) which is a useful definition in this context. With the +current approach only independent control can be modelled. Allowing for group control by multiple inspectable +controlling entities might be useful in the following scenarios: + +- Modelling multiple W3C DID controllers. +- Transparent modelling of ownership over funds or assets of entities like organizations. +- Transparent modelling of committees for anchoring (e.g. L2) + +A _Multi Address_ allows for use-cases like: + +- Requiring a signature by a hardware security module (HSM) and a signature by one of two trusted devices through + software to unlock. +- Requiring signatures of a supermajority of controlling parties each of which are an Account to unlock. +- Modelling a 1 of n control structure in addition to a single backup address that has full control. +- Allowing interested parties to inspect the conditions for unlocking, e.g. majority or supermajority. + +# Multi 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 | +| ------------- | -------------------- | -------------- | +| Multi Address | 40 | iota1**9**... | + +The following table shows the serialization of a _Multi 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.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Address Typeuint8Set to value 40 to denote a Multi Address.
Addresses Countuint8The number of addresses following.
Addresses anyOf +
+ Weighted Address +
An Address with an assigned weight.
+ + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
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).
+
+
Weightuint8The weight of the unlocked address.
+
+
Thresholduint16The threshold that needs to be reached by the unlocked addresses in order to unlock the Multi Address.
+ +A _Multi Address_ is a container for other addresses. Each address has weight and the Multi Address contains a threshold +`Threshold` that needs to be reached by the unlocked addresses in order to unlock the Multi Address. + +## Additional syntactic transaction validation rules + +A Multi Address is only valid if all of the following conditions hold: + +- `2 <= Addresses Count <= 10`. +- The addresses must be lexically ordered and unique based on the contained serialized address. +- `Weight >= 1`, for each `Weight` of contained `Addresses`. +- `Cumulative Weight >= Threshold`, where `Cumulative Weight` is the sum of weight of all `Weight`s in `Addresses`. +- `Threshold >= 1`. + +## Unlocks + +### Multi Unlock + +
+ Multi Unlock +
Unlocks a Multi Address with a list of other unlocks.
+
+ + + + + + + + + + + + + + + + + + + + +
+ Name + + Type + + Description +
Unlock Typeuint8Set to value 5 to denote a Multi Unlock.
Unlocks Countuint8The number of unlocks following.
Unlocks anyOf +
+ Signature Unlock +
Unlocks the address derived from the contained Public Key in the transaction in which it is contained in. Defined in TIP-45 (Signature Unlock).
+
+
+ Reference Unlock +
References a previous unlock to support unlocking multiple inputs owned by the same address. Defined in TIP-45 (Reference Unlock).
+
+
+ Account Unlock +
Points to the unlock of a consumed Account Output. Defined in TIP-42 (Account Unlock).
+
+
+ Anchor Unlock +
Points to the unlock of a consumed Anchor Output. Defined in TIP-54 (Anchor Unlock).
+
+
+ NFT Unlock +
Points to the unlock of a consumed NFT Output. Defined in TIP-43 (NFT Unlock).
+
+
+ Empty Unlock +
Used to maintain correct index relationship between addresses and signatures when unlocking a Multi Address where not all addresses are unlocked. Defined in TIP-52 (Empty Unlock).
+
+
+ +#### Additional syntactic transaction validation rules + +A Multi Unlock is only valid if all of the following conditions hold: + +- `2 <= Unlocks Count <= 10`. + +A transaction containing a Multi Unlock is only valid if all of the following conditions hold: + +- If the transaction's `Unlocks` field contains Reference, Account, Anchor or NFT Unlocks, they must point to an Unlock + outside of the Multi Unlock. +- The _Multi Unlock_ must be unique within the subset of _Multi Unlocks_ in the `Unlocks` field of the transaction based + on the serialization of the unlock. +- Any _Signer UIDs_ from _Signature Unlocks_ present in a _Multi Unlock_ are not also present outside a multi unlock. + - Note that this implies that duplicate _Signature Unlocks_ are allowed to be present within multiple distinct Multi + Unlocks. + +#### Additional semantic transaction validation rules + +A transaction containing a Multi Unlock is only valid if all of the following conditions hold: + +- The corresponding Address of the to-be-unlocked input is of type _Multi Address_. +- The `Addresses Count` of the Multi Address and the `Unlocks Count` of the Multi Unlock must match. +- Let the `Cumulative Unlocked Weight` be the sum of weights of the addresses that were successfully unlocked, through + Unlocks other than _Empty Unlocks_, which do not add to this sum. +- `Cumulative Unlocked Weight >= Threshold`. + +### Empty Unlock + +The indices of _Unlocks_ and `Addresses` in a Multi Address must match when unlocking it since it may be configured to +be unlocked by less than the number of addresses it contains. In such cases, the Empty Unlock needs to be used to +maintain correct index relationship between unlocks and addresses in a _Multi Unlock_, to omit the unlocks of the +addresses that are not unlocked. + +For example, consider a Multi Address with 3 addresses with weight 1 and a threshold of 1. The Multi Address can be +unlocked by providing a Multi Unlock with a Signature Unlock of the first address and two subsequent Empty Unlocks. + +
+ Empty Unlock +
Used to maintain correct index relationship between addresses and signatures when unlocking a Multi Address where not all addresses are unlocked.
+
+ + + + + + + + + + + +
+ Name + + Type + + Description +
Unlock Typeuint8Set to value 6 to denote an Empty Unlock.
+ +## Bech32 Representation + +To allow querying the outputs owned by a Multi Address, its Bech32 representation is used, which is computed as follows: + +- Let `Address Hash` be the BLAKE2b-256 hash of the serialized Multi Address. +- Bech32-encode the concatenation of the Multi Address type prefix and the `Address Hash`. + +# Rationale & Alternatives + +Multi Addresses make transparent which other entities control an entity, since they are specified in the address itself. +For a Digital Identity this allows for inspection of which other identities control it and expresses the relationship of +L1 entities. Additionally Multi Addresses enhance the security and recoverability of Accounts by adding support for +multi-factor authentication (e.g. two addresses with weight 1 and a threshold of 2) or backup addresses (e.g. same as +before plus an address with weight 2 whose private key is in cold storage) for outputs on L1. + +**Alternatives** + +- One alternative would be to have two sets of addresses, where one lists the mandatory and one the optional addresses, + the latter of which contains weights and a threshold. While this allows for similar use cases, it is harder to + validate correctness while not being more expressive. +- Rather than introducing Multi Address as an additional type, it would be possible to introduce it as the only type of + address, as it could express all other existing types. However, that exposes every protocol user to the complexity of + Multi Addresses, which may not be desirable. Introducing it as a dedicated type confines the complexity to a smaller + part of the user-facing surface, while still allowing for the same functionality as if it was the only top-level + address type. +- Another alternative is to simplify towards k of n use cases, avoiding the complexity of weights. This excludes some + use cases and a weight-based approach is not significantly more complex than a k of n only approach, which can already + be achieved with Ed25519 Threshold signatures. + +# Test Vectors + +## Bech32 + +```json +{ + "type": 40, + "addresses": [ + { + "address": { + "type": 0, + "pubKeyHash": "0x52fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649" + }, + "weight": 1 + }, + { + "address": { + "type": 0, + "pubKeyHash": "0x53fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649" + }, + "weight": 1 + }, + { + "address": { + "type": 0, + "pubKeyHash": "0x54fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649" + }, + "weight": 1 + }, + { + "address": { + "type": 8, + "accountId": "0x55fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649" + }, + "weight": 2 + }, + { + "address": { + "type": 16, + "nftId": "0x56fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649" + }, + "weight": 3 + } + ], + "threshold": 2 +} +``` + +The resulting Bech32 representation must be: + +``` +iota19qq0ezu97zl76wqnpdxxleuf55gk0eqhscjtdgqm5sqwav6gcarz6vvesnk +``` + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).