Introduction

There are many reasons to add tokens or colored coins, to Bitcoin Cash. Colored coins have been considered as a simple way to add tokens to Bitcoin Cash, e.g. by OP_GROUP, by promoting some Satoshis to become special . Some have considered this to be a hack. Also, it has other issues, such as ensuring a supply limit.

There have been other proposals, which solve some of the problems, but have others. I think the issue is that the current transaction layout is not really designed to handle tokens. It would be handy to be able to have token amounts be more fine-grained than rather coarse Satoshis, too. Also, OP_GROUP violates the idea of Bitcoin script to have a simple can spend result.

Luckily, Satoshi Nakamoto added a version at the beginning of each transaction (currently, there's only one version, 1). Therefore, it would seem more fitting and less hacky to add a new transaction version to handle tokens.

Before continuing, it would be good to list the possible use cases for tokens. The use cases for tokens are infinite, but I figured those could be the most important ones:

Pegged to USD / gold / real goods

As company share (with the possibility of dividends)

Ticket system (e.g. for taking a certain train ride)

Provably pegged to Satoshis (e.g. for allowing sub-Satoshi transactions)

On-chain exchange/trade

The first three are already possible with colored coins, for the next two we'd have to add new opcodes. These opcodes would need to know about tokens, so they should be not available in ordinary transactions.

Adding a new, separate, transaction version would therefore be the cleanest and most extensible approach.

The new version I'm proposing adds an output type and a token name to each transaction output (1+8 bytes bytes per output). 8 bytes per token name, however, assumes that 2^64 different token types suffice, which could be too few. This ensures that the footprint on the blockchain is as small as possible. Keep in mind that "token name" and "amount" can be omitted for some output types.

We also need an additional administrative token utxo map, which stores 0-4 UTXOs for each token name. That's 200 bytes max per token name.

So the blockchain / memory footprint is quite small.

How does the new system work?

Each token has a token name, a number between 1 and 18,446,744,073,709,551,615. Also, each token has a administrative transaction which specifies the condition for who can mint/burn/transact/administrate the token. Once a token name has been claimed by an administrative transaction, rules of it can only be changed by spending this transaction.

The output type can be one of the following:

send Satoshis

send token

admin

mint

burn

transact

Using those types, we divide the new transactions into three types:

Send transaction: To send tokens or satoshis.

Mint/burn transaction: To mint/burn tokens.

Administrative transaction: To manage permissions who can mint/burn/transact/administrate.

Send transaction

A send transaction is like an ordinary Bitcoin transaction, but enforces that the input and output sum for each token name is the same. So if we have 10 Token A and 20 Token B as inputs, we also need to have 10 Token A and 20 Token B as output, or else the transaction is invalid. This means that fees can only be paid in Satoshis, so normal Satoshi input/outputs are allowed as well.

If a "transact" output type is present in the token's administrative transaction, then a properly signed "transact" input must be present as well. This allows the creator of the token restrict how it can be used. Note that a "transact" UTXO won't be removed from the UTXO set when used this way.

Mint/burn transaction

A mint/burn transaction can create tokens out of nothing and destroy tokens into nothingness. To create new tokens, a properly signed "mint" input of that token must be present in the transaction. To destroy tokens, a properly signed "burn" input must be present, respectively. Note that UTXOs of "mint" and "burn" outputs won't leave the UTXO set when used this way, same as with "transact" in the "send transaction" case.

Administrative transaction

An administrative transaction manages who can mint, burn, transact and administrate a token. If a transaction name is already used, a properly signed administrative input of that token must be present and at maximum one administrative output of that token. If no such output is present, it means that the rules specified are set in stone for all eternity and can only be changed by a blockchain hardfork.

It can also specify a mint, burn and transact output for the token, which replaces those in the administrative token UTXO map, or adds or removes them, respectively.

If a transaction contains no mint or burn output, it cannot be minted or burnt, respectively. If it contains no transact output, no additional restrictions on transactions are placed, in addition to those of the output script.

Additional opcodes

The proposed system is already fairly powerful, it allows much stronger administration than the OP_GROUP proposal. However, to allow very advanced features, such as on-chain exchanges, I suggest to add some additional opcodes. These might be very controversial, but they aren't essential to the token transactions themselves, so they can be added much later.

OP_INPUTTOKENNAME : Pops an input index from the stack, pushes the token name of the input at the input index (of the spending transaction) onto the stack

OP_INPUTAMOUNT : Pops an input index from the stack, pushes the amount of the input at the input index (of the spending transaction) onto the stack

OP_OUTPUTTOKENNAME : Pops an output index from the stack, pushes the token name of the output at the output index (of the spending transaction) onto the stack

OP_OUTPUTAMOUNT : Pops an output index from the stack, pushes the amount of the output at the output index (of the spending transaction) onto the stack

OP_OUTPUTSCRIPT : Pops an output index from the stack, pushes the output script of the output at the output index (of the spending transaction) onto the stack

Provably peg Satoshis to a token

To provably peg Satoshis to a token, we'd have to enforce in the mint script that the correct amount of Satoshis are sent to an output script, which can only be spent by provably burning a correct amount of the pegged tokens. This means the pegging would be completely permissionless and anyone could peg and redeem their Satoshis for the tokens. This would also already solve the future problem of Satoshis being to coarse of a unit of payment.

On-chain exchanges

To enable on-chain exchanges, an output of a transaction could require a certain output amount to a certain script (or script hash) be present, such that the amount could only be spent by trading it for another token. Then, either trades are accepted directly, or a broker searches through all unspent trades, finds matches and keeps fees/leftovers of the trade.

Conclusion

I think by adding a special transaction version for token transactions, we can enable a very powerful token system to Bitcoin Cash and by keeping normal Bitcoin transactions and token transaction separate, we don't add unnecessary technical debt. The script for both transaction versions could remain the same; although we could add additional opcodes in the future to enable an even more powerful system.

Technical details

Token transactions differ from normal Bitcoin transactions by adding additional constraints.

If an administrative input/output is present:

Reject if any send token/mint/burn/transact input is present

Reject if admin input (if present) is unspent (if it is the admin UTXO in administrative token UTXO map)

Reject if any input script (satoshi or admin) isn't accepted by the corresponding output script

Reject if any admin/mint/burn/transact output is present which doesn't have a valid admin input with the same token name EXCEPT if no transaction with an admin output with the token name exists

If no administrative input/output is present: