一文了解Ordinals协议与比特币铭文原理
随着Ordinals协议的诞生,其为比特币提供了编号和铭文的功能,从而拓宽了比特币生态系统的产品范围,并为比特币生态带来了新的活力。在本文中,我们将深入探讨Ordinal协议的细节,包括如何对每个比特币进行编号和追踪,以及铭文与编号之间的关系。但在深入探讨这个主题之前,我们需要首先了解一些比特币的基本背景,以帮助我们更好地理解后续内容。
完成本文的阅读后,你将掌握比特币的交易机制和支付模型,了解Ordinals如何为每个聪实现编号和追踪,以及铭文是如何创建和交易的。此外,你还将了解不同类型的钱包之间的差异。
一、比特币背景
比特币采用了一个类似于现金的交易模型(cash system),其支付方式基于一种称为UTXO的模型,这与传统的基于账户余额的模型有所不同。举例而言:在银行的账户记账模型流程中,当A向B转账100元时,银行会记录三个步骤,这三个步骤构成了一个交易过程。第一步是从A的账户中扣除100元,这个步骤的记录ID为tid1。第二步是将100元存入B的账户中,这个步骤的记录ID为tid2。第三步是记录一笔转账记录,该记录将tid1和tid2关联起来,表示A账户减少100元,B账户增加100元。这样,A和B之间的转账关系就被记录下来,并且可以在未来查询与追踪。现在,我们将通过对于UTXO和支付模型的介绍,讲解比特币的支付方式。
UTXO
在比特币区块链中,所有的余额都是存储在一个名为“未花费交易输出”(Unspent Transaction Output, UTXO)的列表中。每个UTXO都包含一定数量的比特币,以及这些比特币的所有者信息,并标明是否可用。可以将其想象成一张署有持有人姓名的现金支票,只要持有人在上面签名,就可以将使用权转让给他人。对于特定的地址,其所有的UTXO金额加起来即为该地址钱包的余额。通过遍历所有的UTXO,我们可以获取每个地址的当前余额。将所有的UTXO金额加总,则为当前全部流通的比特币。
在比特币的交易结构中,每笔交易都包括若干个输入和输出,其中每个输入是对一个已有的UTXO的引用,而每个输出则指定了新的资金接收地址及相应的金额。一旦一笔交易被发起,其输入部分所引用的UTXO便会被暂时锁定,以防止在交易完成前被重复使用。只有当这笔交易成功地被矿工打包到一个区块(Block)并获得网络确认后,相关的UTXO状态才会发生变化。具体来说,用于交易输入的UTXO将从UTXO列表中移除,表示它们已经被消费,而交易的输出则会生成新的UTXO,并添加到UTXO列表中。可以理解为,旧的现金支票被使用后失效,产生了新的现金支票,其所有权属于新的持有人。
值得强调的是,每个UTXO只能在一笔交易中被使用一次。一旦它作为输入被消费,它就会永久地从UTXO列表中移除。同时,新生成的输出作为新的UTXO加入到列表中。UTXO列表是不断变化的,随着每个新区块的创建,它会相应地进行更新。并且,通过分析区块链中的交易历史,我们能够重建在任何给定时间点的UTXO列表状态。
此外,一笔交易的总输入金额通常会略微超过其总输出金额。这个差额,称为交易费用(Transaction fee)或网络费(Network fee),是作为激励给予负责将交易打包到区块的矿工的。网络费的大小与交易的复杂性成正比,因此,一笔包含更多输入和输出的交易通常需要支付更高的网络费。
现在,为了更加形象地理解比特币的交易结构,我们将通过一个具体的示例进行深入分析。比特币的交易结构如下,其中vin和vout这两个变量分别代表着比特币交易的 “输入” 与 “输出”。比特币的交易并不像传统的账户余额模型记录账户形的数据变化,而是通过输入和输出来表示。

我们可以在blockchain.com随机选一个交易记录来分析,下图展示了 Hash ID为0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2 的交易。其包含了一个输入和两个输出。

