-
Notifications
You must be signed in to change notification settings - Fork 74
Native tokens RFC WIP #416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
89c6be3
f0e5be6
69fdff0
6d2b9e6
8d53bb4
f802cf8
29964c5
04d7d6c
5981435
73c4031
8be5d64
a1c8cba
3cef20d
e7138dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,207 @@ | ||
| # Aeternity Native Tokens | ||
|
|
||
| ## Overview | ||
|
|
||
| We need to distinguish between a specification of a token, and a | ||
| countable amount of the token. In this document we use **ANT** | ||
| (Aeternity Native Token) to represent the specification, and **native | ||
| token** or simply **token** to represent the countable asset. | ||
|
|
||
| Informally, when you need a new type of token for whatever purpose, | ||
| you create an ANT describing the token, and then you can mint new | ||
| tokens and start sending them to accounts. | ||
|
|
||
| Owners of the tokens can spend them to other accounts, or trade them | ||
| (atomically) for other assets with other accounts. If tokens are no | ||
| longer wanted you can burn them. | ||
|
|
||
| Only the owner of the ANT can mint new tokens. Only the owner can | ||
| finalize the ANT, preventing more minting. An ANT can also be | ||
| created with a final supply already minted. | ||
|
|
||
| An ANT can only be destroyed (TODO: design decision) if the total | ||
| token supply of the ANT is zero (i.e., all tokens are burnt). | ||
|
|
||
| Aeons are not part of the ANT system. There are no consensus | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. *Aettos |
||
| controlled exchange rate between tokens and aeons. Fees cannot be | ||
| payed by native tokens, but only by aeons. Other services could be | ||
| payed for with tokens (e.g., contracts accepting tokens as | ||
| payment). (TODO: Design decision: Should oracles be allowed to set | ||
| fees in tokens?) | ||
|
|
||
| The owner of a token can decide to govern the behavior of the tokens | ||
| by connecting a contract when an ANT is created. The contract must | ||
| provide entrypoints according to a specified ACI where one or many of | ||
| the primitive operation (spend, trade, mint, etc) is called to decide | ||
| if the operation is allowed or not. | ||
|
|
||
| ## Definitions | ||
|
|
||
| Note that when *account* is used below, the account can belong to a | ||
| contract, the account may be an oracle, etc. | ||
|
|
||
| An Aeternity Native Token (ANT): | ||
| - is a *specification* of tokens | ||
| - is a *first class object* on the chain with its own state tree | ||
| - is *created* by an account which becomes its owner | ||
| - *governs the behavior* when interacting with tokens (trading, sending, minting, etc). | ||
| - can have a *connected contract* to govern the handling of its tokens | ||
|
|
||
| A native token: | ||
| - has an ANT describing its behavior. | ||
| - is *countable* | ||
| - is recorded as a *balance in the account* that owns it (in the accounts state tree). | ||
| - is *mintable* (`mint`) | ||
| - is *transferable* (`spend`, `trade`) | ||
| - is *destroyable* (`burn`) | ||
|
|
||
| ## Tokens state tree | ||
|
|
||
| The tokens state tree contains ANT objects. Tokens are stored in the | ||
| accounts state tree in the owner's account. | ||
|
|
||
| ### ANT object | ||
|
|
||
| The token id is determined by the creator's account and nonce. | ||
| ``` | ||
| id := Blake2b(<CreatorPubkey><CreateTxNonce>) | ||
| ``` | ||
| where `Blake2b` is the 256 bit hash. The [API | ||
| serialization](../node/api/api_encoding.md) of an ANT id is tagged by | ||
| `nt_` | ||
|
|
||
| The ANT contains the fields: | ||
| - `creator` - The account id of the creator | ||
| - `meta_data` - A byte array field, uninterpreted, but under consensus | ||
| - `contract` - A contract id if there is a governing contract, or the empty binary otherwise | ||
| - `total_supply` - A counter of the currently available amount of the token | ||
| - `parent` - The id of the parent ANT (TODO: Hierarchical tokens?) | ||
| - `final` - If the ANT is final, new tokens cannot be minted. Can flip to true, but never back to false again. | ||
|
|
||
| The `meta data` is an uninterpreted string but token minters are | ||
| encouraged to use the following json object: (TODO: Extend). The | ||
| intention of the meta data is to have a consensus controlled way of | ||
| providing information usable by tools (e.g., displaying an intended | ||
| denominator, a display name, etc). | ||
| ``` | ||
| { | ||
| "type" : "object", | ||
| "properties": { "name": {"type" : "string"}, | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and an identifier... sure, that could be the hash of the string, but it has to be the unique thing to work with in the contract. We could even allow a string of 3 unique characters, like in valutas... that's limited, but makes contracts very readable. |
||
| } | ||
| ``` | ||
|
|
||
| A contract governing the usage of tokens must have a non-empty subset | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but there must not be a governing contract? |
||
| of the following ACI: | ||
|
|
||
| ``` | ||
| spend(recipient : address, payload : Type) : boolean | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the payload type here? A binary string, I guess, like in normal spend?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it probably could be something ABI encoded. Just as in oracles. 🤔 |
||
| trade([(from : address, to: address, Option(token : address))], payload : Type) : boolean | ||
|
Comment on lines
+98
to
+99
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. amounts? |
||
| mint(amount: integer) : boolean | ||
| burn(amount : integer) : boolean | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| ``` | ||
|
|
||
| The contract may contain other endpoints as well, but at least one of | ||
| the entrypoints above must be implemented. The contract can only be | ||
| attached at create time. | ||
|
|
||
| If a contract is provided, any transaction (spend, trade, mint, burn) | ||
| would call this contract and the transaction only goes through if the | ||
| result of the corresponding contract call returns true. Any other | ||
|
Comment on lines
+108
to
+110
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that in the case of a trade there will be one contract call per unique ANT used in the trade. What if different ANTs share the same contract? |
||
| transaction using the token (such as contract call) would only be | ||
| executed if a call to spend returns true. (TODO: Decide how this plays | ||
| with contract calls that tries to pass tokens as value, etc). | ||
|
Comment on lines
+108
to
+113
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Who pays for the gas (the caller of the transaction presumably)? This means that all transactions dealing with tokens need gas/gas price fields. |
||
|
|
||
| Note that the `final` field in the ANT takes precedence over the | ||
| governing contract. If the ANT is final, no minting can occur. (TODO: | ||
| Perhaps the contract should have a `finalize` endpoint as well?) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
|
||
| ## ANT transactions | ||
|
|
||
| ### ANT create transaction (`ant_create_tx`) | ||
|
|
||
| The ANT create transaction takes the argument: | ||
| - Meta data : string | ||
| - Amount | ||
| - Recipient | ||
| - Final | ||
| - Contract | ||
| - Parent (TODO: Hierarchical tokens?) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does hierarchical tokens mean? |
||
|
|
||
| The `amount` is the number of tokens to mint at create time. Set to | ||
| `0` if none should be minted. This can for example be combined with | ||
| setting the `final` argument to true, thereby immediately minting all | ||
| tokens that will ever exist. | ||
|
|
||
| The `recipient` is the recipient of the minted tokens in `amount`. If | ||
| not provided, the tokens are given to the creator's account. | ||
|
|
||
| The `parent` is a pointer to a parent token for hierarchical | ||
| tokens. (TODO: hierarchical tokens?) | ||
|
|
||
| ### ANT finalize transaction (`ant_finalize_tx`) | ||
|
|
||
| The ANT finalize transaction takes the arguments: | ||
| - owner | ||
| - ANT | ||
|
|
||
| The finalize transaction can only be submitted by the actual owner, | ||
| and only if the ANT is not already finalized. | ||
|
|
||
| ### ANT mint transaction (`ant_mint_tx`) | ||
| The ANT mint transaction takes the argument: | ||
| - owner | ||
| - ANT | ||
| - amount | ||
| - recipient | ||
| - final | ||
|
|
||
| Only the `owner` can mint new tokens, but it can pass the minted | ||
| tokens to a recipient. If `final` is set to true, the ANT will be | ||
| finalized after the new tokens are minted. | ||
|
|
||
| ### ANT destroy transaction | ||
| TODO: Should we be able to destroy an ANT that has a `total_supply` of 0? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would be the incentive for the owner to destroy the ANT? Also it seems unlikely that the total supply will ever reach 0 (case-in-point: aeternity token migration). |
||
|
|
||
|
|
||
| ## Token transactions | ||
|
|
||
| ### Token trade transaction | ||
| The token trade transaction takes the argument: | ||
| - trades | ||
|
|
||
| The `trades` field contans a non-empty list of token transfers. A | ||
| single token transfer consists of the fields: | ||
|
|
||
| - Sender | ||
| - Receiver | ||
| - Amount | ||
| - An ANT id | ||
|
|
||
| This construct makes it possible to atomically perform complicated | ||
| trade operations involving more than one ANT and also aeons (TODO: How | ||
| to signal that a trade concerns aeons) between multiple parties. | ||
|
|
||
| The transaction must be signed by all senders. (TODO: Should we use | ||
| some alternative multisig format here?). | ||
|
|
||
|
|
||
| ### Token burn transaction | ||
|
|
||
| The token burn transaction contains the fields | ||
| - Account (owner of the tokens, not necessarily of the ANT) | ||
| - Amount | ||
| - ANT | ||
|
|
||
| Destroy an `Amount` of `ANT` tokens currently owned by the | ||
| `account`. The burned amount is also counted from the `total_supply` | ||
| in the ANT object. | ||
|
|
||
| ### Other transactions on tokens | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this PR should probably include the protocol changes to these other transactions as well |
||
|
|
||
| Tokens can also be transfered from one account to another through any | ||
| other transaction that can pass an amount. You can: | ||
| - spend tokens through the `spend_tx` | ||
| - pass tokens as value in a `contract_call_tx` or `contract_create_tx` | ||
| - pass tokens as value in contract calls in a smart contract. | ||
|
Comment on lines
+205
to
+206
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider allowing multiple currencies (for instance, some tokens + a tip in aeons). |
||
| - spend tokens as query fees in `oracle_query_tx` (TODO: Might be a future extension). | ||
Uh oh!
There was an error while loading. Please reload this page.