bsv20.com
WhitepaperToken standard for Bitcoin SV

BSV-20

“First-is-first” style fungible token specification

First is first deployment and minting allows for a single use-case where a token is publicly mintable, by anyone, outside of the control of any token issuer.

4 min readContent type application/bsv-20Based on BRC-20
Deployop: "deploy"

Claim a ticker with its maximum supply, mint limit and decimals. The first deployment wins.

Mintop: "mint"

Anyone mints up to the limit per inscription until the maximum supply is reached.

Transferop: "transfer"

Spend the token UTXO into outputs carrying transfer inscriptions, like spending satoshis.

Abstract

This proposal introduces a fungible token standard based off of the BRC-20 [1] standard on BTC introduced by Domo (here) but customized to work on BSV (Bitcoin Satoshi Vision). In order to avoid confusion with the BRC-20 standard on BTC, we are calling this standard BSV-20.

Motivation

The purpose of this proposal is to provide a standard that offers the same functionality that BRC-20 on BTC offers, but works on BSV instead of BTC. A guiding motivation behind this standard proposal is to try and keep the standard as simple as possible.

Specification

This specification is meant to be as similar to the BTC BRC-20 standard as possible, so it also follows the first is first approach. In order to deploy or mint a token, the process is almost identical to the protocol on BTC: you would create a transaction output with the data fields below, and transactions are indexed on a “first is first” approach, with duplicates or overflows being invalid and ignored. The main difference between BSV-20 (this protocol) and the BRC-20 protocol (on BTC) is:

A content type of application/bsv-20 is used in place of text/plain. This change means a BSV-20 indexer does not need to parse every text inscription to test for embedded JSON content (and failing most of the time) in order to determine if an inscription is BSV-20 related.

Deploy

Notes

  • The first deployment of a ticker is the only one that has claim to the ticker. Tickers are not case sensitive (DOGE = doge).
  • If two events occur in the same block, prioritization is assigned via the order they were confirmed in the block (first to last).
  • The first mint to exceed the maximum supply will receive the fraction that is valid (for example: 21,000,000 maximum supply, 20,999,242 circulating supply, and a 1,000 mint inscription = 758 balance state applied).
  • The number of decimals cannot exceed 18 (default).
  • The maximum supply cannot exceed uint64_max.

In order to deploy a BSV-20 token, you must make sure that the token ticker has not already been deployed, and then create a TXO with the following data present in the script. It does not matter whether this UTXO is spendable or not.

KeyRequiredDescription
pYesProtocol: bsv-20
opYesOperation: deploy
tickYesTicker: 4 letter identifier of the BSV-20
maxYesMax supply: set max supply of the BSV-20
limNoMint limit: if letting users mint to themselves, limit per ordinal. If omitted or 0, the mint amount is unlimited.
decNoDecimals: set decimal precision, default to 0
Example. To deploy the ordi token, you would create an inscription with the following JSON (with content type application/bsv-20):
application/bsv-20
{
"p": "bsv-20",
"op": "deploy",
"tick": "ordi",
"max": "21000000",
"lim": "1000"
}
ORDI is on chain
Deployed in block 792,686 on May 20, 2023 by 1Gh8w…yDzN5deploy transaction
View ORDI

Mint

In order to mint tokens of a specific BSV-20 token, you must make sure that the token ticker has already been deployed, and then create a UTXO with 1 satoshi value, with the following data present in the script. This UTXO should be spendable in order for you to be able to transfer these minted tokens.

KeyRequiredDescription
pYesProtocol: bsv-20
opYesOperation: mint
tickYesTicker: 4 letter identifier of the BSV-20
amtYesAmount to mint: states the amount of the BSV-20 to mint. Has to be less than lim above, if stated
Example. To mint ordi tokens, you would create an inscription with the following JSON (with content type application/bsv-20):
application/bsv-20
{
"p": "bsv-20",
"op": "mint",
"tick": "ordi",
"amt": "1000"
}
ORDI minted so far21,000,000 of 21,000,000
Fully minted: further mints are invalid and move no tokens.

Transfer

Tokens in BSV-20 are held in UTXOs, similar to native bitcoins. This is different from BRC-20, which holds balance in an account model. In order to transfer tokens, you spend that specific UTXO and create new outputs the same way you spend regular satoshis, but the output(s) must contain transfer inscriptions.

If more tokens are transferred in the output(s) than are available in the input(s), then the transaction is considered invalid and the tokens are burned. If fewer tokens are created in the outputs than are available in the input(s), the unallocated tokens are burned.

Using the same procedure as regular satoshi transfers allows us to benefit from the parallelisation Bitcoin benefits from, where you can split a specific UTXO with a large amount into smaller UTXOs and spend those in parallel (the same way you could exchange a $100 bill into $1 bills and spend those in parallel), with no sequential bottlenecks that something like ERC-20 (Ethereum) suffers from.

KeyRequiredDescription
pYesProtocol: bsv-20
opYesOperation: transfer
tickYesTicker: 4 letter identifier of the BSV-20
amtYesAmount of tokens transferred in this output
Example. To transfer the ordi tokens that you minted as shown above, you would create a transaction spending the minting UTXO (providing the signature and public key normally used to spend the P2PKH script), with one or more outputs carrying similar scripts and the following JSON (with content type application/bsv-20):
application/bsv-20
{
"p": "bsv-20",
"op": "transfer",
"tick": "ordi",
"amt": "1000"
}
One transfer transaction: a mint of 1,000 ORDI split into three outputs
Inputs
1,000 ORDI
The mint UTXO
signature + public key
Outputs
  • 100 ORDItransfer
    inscription({"p":"bsv-20","op":"transfer","tick":"ordi","amt":"100"})
  • 500 ORDItransfer
    inscription({"p":"bsv-20","op":"transfer","tick":"ordi","amt":"500"})
  • 400 ORDItransfer
    inscription({"p":"bsv-20","op":"transfer","tick":"ordi","amt":"400"})
100 + 500 + 400 = 1,000: every token in the input is allocated, so nothing is burned.

Grandfathering in older inscriptions

There are several inscriptions on the blockchain prior to the release of this spec that use text/plain as the content type instead of application/bsv-20. We will continue to index these up to block height 793000. Starting with this block, BSV-20 inscriptions must have a content type of application/bsv-20 to be considered valid by indexers.

Implied transfers deprecated

V1 of this spec supported the functionality of implied transfers. An implied transfer was achieved by transferring a mint or transfer inscription without the creation of a new transfer inscription. This functionality was put in place to support users who transferred their inscriptions before there were any publicly accessible tools to create transfer inscriptions, and was always a temporary solution. This functionality will be discontinued at block height 807000.

References

  1. [1]BRC-20 on BTC
BSV-20 specification
The original document, as a PDF (4 pages).
Download PDF