How to Build a Token on Bitcoin in Javascript

Clemens
4 min readSep 25, 2020

--

This article explains a simple and extensible way to build fungible tokens on Bitcoin. We cover how to write a token smart contract in Javascript and how to mint and send tokens.

We use the Bitcoin Computer, a smart contract system for Bitcoin and Litecoin (available on Npm and Github).

The Smart Contract

A smart contract for the Bitcoin Computer is a Javascript ES6 class.

class Token {
constructor(supply, name, pubKey) {
this.coins = supply
this.name = name
this._owners = [pubKey]
}
send(amount, to) {
if (this.coins < amount) throw new Error()
this.coins -= amount
return new Token(amount, this.name, to)
}
}

The constructor of the Token class creates an object that stores the supply and name of the token. The property _owners is a keyword in smart contracts and setting it guarantees that only the holder of the private key corresponding topubKey can send tokens initially.

The send function checks whether the amount of tokens in the current object is sufficient to cover the number of tokens to be sent. It throws an error if insufficient funds are detected. Otherwise, it reduces the amount of tokens in the current object by number. The method returns a new Token object with amount-many tokens that are owned by the recipient to.

Example

The image shows the transactions that are broadcast when a token is created and transferred between users. Enclosing boxes represent transactions, colored boxes represent outputs, arrows represent spending relations. The numbers indicate the number of tokens in an output and the color represents the owner of the tokens.

Note that the transactions mimic the way that Bitcoin transfers satoshi between users. Sending tokens this way costs no more than sending Bitcoin.

Minting a Token

Minting a token means broadcasting a transaction that records the creation of the token. To broadcast the transaction we create a wallet by instantiating the Bitcoin Computer library.

import Computer from 'bitcoin-computer'const seed = <some BIP39 seed>
const computer = new Computer({ seed }))

The object computer that is returned can deploy Javascript objects to the Bitcoin blockchain via its new method. The creation of the new object is recorded in a transaction.

import Token from './token'const to = '03223d...46d06c8dfe'
const supply = 1000000
const name = 'Bitcoin Token'
const token = await computer.new(Token, [supply, name, to])

The computer.new method returns an object token that has all the properties and methods of the Token class. We call token a smart object because its state is backed up on the blockchain. Each smart object has a property _id that remains fixed throughout its lifecycle. It encodes the output where the object was deployed.

Sending a Token

The send method creates a new smart object sentToken with the given amount of tokens. A function call on a smart object is recorded in a transaction so we have to await on the function call to sign and send it.

const amount = 50000
const to = '03223d...46d06c8dfe'
const sentToken = await token.send(amount, to)

The sentToken object is also a smart object owned by to. In addition to the _id property, every smart object also has a property _rev that encodes the output where its latest state is recorded. This _rev can be sent to the recipient of the token transfer through email, a website, or any other means.

Receiving a Token

The computer.sync method returns the smart object stored at a given output. Receiver can pass the _rev obtained from Sender into computer.sync to compute the state of the object stored at that location.

const id = 'd2242c...43ffb:0'
const receivedToken = await computer.sync(id)
// expect.toEqual(receivedToken, sentToken)

The object receivedToken has the same state as sentToken but is stored on Receiver’s machine. Receiver can inspect the state to verify that receivedToken contains the expected number of tokens. However, Receiver also needs to check that Sender has sent the correct token. After all, an attacker can deploy a counterfeit token with the same type and state. How can Receiver distinguish the official token A from a counterfeit token B?

This problem can be solved by inspecting the _root property of the smart object. The _root property of a smart object is always set to the root of the dependency tree that is built during the evolution of a smart object.

All three properties _id, _revand _root encode outputs. Note that the counterfeit token has a different root output than the original token. All Receiver needs to do is to check if the _root is as expected. If so Receiver can safely accept the token.

Demo

If you want to try it out for yourself you can download the code from Github. The app is built to be a starting point for new token projects and to be easy to integrate into existing Javascript wallets.

Build Your Own Token

You can launch your own token today. No previous knowledge other than Javascript is required. There is more information in the docs and if you have any questions feel free to join our Telegram group.

www.bitcoincomputer.io

--

--

Clemens
Clemens

No responses yet