Skip to content

Instantly share code, notes, and snippets.

@melvincarvalho
Created July 23, 2024 07:22
Show Gist options
  • Save melvincarvalho/91e759356f2038948c8cfa728915fa0d to your computer and use it in GitHub Desktop.
Save melvincarvalho/91e759356f2038948c8cfa728915fa0d to your computer and use it in GitHub Desktop.
runes.md

Runes Etching and Transfer Specification

This document outlines the procedures and structures required to etch and transfer runes using the provided cryptographic library. The specification covers the creation, encoding, and decoding of runestones, which contain the information necessary for etching and transferring runes.

Overview

Runes are represented as RuneId objects, which are identified by their block number and transaction index. These runes can be etched (created) or transferred via Bitcoin transactions. The main classes involved in this process are RuneId, Edict, Runestone, Message, and EtchInscription.

Terminology

  • RuneId: A unique identifier for a rune in the format BLOCK:TX.
  • Edict: Contains information about a rune, including its ID, amount, and output index.
  • Runestone: Encapsulates the etching or transfer data of runes.
  • Etching: The process of creating new runes.
  • Transfer: The process of transferring existing runes.

Procedures

1. Etching Runes

To etch a new rune, you must create a Runestone with the appropriate etching data.

EtchJSON Structure

The EtchJSON interface defines the structure of the JSON object used to create an etching:

export interface EtchJSON {
    name: string;
    divisibility?: number;
    premine?: number;
    symbol?: string;
    amount: number;
    cap: number;
    startHeight?: number;
    endHeight?: number;
    startOffset?: number;
    endOffset?: number;
    pointer?: number;
}

Creating an Etching

  1. Prepare the JSON object:

    {
        "name": "RuneName",
        "divisibility": 2,
        "premine": 1000,
        "symbol": "#",
        "amount": 500,
        "cap": 10000,
        "startHeight": 650000,
        "endHeight": 660000,
        "startOffset": 0,
        "endOffset": 1000,
        "pointer": 1
    }
  2. Create the Runestone object:

    const etchJson: EtchJSON = { ... };  // Fill with the JSON object
    const runestone = Runestone.create(etchJson, 'etch');
  3. Encipher the Runestone:

    const buffer = runestone.encipher();
  4. Include the buffer in a Bitcoin transaction:

    • The buffer is added to a transaction output script as an OP_RETURN payload.

2. Transferring Runes

To transfer an existing rune, you must create a Runestone with the transfer data.

MintJSON Structure

The MintJSON interface defines the structure of the JSON object used to create a transfer:

export interface MintJSON {
    block: number;
    txIdx: number;
    pointer?: number;
}

Creating a Transfer

  1. Prepare the JSON object:

    {
        "block": 650000,
        "txIdx": 1,
        "pointer": 1
    }
  2. Create the Runestone object:

    const mintJson: MintJSON = { ... };  // Fill with the JSON object
    const runestone = Runestone.create(mintJson, 'mint');
  3. Encipher the Runestone:

    const buffer = runestone.encipher();
  4. Include the buffer in a Bitcoin transaction:

    • The buffer is added to a transaction output script as an OP_RETURN payload.

Decoding a Runestone

To decode a runestone from a Bitcoin transaction:

  1. Extract the raw transaction data.
  2. Decipher the runestone:
    const rawTx = "hex-encoded-transaction";
    const runestoneOption = Runestone.decipher(rawTx);
    if (runestoneOption.isSome()) {
        const runestone = runestoneOption.value();
        // Access runestone data
    } else {
        // Handle error
    }

Fields and Flags

Flags Enum

Defines various flags used in transactions:

export enum Flag {
    Etching = 0,
    Terms = 1,
    Turbo = 2,
    Cenotaph = 127,
}

Tag Enum

Defines tags for different fields in the transaction payload:

export enum Tag {
    Body = 0,
    Flags = 2,
    Rune = 4,
    Premine = 6,
    Cap = 8,
    Amount = 10,
    HeightStart = 12,
    HeightEnd = 14,
    OffsetStart = 16,
    OffsetEnd = 18,
    Mint = 20,
    Pointer = 22,
    Cenotaph = 126,
    Divisibility = 1,
    Spacers = 3,
    Symbol = 5,
    Nop = 127,
}

Example

Etching Example

  1. Prepare the JSON object:

    {
        "name": "ExampleRune",
        "divisibility": 2,
        "premine": 500,
        "symbol": "$",
        "amount": 100,
        "cap": 1000,
        "startHeight": 680000,
        "endHeight": 690000,
        "pointer": 2
    }
  2. Create and encipher the runestone:

    const etchJson: EtchJSON = { ... };  // JSON object from above
    const runestone = Runestone.create(etchJson, 'etch');
    const buffer = runestone.encipher();
  3. Include the buffer in a Bitcoin transaction.

Transfer Example

  1. Prepare the JSON object:

    {
        "block": 680000,
        "txIdx": 0,
        "pointer": 1
    }
  2. Create and encipher the runestone:

    const mintJson: MintJSON = { ... };  // JSON object from above
    const runestone = Runestone.create(mintJson, 'mint');
    const buffer = runestone.encipher();
  3. Include the buffer in a Bitcoin transaction.

By following these steps and using the provided classes, you can successfully etch and transfer runes within Bitcoin transactions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment