近期火爆的比特币铭文、符文将比特币的生态发展推向了新的高度,本篇文章将尽量使用通俗的语言讲述清楚关于铭文与符文的底层技术实现原理,话不多说,let,s go!
Ordinals协议
理解铭文与符文的技术实现之前需要先理解Ordinals协议。BTC的最小单位是聪(SATS),1 BTC 等于 1 亿聪,Ordinals协议就是为聪编号的协议。允许跟踪和转移个别聪。这些编号称为 Ordinal。聪按照挖掘顺序进行编号,并按先进先出的顺序从交易输入转移到交易输出。编号方案和转移方案都依赖于顺序,编号方案依赖于聪被挖掘的顺序,转移方案依赖于交易输入和输出的顺序。因此得名 Ordinals。
备注: 这里的度数表示法表示聪的稀有程度
我们知道btc的产生只有通过矿工挖掘,也就是coinbase奖励获得。例如:矿工获得了区块200的记账权,奖励是50 BTC,那么该BTC就对应第200区块,0~50*10^9 聪编号。那这里这么多聪是如何确定哪些编号具体属于哪些聪呢?上面提到“聪按照挖掘顺序进行编号,并按先进先出的顺序从交易输入转移到交易输出”。例如矿工将50BTC中的10BTC先转了出去,那么这10个BTC就对应第200区块,0 ~10*10^9聪编号,剩余的40BTC,自然就对应第200区块,10*10^9 ~ 50*10^9 聪编号,这就是按交易的顺序来为聪编号。
当然BTC的交易是以UTXO进行转移的,同样的道理,UTXO对应输出的顺序可以理解为花费的顺序,例如花费该50BTC对应的UTXO,对应输出10BTC的UTXO、40BTC的UTXO,这里10BTC在“输出位置”中的顺序靠前,所以就对应第200区块,0 ~10*10^9聪,如果输出的顺序是40BTC对应UTXO在前,则40BTC的UTXO就对应 0~40*10^9,一次类推。(UTXO的说明见:比特币UTXO说明)
你可能想到,这样的跟踪可能会变得特别麻烦,因为你要跟踪所有的比特币的交易来为对应的聪排序,是这样的,所以目前有专门的排序器来跟踪这些聪的转移。不过这里的排序虽然是麻烦的,但是聪的顺序是不会改变的,因为其已经写入到区块链,即使某个排序器跑路,也不会影响聪的顺序。
有了跟踪“聪”的协议之后,就可以将一个一个的“聪”视为一个载体,在其上附加对应的内容。这也是实现比特币铭文与符文的基础。
铭文
有了聪的排序之后,现在的问题就变成如何为具体的聪“绑定数据”。铭文采用将数据写入比特币交易中的“见证数据” wintness字段中。
以下是一个普通的比特币交易信息,inputs包含多个待花费UTXO,同时包含一个witness字段,该字段是inputs UTXO的解锁字段。
{
"txid": "c2f59c6fc8e812f5f1f00c8a0a9ab1929c1e796788c57f49001b8006a824ea17",
"size": 205,
"version": 2,
"locktime": 0,
"fee": 155500,
"inputs": [
{
"coinbase": false,
"txid": "c3e417e84950e955b523d02be6805955db547d1da6b49094d8357cc236bc5a50",
"output": 1,
"sigscript": "",
"sequence": 4294967295,
"pkscript": "5120de29b8c4065d2964457ca60860c5e69c19dd6b0108ca0b5383155966b1585f3b",
"value": 3659879,
"address": "bc1pmc5m33qxt55kg3tu5cyxp30xnsva66cppr9qk5urz4vkdv2ctuasy200qx",
"witness": [
"4654e1fa7622c41e4ca462a1d51f42dc34a987f2610dd6d163ffe98f85982e95e8c9468bad9f01f4b5544cc3504af747907ef687ab14cf12694fbcd14195040a"
]
}
],
"outputs": [
{
"address": "bc1p9zujs6f5sndugh6eufu5saynzmmwwwxnfusdytacj0e3enxsraaq03e430",
"pkscript": "512028b928693484dbc45f59e27948749316f6e738d34f20d22fb893f31cccd01f7a",
"value": 197000,
"spent": true,
"spender": {
"txid": "965f866bf8623bbf956c1b2aeec1efc1ad162fd428ab7fb89f128a0754ebbc32",
"input": 0
}
},
{
"address": "bc1pmc5m33qxt55kg3tu5cyxp30xnsva66cppr9qk5urz4vkdv2ctuasy200qx",
"pkscript": "5120de29b8c4065d2964457ca60860c5e69c19dd6b0108ca0b5383155966b1585f3b",
"value": 3307379,
"spent": true,
"spender": {
"txid": "c2d6f84b13058b75a0cb02a748906e88f68b7cc2aa7991a6cb3cf0c264533d18",
"input": 0
}
}
],
"block": {
"height": 800000,
"position": 2
},
"deleted": false,
"time": 1690168381,
"rbf": false,
"weight": 616
}
交易信息来源
铭文通过比特币P2TR交易的方式将数据写入witness数据当中。P2TR交易分为commit-reveal两个步骤。commit可以理解为将待写入的数据加个锁放入了对应UTXO当中。而之后的reveal交易是使用具体的数据来“解锁”这个交易并将数据与对应UTXO绑定,我们通过一个实例来说明这个:
首先是一个commit的交易:
{
"txid": "7df2f0a05056bc1d49c18e060e47dd916199ee3fb80f440c3de8464840ed6e15",
"size": 162,
"version": 2,
"locktime": 0,
"fee": 666,
"inputs": [
{
"coinbase": false,
"txid": "69b617fb89b2472efd1b62c363d7a203d8a50e12bc18c350d652b3c2d66e92ff",
"output": 1,
"sigscript": "",
"sequence": 4294967293,
"pkscript": "5120e1fc918ad7cd9fc2bf0cec887e41436c261e2f3411026c951b73318a3714ebea",
"value": 97004,
"address": "bc1pu87frzkhek0u90cvajy8us2rdsnpute5zypxe9gmwvcc5dc5a04qdfn7jn",
"witness": [
"e9e464c76b9bd963fa1114640aee9a1d0db0902c6822aaf26a493dba5c8efda8df02824d50224a9aead241ea0370448b09abb081601f67536c7aa0dc1c09351c"
]
}
],
"outputs": [
{
"address": "bc1pvah3e0k4akkz769gm3jc7wax4kjhuhndk8r5npwk2lf6kkleazqs0me0xv",
"pkscript": "5120676f1cbed5edac2f68a8dc658f3ba6ada57e5e6db1c74985d657d3ab5bf9e881",
"value": 96338,
"spent": true,
"spender": {
"txid": "5602e5324b6c556450a9110618fa294201037a1f54d4adb1fec8c46999509de4",
"input": 0
}
}
],
"block": {
"height": 851432,
"position": 3026
},
"deleted": false,
"time": 1720540474,
"rbf": false,
"weight": 444
}
交易来源
这里outputs的UTXO包含了需要通过reveal进行解锁的hash,可以理解为宣示自己对待铭刻数据的所有权。
再来看reveal交易:
{
"txid": "5602e5324b6c556450a9110618fa294201037a1f54d4adb1fec8c46999509de4",
"size": 367,
"version": 2,
"locktime": 0,
"fee": 1170,
"inputs": [
{
"coinbase": false,
"txid": "7df2f0a05056bc1d49c18e060e47dd916199ee3fb80f440c3de8464840ed6e15",
"output": 0,
"sigscript": "",
"sequence": 4294967293,
"pkscript": "5120676f1cbed5edac2f68a8dc658f3ba6ada57e5e6db1c74985d657d3ab5bf9e881",
"value": 96338,
"address": "bc1pvah3e0k4akkz769gm3jc7wax4kjhuhndk8r5npwk2lf6kkleazqs0me0xv",
"witness": [
"6d45c89f8aea8fa12ca71d83ba0aa3b8f6ea8de0789325176d939fa470d827f621d502e81f24a82d89b7ad030edca8efb2e5a14cb691743b08248eb57179c053",
"20ba8c1448bbf5d3d1c076c3adfbad85787e970782358d841e4bf272c4797b0f7cac0063036f7264010118746578742f706c61696e3b636861727365743d7574662d3800397b2270223a226272632d3230222c226f70223a227472616e73666572222c227469636b223a2270697a7a61222c22616d74223a22313030227d68",
"c0ba8c1448bbf5d3d1c076c3adfbad85787e970782358d841e4bf272c4797b0f7c"
]
}
],
"outputs": [
{
"address": "bc1p42kr3vcm9n5ajm6qsf7kky6ql9x8jegjutmfwlh3n9hrr5dv76gsgue0wj",
"pkscript": "5120aaac38b31b2ce9d96f40827d6b1340f94c796512e2f6977ef1996e31d1acf691",
"value": 330,
"spent": false,
"spender": null
},
{
"address": "bc1pu87frzkhek0u90cvajy8us2rdsnpute5zypxe9gmwvcc5dc5a04qdfn7jn",
"pkscript": "5120e1fc918ad7cd9fc2bf0cec887e41436c261e2f3411026c951b73318a3714ebea",
"value": 94838,
"spent": true,
"spender": {
"txid": "5a3460fec952c4edb045f16f91f85f2329dd24c9dbda16f1c46c24458196dea7",
"input": 0
}
}
],
"block": {
"height": 851432,
"position": 3368
},
"deleted": false,
"time": 1720540475,
"rbf": false,
"weight": 778
}
交易来源
在reveal交易的inputs witness中包含了具体的我们待铭刻的信息,同时该段信息可以解锁commit输出的UTXO,这样,具体铭刻的信息就与reveal交易outputs中的第一个UTXO绑定在了一起,该UTXO可能会有多个聪,协议规定与其UTXO中的第一个聪进行绑定。
一旦铭文被铭刻到具体的聪之后,铭文的转移将不会将铭刻的内容带上,而是转移对应的聪,而这个聪已经与对应的铭文做了绑定了。之后该铭文的转移其实就是这个聪的序列转移。
符文
从技术角度来讲的话,这里直接引用一下余弦老板的说法:比特币铭文(Inscription)与符文(Rune)的一个关键区别在于,铭文是刻在隔离见证数据里,而符文是刻在OP_RETURN 里。OP_RETURN能存储的数据大小非常有限,但是用于发币绰绰有余,这个也并非什么新技术。
OP_RETURN 是比特币网络「存储信息」的功能。该功能支持向比特币网络写入十六进制字符,最多可以添加80字节的信息。带有OP_RETURN的UTXO是无法被被继续使用的,所以该UTXO就作为一个不可改变的存储被放在链上。因为OP_RETURN不可消费的特性,所以它也可以用来销毁BTC。
如下面这个交易:
交易来源
如上图所示输出 Outputs 中有一个是 OP_RETURN 类型的交易,里面添加的信息是一个json形式的字符串(注意:OP_RETURN 类型UTXO对应BTC数量可以为0)。
我们以一个简单的符文BRC-20协议来说明符文从部署到交易的整个过程,
- 部署BRC-20协议信息
使用P2TR交易,先commit 一个 BRC-20 交易。再通过reveal来揭示具体的信息。reveal交易的输出中就有一个对应的OP_RETURN UTXO,该UTXO其中携带的信息就是具体该BRC-20 token的信息。对应的区块高度与交易索引就是该BRC-20协议的唯一标识。
如下图所示交易:
交易来源
输出的OP_RETURN信息中就指定了对应BRC-20代币协议。包括:symbol代表币的标识、premine代表项目方预挖的币等。其中比较重要的是这个pointer字段,预先挖出的币和哪个聪绑定?就是和这个pointer相关,它指定了预先挖出的币在对应OUTPUT中对应哪个UTXO,如果不指定就默认第一个非OP_RETURN的UTXO,如果指定就与指定下标UTXO绑定(下标从0开始算)。如图所示,对应pointer是1,可以看出从0开始的第1个UTXO右下角标识出了未花费的代币数量。
具体对应字段信息可见参考 [6].
- mint 对应代币
有了部署的协议,就可以根据部署的协议mint代币了。mint可以使用普通的包含有OP_RETURN输出的交易,OP_RETURN信息里面会指定mint的代币数量以及和该交易中的哪个UTXO进行绑定(即和具体的那个聪进行绑定)。这里就将对应代币与对应聪进行了绑定,之后的转账就可以只转移对应的聪即可。
也可以使用P2TR交易,道理是一样的,reveal的时候需要有一个OP_RETURN输出待mint的代币信息以及要绑定的对应UTXO,之后的转账就可以只转移对应的聪即可。
贴一个示例:
交易来源
- 转移对应代币
在mint的时候已经制定了绑定到了那个UTXO(也就是绑定了指定的聪上面),之后的交易和上面铭文的方式类似,交易对应的聪即是在转移对应代币。这里需要注意的一点是,BRC-20代币的转移类似于UTXO,例如:你mint了200个BRC-20代币,那么转移的时候,你不能只转移50个代币,而剩下150个代币。你需要将200个代币都转移出去,不过类似于UTXO的方式,输出的时候可以有两个代币的输出--一个50代币,一个150代币。这里的150代币可以再转给自己。如果的输出中只有50代币,那么默认的150代币将默认分配个当前交易输出中的第一个非OP_RETURN UTXO。
参考
[2] 什么是Runes符文币蚀刻铭刻
[4] 符文Runes协议技术详解
[5] 符文文档解析
[6] 符文文档英文版说明
[7] P2TR的实现




文章评论