# Rune 符文文档解析

By [3P-Labs](https://paragraph.com/@3p-labs) · 2024-03-30

---

> 符文利用比特币交易来蚀刻、铸造和转移比特币原生的数字商品。
> 
> _Runes allow Bitcoin transactions to etch, mint, and transfer Bitcoin-native digital commodities._

Runestone
---------

**这里的 runestone 和 @LeonidasNFT 所发行的符石 NFT 所区分，它是符文协议中对消息的一种称呼**

Runestone 在实际实现中的数据结构为

    struct Runestone {
      // 命令，用于实现符文的转移
      edicts: Vec<Edict>,
      // 铭刻数据，写入符文的各项指定数据，用在铭刻符文的交易中
      etching: Option<Etching>,
      // 铸造条款，用在铭刻符文的交易中
      mint: Option<RuneId>,	
      // 一个用于将未分配的符文转移的指针，如果不存在则默认转移到第一个非 OP_RETURN 输出
      pointer: Option<u32>,				
    }
    

参考 [Output - Learn me a bitcoin](https://learnmeabitcoin.com/technical/transaction/output/)，比特币交易的每个输出中会有 `ScriptPubKey` 字段用来存放锁定脚本

Runestone 就被存放在比特币交易的输出中，一个 Runestone 的输出脚本形式为

    [OP_RETURN] [OP_13] [data1] [data2] ...
    

它利用了比特币自身的“备注”功能来存放 Runestone 的数据，`OP_13` 后的一系列数据被连接和解码为一系列 128-bits 的整数，最后解析为 Runestone

符文中规定了：

*   一笔交易智能有一个 Runestone
    
*   Runestone 可以铭刻新的符文或者铸造现有的符文，并将符文中交易的输入转移到输出
    
*   交易的输出可以包含任意数量的符文余额
    

符文通过 ID 来进行标识，它的 ID 由铭刻符文的区块和交易的索引来构成，表示为 `Block:Tx`

例如第 500 个区块的第 20 笔交易所铸造的符文 ID 是 `500:20`

Etching
-------

符文通过铭刻（可以对应到 BRC-20 的 deploy、部署）而存在，铭刻会创建一个符文并填充它的一系列属性，这些属性在铭刻后是不可更改的

### 名称（Name）

名称由字母 A-Z 组成，其长度在 1-28 之间。同时，每个名称可能包含间隔符用于增加可读性，例如 `UNCOMMONGOODS` 可能会被铭刻为 `UNCOMMON·GOODS`

**名称的唯一性不取决于分隔符，符文不会铭刻与现有的符文相同的字母序列，即符文的字母序列是唯一的**

### 整除性（Divisibility）

符文的可分割性是它可以被分为原子单位的精细程度

这里对应了 ERC-20 代币的 decimal，以 ETH 为例，它的 decimal 为 18，那么就有 $1$ ETH = $10^{18}$​ wei

### 间隔符（Spacers）

一种用来表示间隔的信息，使用 `·` 来划分名称

使用不同的间隔符表示 `AAAA`：

*   0b1：A·AAA
    
*   0b11：A·A·AA
    
*   0b10：AA·AA
    
*   0b111：A·A·A·A
    

> 这里的表示方式是使用二进制来表示某个位置的间隔符是否显示，`AAAA`中间的间隔具像化后为 `A[0]A[1]A[2]A`，从左到右依次编号为0、1、2，对应到二进制中可以有8中表示方式，如果对应位为 1 则表示间隔符需要显示

### 符号（Symbol）

符文的货币符号是单个 Unicode 码，这也意味着一系列的 Emoji 符号可以被用来当作货币符号，例如`$`, `⧉`, 或`🧿`

没有符号的符文默认使用 `¤`

### 预铸造（Premine）

符文的铭刻者可以选择直接将符文分配给自己，这种分配模式称为预铸造

### 条款（Term）

一个符文可以有开放的铸造，这允许所有人为自己创建和分配符文，开放的铸造受铭刻时设定的条款的约束

开放的铸造可能被限制起始高度、结束高度和上限

容量（Cap）：符文的可铸造次数是它的上限，铸造会在达到上限时关闭；

数量（Amount）：每一笔铸造交易都会创建固定数量的符文单元；

起始高度（Start Height）：铸造从具有起始高度的区块开始；

结束高度（End Height）：在达到该高度后不再允许铸造；

起始偏移（Start Offset）：铸造从高度等于起始偏移+铭刻符文的高度的区块开始，例如：一个符文在高度 840000 被铭刻，并制定了起始偏移 50，那么对它的铸造就只能从 高度为 840050 的区块开始；

结束偏移（End Offset）：铸造从高度等于结束偏移+铭刻符文的高度的区块结束；

Transferring
------------

在交易输入包含符文，或者通过预铸造、铸造来创建心的符文单元时，这些符文会被传输到交易的输出中，交易的 Runestone 可能改变输入符文转移到输出的方式

命令（Edicts）：一个 Runestone 中会包含任意数量的命令（Edicts），命令由符文 ID、数量和输出编号组成，它按照顺序处理将未分配的符文分配给输出；

指针（Pointer）：所有未分配的符文会转移到交易的第一个非 `OP_RETURN` 输出中，Runestone 可以选择包含指定替代默认输出的指针；

销毁（Burning）：符文可以通过使用命令或指针的方式被传输到 `OP_RETURN` 输出来销毁；

**从实际的实现上来看符文的转移方式：**

指令在具体的数据结构中表示为

    struct Edict {
      // 以区块+交易索引组成的符文 ID，对应的位置包含了符文的元数据
      id: RuneId,				
      // 转移的数量
      amount: u128,				
      // 指向的输出
      output: u32,				
    }
    

Runestone 中包含了一个 `Edict` 数组，即在一个 Runestone 中会有任意数量的命令，在处理时顺序处理它们

在处理之前，输入符文和待铸造的符文未被分配，每个命令都会减少符文的未分配余额，并且将减少的这部分分配到输出中

如果命令分配到符文数量大于未分配到符文数量，那么它就会分配所有剩余的未分配的符文单位

> 举个例子，如果一个交易的输入中有 1000 个符文单位，那么未分配的符文数量初始为 1000
> 
> 命令依次为：
> 
> <200, 1> <400, 2> <700, 3>
> 
> 那么在处理最后一个命令的时候，未分配余额为 400，700 超过了余额，所以会将剩余的这部分全部分配给对应的输出

Reference
---------

1.  [Runes - Ordinal Theory Handbook](https://docs.ordinals.com/runes.html)
    
2.  [Output - Learn me a bitcoin](https://learnmeabitcoin.com/technical/transaction/output/)

---

*Originally published on [3P-Labs](https://paragraph.com/@3p-labs/rune)*
