Mandala Token Protocol

BRC-92: Mandala Token Protocol

Deggen (deggen@kschw.com)

Abstract

Minimalist protocol for tokenization, issuance, transfer, recovery, and redemption.

Motivation

There is a lack of clarity with respect to how tokens can be defined and managed within the context of Overlays. This proposal aims to demonstrate the minimim viable solution for tokens, having considered all available options, picked the most viable, and made small improvements to allow for simple extension of functionality.

Specification

  1. Use a genesis transaction output as an assetId concatenating the txid and vout.

  2. Push that assetId to the stack in any output script you want to send that token to so that overlays, wallets, and smart contracts can evaluate it.

  3. Push the amount of tokens the output represents if it's a fungible token.

  4. Drop the data so that you can use whatever functional logic you like thereafter ...

  5. 1 satoshi assigned to each output.

  6. Prefix everything with a UTF8 exclamation point ! (0x21 in hex) for sake of measuring adoption.

Fungible Token

21 <assetId> <amount> OP_DROP OP_2DROP ...

NFT Script

21 <assetId> OP_2DROP ...

Transfers

The sum of input token amounts must equal the sum of output token amounts of the same assetId.

inputs
outputs

output holding 9 tokens

21 assetId 04 OP_DROP OP_2DROP ...

21 assetId 05 OP_DROP OP_2DROP ...

The order of inputs and outputs is disregarded.

Design Justification

Include Genesis Output and Protocol Identifier In Every Output

Token outputs each refer to the genesis output as a way to avoid collisions when identifying the asset they represent. This acts as a universal asset identifier for enabling swap contracts and token based payment protocols. The randomness helps us avoid things like people competeing to claim the "USD" assetId or other potentially popular labels.

They also include a prefix of ! in utf8 as a way to tag outputs for tracking global adoption of the protocol; to reduce the cost of recovery from archival services; and for use within the context of IPv6 multicast group address routing.

Why Push Data Formatting?

The only reason to include the data in the outputs at all is for access to the data in smart contracts, any metadata ought to be kept in the application layer if needed.

Bitcoin Number format is used for the token amount.

Transaction outpoint format is used for the genesis outpoint information.

This is to ensure smart contracts can more easily parse the data within a transaction to enforce conditional logic based on token values, and enforce token type in a format which is already incorporated into the transaction format itself.

Single Satoshi Outputs

All outputs have 1 satoshi assigned to avoid AML problems like sending “a worthless bean token” to someone which actually has 100 BSV under it.

Tokenization: Deep Dive

NFTs

Non-Fungible tokenization is the process of associating something with a particular transaction output which will thereafter represent a claim to that something. We assume that the issuer has already registered a public key as associated with them: identityPublicKey.

const details = {
	entity: 'Local Comedy Troupe',
	asset: 'Ticket for show on 9/01/2024',
	address: '412 E 6th St, Austin, TX 78701'
}

const commitment = hash(details)
const anyone = new PrivateKey(1)
const pubkey = identityPublicKey.deriveChild(anyone, commitment)

We propose this key be referred to as a BoundKey.

The output looks like a regular P2PK but if you know the owner’s identity public key and the token details you are able to verify the association. The txid and vout of this transaction form the assetId for this NFT.


Fungible Tokens

Fungible tokens sometimes require administrative management: multiple issuances to increase available supply, redemptions to reduce supply, recovery from loss in case of errors or theft. These things require an known issuer to steward the token system as a whole while keeping individual transactions private.

Registration

There is an issuer who is responsible for maintaining the relationship between tokens and the real world assets they represent. Before we issue any tokens, we register a public key by creating an authorized outpoint with a key derived from the issuer’s identity key. This transaction is used as the basis for a particular fungible token.

inputs
outputs

any

21 OP_DROP boundKey OP_CHECKSIG (the genesis outpoint, assetId, and authorized outpoint 0)

Issue

Once registered, tokens can be issued by creating a single transaction which:

  • spends the genesis outpoint

  • creates token outputs

  • creates the next authorized outpoint

inputs
outputs

authorized outpoint n

21 OP_DROP boundKey OP_CHECKSIG (authorized outpoint n+1)

21 assetId 09 OP_2DROP P2PKH (creates 9 tokens)


Redeem

Redemption transactions spend token outputs without creating new ones, taking them out of circulation. The boundKey in this case could incorporate data associated with a withdrawal of funds from an associated bank account for example.

inputs
outputs

authorized outpoint n

21 OP_DROP boundKey OP_CHECKSIG (authorized outpoint n+1)

Any token outpoint with our genesis_outpoint

no token outputs

A chain of authorization outpoints is created such that the transaction DAG works as an immutable linked hash chain of all administrative actions taken since genesis. Public audit-ability. No hidden issuances or redemptions. The token supply is known and provable.


Burning ⇒ Loss

When a token owner creates a valid BSV transaction which does not conform to the token transfer rules, the tokens are burned, and the transaction will not be accepted by the token overlay, despite perhaps being broadcast on the blockchain itself.

inputs
outputs

Valid tokens

no token outputs, or too few

In this case, tokens in does not equal tokens out.


Recovery

Post burning, tokens which were lost can be recovered by the issuer by spending and creating an authorized output while including metadata into the derivation of a pubkey to indicate which txids are to be processed as having been spent invalidly.

inputs
outputs

authorized outpoint n

21 OP_DROP boundKey OP_CHECKSIG (authorized outpoint n+1)

21 assetId 05 OP_2DROP P2PKH


Example Transactions

Implementations

Not yet available. Proposal stage.

Last updated