First and foremost, we want to express our gratitude to the anonymous developer who published the CRC20 protocol on May 14, 2023. This guide is based on their work and our aim is to make it as accessible as possible.
Introduction to the CRC20 Protocol
In May 2023, the Bitcoin Cash upgrade activated the [Cashtoken protocol (https://github.com/bitjson/cashtokens). This major step forward brought in built-in support for both fungible and non-fungible tokens on Bitcoin Cash, moving beyond the earlier Layer-2 token issuance protocols like the Simple Ledger Protocol.
However, compared to well-known existing protocols like ERC20, Cashtoken was missing a few features. Specifically, it didn’t specify the token’s symbol, name, and decimals.
To fill these gaps, the CRC20 protocol was introduced as an extension to the Cashtoken protocol. It adds three important pieces of information for tokens:
Symbol: The abbreviation used to represent the token.
Name: The full name of the token.
Decimals: The number of decimal places the token can be divided into.
We strongly advise all users to conduct their own research and exercise caution when using our service. Your use of this platform is entirely at your own risk.
The Two-Stage Registration Process
The CRC20 protocol uses a two-step process (similar to [ENS]) to register these information fields. This is done to prevent any bad actors from trying to register token information in a hurry.
The first step involves storing a hashed version of the token information on the blockchain. The second step reveals the actual token information.
The Canonical Category
When a token is the first to register a specific symbol, it defines the “canonical category” for that symbol. Simply put, it sets a standard for that symbol. The CRC20 protocol has a method to help users find out the canonical category of a symbol without needing new services. It uses the existing Electrum protocol within the Bitcoin Cash ecosystem.
We hope this guide provides you with a clear understanding of the CRC20 protocol. As we continue to witness the growth and development within Bitcoin Cash, we’re excited about the potential of the CRC20 protocol and look forward to seeing how it will be utilized. Remember, the Bitcoin Cash culture is growing globally, and you are a part of it!
CRC20 Protocol Specification
The CRC20 protocol lays out a specific code requirement for the Genesis Output. This is essentially the starting point of the token.
contract GenesisOutput(pubkey recipientPK, bytes metadata, int symbolLength) {
function reveal(sig recipientSig) {
require(checkSig(recipientSig, recipientPK));
bytes20 symbolHash = hash160(metadata.split(symbolLength)[0]);
bytes25 outLockingBytecode = new LockingBytecodeP2PKH(symbolHash);
require(tx.outputs[0].lockingBytecode == outLockingBytecode);
}
}
In this code:
- ‘pubkey recipientPK’ represents the public key of the recipient.
- ‘bytes metadata’ contains the information about the token.
- ‘int symbolLength’ specifies the length of the symbol.
The ‘metadata’ parameter stores the token’s symbol, decimals, and name in the format ‘metadata[:symbolLength]’, ‘metadata[symbolLength]’ and ‘metadata[symbolLength+1:]’ respectively.
To start a token using this protocol, you need to first create a Genesis Output using a transaction. Once this transaction is confirmed, you can then send the Genesis Transaction. When the Genesis Output is spent, it reveals the token’s symbol, decimals, and name.
The protocol also specifies that the first output of the Genesis Transaction should be a P2PKH (Pay-to-Public-Key-Hash) output. However, the hash of the symbol replaces the Pubkey’s Hash, meaning this UTXO (Unspent Transaction Output) cannot be spent by anyone. This is known as the Symbol UTXO, and it serves to be indexed by the Electrum protocol.
Querying a Symbol’s Canonical Category
To find out the canonical category of a symbol, you can use the Electrum protocol. The Fair Genesis Height of a token is defined as the maximum of H_commit and H_reveal-20, where H_commit and H_reveal are the heights of the transactions committing and revealing the metadata respectively. It’s advised not to have too many blocks between the committing and revealing.
Given a symbol, you can calculate the address of the Symbol UTXO and then use ‘blockchain.address.listunspent’ to find this address’s UTXO list. Sort the list according to the Fair Genesis Height and the Genesis Transaction’s hash ID, and filter out the UTXOs that do not meet certain criteria:
- If this UTXO has not been packaged into a block, filter it out.
- If this UTXO is not the first output of the transaction, filter it out.
- If this UTXO is not an output of the Genesis Transaction, filter it out. This requires checking whether other outputs have the token category attribute, and the Symbol UTXO itself does not need to have the token category attribute.
- Search for the Target Input among the inputs of this Genesis Transaction. If the Target Input cannot be found, the UTXO should be filtered out. The Target Input must satisfy the following three conditions:
-
- It is a [Genesis Input].
-
- It spends a covenant whose code is specified above.
-
- The symbol it reveals is the one we’re querying.
The canonical category of the symbol will be the token category defined by the first UTXO in the filtered list.
It’s important to note that when a reorg (reorganization) occurs in the BCH mainnet => when a reorganization occurs in the Bitcoin Cash blockchain.