Runes
Introduction
Runes is a fungible token protocol for Bitcoin.
It allows to issue/mint/transfer/burn tokens in a utxo1 way by client side validation, which means the Bitcoin itself is not aware of these tokens.
The token owner must be some non-OP_RETURN
tx output, tokens allocated to OP_RETURN
output are considered burned.
The overall process is:
In order to spend(transfer/burn) tokens, the user just spends the corresponding tx output, but the spending details are encoded into the Runestone
structure in a OP_RETURN
output.
In order to issue/mint tokens, the user also has to encode the intent into the Runestone
structure in a OP_RETURN
output, but this time no need to spend any tx output.
A single tx can only host a single RuneStone
object, only the first matching tx output will be effective.
Implementation
Here's the above mentioned Runestone
structure:
The
etching
field is used for issuing tokens.The
edicts
field is used for minting/transfering tokens.The
default_output
field is used for specifying a default output for "unallocated
" tokens.The
burn
field is used for burning tokens.
"unallocated
" deserves some more explanations here.
The tx input specifies the tokens that the user wants to spend, these tokens are initially considered unallocated
unless allocated by RuneStone.edicts
.
Let's go through the implementation details of each operation, more specically: issue/mint/transfer/burn tokens.
Issue tokens
We'll need to make use of the Runestone.etching
field above, let's take a closer look at the Etching
structure:
divisibility
represents the precision of amount, corresponding todecimals
in ERC20.mint
contains 3 optional parameters for minting:deadline
configures the deadline timestamp if specified.limit
configures the max amount of token each single tx can mint if specified.term
configures the termination block if specified.
rune
is an optional id for the token, an internal id will be automatically generated if it'sNone
.The generated id won't conflict with user provided id because of this check.
spacers
is the bit positions of "β’" characters, follow here for an example.symbol
is an optional single character symbol for this token.
Here's an example to issue an token:
Basically one only needs to tweak the runestone object, all other codes are template codes copied from here.
The canonical id
of the issued token is computed here, which uniquely locates the etching tx with block height and tx index within the block.
Mint tokens
We'll need to make use of the Runestone.edicts
field above, let's take a closer look at the Edict
structure:
Basically this structure represents the intention to mint some amount
of the id
token to some tx output
of the minting tx.
In order to mint an existing token, one just needs to set Edict.id
to "u128::from(id) | CLAIM_BIT
", where id
is the canonical id of the issued token, refer here for details.
In order to both issue and mint a token at the same time, one needs to make sure to specify a valid Runestone.etching
and then set Edict.id
to 0
, refer here for details.
Here's an example to mint an existing token:
Here's an example to both issue and mint at the same time:
Transfer tokens
The transfer function is coerced into Runestone.edicts
field.
In order to transfer some token, the user has to spend the corresponding tx output and allocate the tokens with Runestone.edicts
.
Unallocated tokens are either allocated to the tx output specified by Runestone.default_output
if it's a non OP_RETURN
output, or the first non OP_RETURN
output if there is no default, or burned otherwise.
Here's an example to transfer tokens from some tx output:
Basically it's very similar to mint an existing token, except that one has to spend the tx output by specifying corresponding tx_input_to_spend
as tx input.
Burn tokens
In order to burn tokens, one just needs to set Runestone.burn
to true and spend the corresponding tx output.
Here's an example to burn tokens from some tx output:
Basically it's very similar to transfer tokens in that one needs to spend the corresponding tx output, but no need for Runestone.edicts
.
Difference with Inscriptions
No dependency for taproot.
Each operation only needs
1
tx on Bitcoin.Assets are allocated to
utxo
instead ofsat
.
Last updated