通过使用 bitcoin-cli 的命令 getrawtransaction 和 decoderawtransaction ,我们可以查看上述交易的底层结构:
在比特币网络中,交易输出包含两个重要信息:地址(公钥哈希)和 金额(以比特币为单位)。如果一个交易的输出没有在其他交易的输入中使用,那么这个交易输出就被称为未消费交易输出(UTXO)。谁拥有 UTXO 中公钥对应的私钥,谁就有权使用(即花费)这个 UTXO。
我们观察一下上面代码中的“vin”中的信息,它表示这个交易所花费的 UTXO 来自于另外一个交易(其 id 为 7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18)的第 0 个输出(一个交易的输出可以有多个,索引从 0 开始编号),我们可以从历史交易中查找出这个 UTXO 的金额(比如为 0.1),所以这个交易中这个用户花费了 0.1 BTC,数值 0.1 不需要显式地写在 交易中,而是通过查找 UTXO 信息来得到的。这个交易的“vout”有两个输出,这两个输出为两个新的UTXO,对应了新的余额以及持有人,直到有另外的交易把它们作为输入消费掉。

对于用户A,首先需要确定其拥有的所有UTXO集合,即用户A可以支配的所有比特币;
A从这个集合中选取一个或者多个UTXO作为交易的输入,这些输入的金额之和为m(2+0.8+0.5=3.3 BTC)要大于需要支付的金额n(3 BTC);
用户A为交易设置两个输出,一个输出支付给B的地址,金额是n(3 BTC),另一个输出支付给A自己的一个找零地址,金额为m-n-fee(3.3-3-0.001=0.299 BTC)。用户的钱包通常由多个地址组成,一般情况下每个地址只使用一次,找零默认返回给一个新的地址;
等矿工将这笔交易打包上链进行确认后,B就可以收到这笔交易信息。因为区块的大小有上限(约1 MB),所以矿工会优先确认交易费率(fee_rate=fee/size )高的交易,以获取最高的手续费回报。我们可以在mempool看到实时的挖矿 transaction fee 的情况。如果我们在转账过程中如果想要最快进行确认,就可以选择高优先权(High Priority)或者自定义(custom)一个合适的 交易费率。

二、聪的编号与追踪
比特币总量是2100万个,每个比特币包含10^8个聪(Satoshi, Sat)。因此,比特币网络上一共有2100万*10^8个聪。Ordinals协议将这些聪区分出来,为每个聪进行唯一编号。本节将介绍这个协议是如何做到为每一个聪进行唯一编号,并且如何追踪其所在的账户。此外,还会简介对于聪的稀有度份分类。
聪的编号
根据 Ordinals 协议,聪的编号是根据它们被开采的顺序而定。下图展示了第0个区块挖出的第0个聪的表示方式。

对于聪的表达方式有多种:
整数符号:例如2099994106992659,表示该聪按照挖掘顺序所分配的序号。
十进制符号:例如3891094.16797,第一个数字表示挖掘该聪的区块高度,第二个数字表示聪在区块中的编号。
度数符号:例如3°111094′214″16797‴,第一个数字是周期,从0开始编号,第二个数字是减半纪元的区块索引,第三个数字是难度调整期间的区块索引,最后一个数字是区块中sat的索引。
百分比符号:例如99.99971949060254%,表示该聪在比特币供应量中的位置,以百分比表示。
名称:例如Satoshi。使用字符a到z对序号进行编码的名称。
我们将通过一个例子来讲解如何对新挖出的比特币进行编号。观察比特币区块链的第 795952 个区块,我们可以看到其中第一笔交易Tx 3a1f…b177 记录了矿工的奖励(coinbase transaction)。这笔交易包含了新挖出的比特币,这些比特币是作为矿工的打包奖励,以及交易发起者付给矿工的手续费。通过查看下图的输入,我们可以发现其UTXO的id由一串0和区块高度组成。输出的地址则是矿工的钱包地址,金额则是上述的奖励和手续费的总和。

若我们进一步查看输出给矿工的部分,可以看到地址、金额以及所包含的聪的分布情况。如前所述,这些包含了挖矿奖励和手续费。其中,绿色的 sats 编号信息1941220000000000–1941220625000000是挖矿奖励产生的新聪,其余的 712 条聪的记录则对应了该区块中的所有手续费。






