一、比特币背景
比特币采用了一个类似于现金的交易模型(cash system),其支付方式基于一种称为UTXO 的模型,这与传统的基于帐户余额的模型有所不同。

举例而言:在银行的帐户记帐模型流程中,当A 向B 转帐100 元时,银行会记录三个步骤,这三个步骤构成了一个交易过程。第一步是从A 的帐户中扣除100 元,这个步骤的记录ID 为tid1。第二步是将100 元存入B 的帐户中,这个步骤的记录ID 为tid2。第三步是记录一笔转帐记录,该记录将tid1 和tid2 关联起来,表示A 帐户减少100 元,B 帐户增加100 元。
这样,A 和B 之间的转帐关系就被记录下来,并且可以在未来查询与追踪。现在,我们将通过对于UTXO 和支付模型的介绍,讲解比特币的支付方式。
UTXO
在比特币区块链中,所有的余额都存储在一个名为「未花费交易输出」(UTXO)的列表中。每个UTXO 包含一定数量的比特币、拥有者信息以及可用性状态,类似于一张带有持有人姓名的支票。这张支票可以被签名后转让给其他人。
一个地址的余额等于其所有UTXO 的总和,通过遍历UTXO 列表可以获取每个地址的当前余额,同时这些UTXO 的总和代表了当前所有比特币的总供应量。

在比特币交易结构中,每笔交易包含输入和输出,每个输入是对已存在的UTXO 的引用,而每个输出指定了新的接收地址和金额。一旦交易被创建,与输入相关的UTXO 就会被临时锁定,以防止重复使用,只有在成功被矿工打包并确认后,相关的UTXO 状态才会改变。
具体来说,输入的UTXO 被移除,而输出会生成新的UTXO 并加入到列表中。这类似于旧的支票失效后生成新的支票,新支票的所有权转移到新持有人名下。
需要强调的是,每个UTXO 只能在一笔交易中被使用一次,使用后被永久移除,同时新的输出被创建并添加到UTXO 列表。随着新区块的创建,UTXO 列表会不断更新。通过分析交易历史,可以重建任何给定时间点的UTXO 列表状态。
此外,一笔交易的总输入金额通常略微超过总输出金额,这个差额成为交易费用,作为K工的激励。交易费用与交易复杂性成正比,因此,一笔包含更多输入和输出的交易通常需要支付更高的网络费。

为了更形象地理解比特币的交易结构,我们可以通过以下示例来深入了解,其中"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比特币,而数值0.1不需要明确写在交易中,而是通过查询UTXO信息来获得的。
这笔交易的"vout"包含两个输出,它们分别代表了两个新的UTXO,对应了新的余额和拥有者。这些新UTXO会一直存在,直到有另外的交易把它们作为输入消费掉。

支付模型
为了更好地理解比特币网路的支付模型,我们通过一个例子介绍由A 支付给B 金额为n 的比特币的支付流程。下图展示了使用者A 传送3 个比特币给使用者B 的过程。

对于使用者A,首先需要确定其拥有的所有UTXO 集合,即使用者A 可以支配的所有比特币;
A 从这个集合中选取一个或者多个UTXO 作为交易的输入,这些输入的金额之和为m (2+0.8+0.5=3.3 BTC) 要大于需要支付的金额n (3 BTC);
使用者A 为交易设定两个输出,一个输出支付给B 的地址,金额是n (3 BTC),另一个输出支付给A 自己的一个找零地址,金额为mn-fee (3.3-3-0.001 =0.299 BTC)。使用者的钱包通常由多个地址组成,一般情况下每个地址只使用一次,找零预设返回给一个新的地址;
一旦K工将交易打包并确认到区块链上,接收方 B 就能够获取有关这笔交易的信息。

由于每个区块的大小都有限制(通常约为1 MB),因此K工优先确认交易费率(fee_rate=fee/size) 高的交易,以获取最高的手续费回报。
我们可以在未确认交易池(mempool)中实时查看挖K交易费率的情况。如果我们希望在转账过程中尽快得到确认,就可以选择高优先权(High Priority) 或者自定义(custom) 一个合适的交易费率。

二、聪的编号与追踪
比特币的总供应量是2,100万枚,而每一枚比特币包含着10^8个聪(Satoshi,Sat)。因此,在比特币网络中,我们总共有2,100万 * 10^8 个聪。
Ordinals 协议采用一种独特的方式来对每一个聪进行编号,以确保其唯一性,并且能够准确地追踪它们所属的帐户。此外,还会简接对聪的稀有度分类。
聪的编号
根据Ordinals 协议,聪的编号是根据它们被开采的顺序而定。下图展示了第0 个区块挖出的第0 个聪的表示方式。

对于聪的表达方式有多种:
整数符号:例如2099994106992659,表示该聪按照挖掘顺序所分配的序号。
十进位制符号:例如3891094.16797,第一个数位表示挖掘该聪的区块高度,第二个数位表示聪在区块中的编号。
度数符号:例如3°111094′214″16797‴,第一个数位是周期,从0 开始编号,第二个数位是减半纪元的区块索引,第三个数位是难度调整期间的区块索引,最后一个数位是区块中sat 的索引。
百分比符号:例如99.99971949060254%,表示该聪在比特币供应量中的位置,以百分比表示。
名称:例如Satoshi。使用字元a 到z 对序号进行编码的名称。

我们来举例解释如何对新挖出的比特币进行编号。观察比特币区块链的第795952个区块,其中包含了一笔名为"Tx 3a1f…b177"的交易,记录了K工的奖励(coinbase transaction)。在这笔交易中,包含了新挖出的比特币,这些比特币是作为K工的奖励,以及交易发起者支付给K工的手续费。
通过观察输入部分,我们可以看到UTXO的ID,它由一串0和区块的高度组成。而在输出部分,我们可以看到接收这些奖励和手续费的地址,以及它们的总金额。

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

我们可以验证一下Sat 1941220000000000 这个编号。
它的block 编号为795952,十进位制符号(decimal) 为795952.0,意味着挖掘该聪的区块高度为795952,聪在此区块中的编号为0,后面的稀有度(rarity) 标记为uncommon ,我们将在后面的部分进行详细介绍。

聪的流转
比特币的交易模型使用了Unspent Transaction Output (UTXO) 模型,这意味着每个比特币(BTC)都可以被追踪到其来源。让我们以一个例子来说明这个过程:
假设用户A通过挖K得到了一笔奖励,其中包含了从第100聪到第110聪的比特币,这些比特币都存储在同一个UTXO(Unspent Transaction Output)中,这个UTXO的ID为adc123。
现在,当用户A想要支付给用户B 5聪时,他选择使用ID为abc123的UTXO作为交易的输入。这个交易会将5聪发送给用户B,同时返回5聪作为找零给用户A。
这两笔5聪都会成为一个整体,但会分别存储在两个不同的UTXO中,比如abc456和abc789。
上述UTXO id 和聪的数量仅作为例子展示,在实际情况下发送的聪的数量最小限制为546个以及UTXO id 也并非以此形式表达。

在上述的交易中,使用者A 的10 个聪的流转路径为:
挖K产生10 个聪,编号是[100 , 110)。 其表示编号为第100 到第109 个聪存放在id 为abc123 的UTXO 中,其所有者为使用者A。
在A 进行转帐时,10 个聪分成两份,每份5 个聪。这里采用「先进先出」 的原则,即聪的编号排序是按照它们在交易输出中的索引决定的。
假设输出的顺序先是使用者A,然后是使用者B,那么使用者A 剩余5 个聪的序号是[100, 105),存放在id 为abc456 的UTXO 中,而使用者B 的5 个聪的序号是[105, 110),存放在id 为abc789 的UTXO 中。

稀有度(Rare Satoshi)
作为Ordinals 协议的衍生玩法,聪的稀有度可以根据它们的挖掘顺序来定义。这将导致一些特殊的聪具有不同的稀有度。以下是不同聪的稀有程度:
common 普通级:除区块第一个聪外的任何聪(总供应量为2100 兆)
uncommon 优良级:每个区块的第一个聪(总供应量为6929999)
rare 稀有级:每个难度调整期的第一个聪(总供应量为3437)
epic 史诗级:每次减半后的第一个聪(总供应量为32)
legendary 传奇级:每个周期的第一个聪(总供应量为5)
mythic 神话级:创世区块的第一个聪(总供应量为1)
这种稀有聪的概念可以为比特币生态增加更多的趣味性和价值。不同稀有度的聪可能在市场上具有不同的价值,吸引收藏家和投资者。

三、铭文方式
Ordinals 与其他非比特币链上的NFT 有一个显著不同之处,那就是它的元数据没有被存储在特定位置上。
相反,这些元数据被嵌入到交易的见证资料(witness data, witness field)中,这也是我们将其称为“铭文(inscription)”的原因,因为这些数据就像铭文一样被“刻在”比特币交易的特定部分上,而这些数据正是附着在特定聪上。
这个铭文过程是通过隔离见证(Segregated Witness, SegWit)和“向Taproot支付”(Pay-to-Taproot, P2TR)的方式来实现的,它包括提交(commit)和揭露(reveal)两个阶段,可以将任何形式的内容(如文字、图像或视频)刻在指定的聪上。
接下来,我们将详细介绍另一种更直接的存储方式,即OP_RETURN,并解释为何它不适用于铭文。同时,我们将探讨隔离见证和Pay-to-Taproot的概念,以及它们在铭文中的作用。最后,我们将深入探讨铭文的方式。

OP_RETURE
在Bitcoin Core客户端0.9版本中,采用RETURN操作符最终达成了一种妥协。RETURN允许开发者在交易输出中添加80位字节的非支付数据。不同于伪支付,RETURN创建了一种明确可验证但不可花费的输出,无需存储在UTXO(未使用交易输出)集合中。
RETURN输出会记录在区块链上,这将占用磁盘空间并导致区块链尺寸增加,但它们不会占用UTXO集合,因此不会导致UTXO集合膨胀,也不会增加全节点的昂贵内存成本。
虽然OP_RETURN是一种直接将信息存储在比特币区块链上的方法,但它也存在一些挑战。首先,OP_RETURN只能存储80 位元组的数据,对于需要存储更多数据的情况来说,这种限制明显不足够。
其次,OP_RETURN数据存储在交易输出中,虽然它们不会占用UTXO集合,但它们会占用区块链的存储空间,导致区块链尺寸增加。
最后,使用OP_RETURN会增加交易费用,因为它需要支付更多的费用来发布这些交易。

隔离见证
相比之前的方法,SegWit 提供了一种新的解决方案,能够解决上述问题。
SegWit 是比特币的一个关键协议升级,由比特币核心开发者Pieter Wuille 在2015年首次提出,最终在2017年的0.16.0版本中正式采纳。
Segregated Witness(SegWit)中的"Segregated" 意味着分离或隔离,而"Witness" 涉及与交易相关的签名数据。因此,SegWit 的核心概念是将某些交易签名数据(也称为见证数据)与实际交易数据分离开来。
将签名数据与交易数据分离的主要好处是减小了存储在比特币区块中的数据大小。这使得每个区块具有更多的可用容量,以容纳更多的交易,同时也意味着网络能够处理更多的交易,并且用户支付更低的交易手续费。
从技术上讲,这意味着将原本包含在基本区块结构中的脚本签名数据(scriptSig)移动到一个新的数据结构中。验证节点和K工也会验证这个新的数据结构中的脚本签名,以确保交易的有效性。

SegWit 升级还引入了一个新的见证数据字段,以增强隐私性和效率。尽管见证数据并非专门用于存储明文交易数据,但它实际上给了我们一个储存铭文元资料等内容的机会。
我们通过下图来更加形象地理解隔离见证:

Taproot
P2TR是比特币的一种交易输出类型,它在2021年的Taproot升级中引入,它使得不同的交易条件可以更加隐私地储存在区块链中。
在这一架构中,P2TR在Ordinals的铭文(data inscription)中发挥着至关重要的作用。铭文实际上是将特定数据嵌入到比特币交易中,而Taproot升级,特别是P2TR,使这种数据嵌入变得更加灵活和经济。
首先,由于Taproot指令码的存储方式,我们可以在Taproot指令路径中存储铭文数据,而这些指令码在内容方面几乎没有限制,同时还能享受见证资料的折扣,使得储存铭文数据相对经济。
然而,由于Taproot指令的消费只能来自已存在的Taproot输出,所以铭文的存储采用了两阶段的提交/揭示流程。首先,在提交交易中,建立了一个承诺包含铭文数据的Taproot输出。

然后,在揭示交易中,消费了由提交交易建立的输出,从而在链上揭示了铭文内容。
这种方法大大减少了资源的使用。如果不使用P2TR,见证数据将存储在交易输出中,只要这笔输出未被消费,见证数据就会一直存在于UTXO集中。
相反,如果使用P2TR,见证数据不会在提交阶段生成的交易中出现,因此不会写入UTXO集。只有当这笔UTXO被消费时,见证数据才会在揭示阶段的交易输入中出现。
P2TR使得原始数据可以写入比特币区块链,但却不会一直占用UTXO集中的空间。由于维护/修改UTXO集需要更多的资源,这一方法可以大幅节省资源。

铭文
Ordinals 协议通过使用SegWit来扩大比特币网络中写入内容的大小限制,将明文内容存储在见证资料中,从而允许最多4MB的元数据存储。
Taproot则简化了在比特币交易中存储任意见证资料的过程,允许Ordinals的开发者Casey Rodarmor重新利用旧操作码(OP_FALSE、OP_IF、OP_PUSH)来创建所谓的“信封”,用于存储被称为“铭文”的任意资料。
铭文的铸造过程包括以下两个步骤:
首先,在提交交易中,需要创建一个指向包含铭文内容的Taproot输出的承诺。这个储存的格式是Taproot,前一个交易的输出必须是P2TR(Pay-To-Taproot),并且在Taproot见证脚本中嵌入了特定格式的内容。
首先,将字符串"ordn"入栈,以消除铭文用途的歧义。然后,使用OP_PUSH 1指示下一个推送包含内容类型,使用OP_PUSH 0指示后续数据推送包含内容本身。
由于Taproot的限制之一是单个数据推送不能超过520字节,因此需要多次数据推送来存储大型铭文。此时,铭文数据已与交易输出的未使用交易输出(UTXO)关联,但尚未公开。

其次,在揭示交易中,需要消费建立的那个输出。在这一阶段,通过将与铭文对应的UTXO作为输入来启动交易。此时,与该UTXO相关的铭文内容将被公开到整个网络。
通过以上两个步骤,铭文内容已经与特定的UTXO相关联。根据之前介绍的聪(UTXO)的定位方式,铭文被铭刻在与其输入的UTXO对应的第一个聪上,并且铭文内容包含在显示交易的输入中。
根据前述的聪(UTXO)的流转和追踪,这个包含特殊内容的聪可以进行转移、购买、出售、丢失和恢复。需要注意的是,铭刻是不可重复的,否则后续的铭文将无效。
为了更详细地说明这一过程,让我们通过一个示例来展示如何铭刻一个比特币NFT的小图片。这个过程涵盖了之前提到的提交(commit)和揭示(reveal)两个阶段。
首先,我们可以看到第一个交易的哈希ID是2ddf9...f585c。需要注意的是,该交易的输出不包含见证数据,网页中也没有相关的铭文信息。

接着,我们检视第二阶段的记录,其Hash ID 是e7454…7c0e1。在这里,我们可以看到Ordinals inscription 的资讯,也就是见证的铭文内容。
这笔交易的输入地址是前一个交易的输出地址,而输出的0.00000546BTC(546 聪)则是将这个NFT 传送到自己的地址。同时,我们也可以在Sat 1893640468329373中找到这个铭文所在的聪。


在比特币钱包中,我们可以看到这个资产。如果我们想要交易这个NFT,可以直接将其传送给其他人的地址,也就是将这笔UTXO 传送出去,这样就完成了铭文的流转。

四、 比特币钱包
在我们了解了什么是Ordinals 生态、聪的流转以及铭文的相关知识后,目前有许多应用场景,无论是BRC-20,ORC-20,BRC-721,GBRC-721 等相关衍生协议的出现,需要我们有对应的钱包来支援和显示出代币资讯或者NFT 小图片。
本节我们会介绍一下不同比特币钱包地址的概念和特点。
比特币地址通常以1、3或bc1开头,就像电子邮件地址一样,可以与其他比特币用户共享,以便将比特币直接转入您的钱包。
从安全性的角度来看,比特币地址不包含敏感信息,因此可以随时在公共场合分享,而不会威胁到您的账户安全。与电子邮件地址不同,您可以根据需要创建新的比特币地址,而所有这些地址都将资金直接存入您的钱包。

事实上,许多现代钱包会自动为每笔交易建立一个新地址,以最大限度地保护隐私。钱包只是地址和解锁其中资金的钥匙的集合。首先我们要知道比特币钱包的地址是怎么产生的。
比特币私钥和公钥
比特币采用椭圆曲线Secp256k1,「私钥」 是1 到n−1 之间的随机数,n是个很大的数(256 个位元位),n 用科学计数法表示约为:

这个范围非常广,几乎无法破解其他人的私钥。这个私钥是一个随机整数,通常用256位二进制位来表示,有多种编码方式。使用WIF(Wallet Import Format)或WIF-compressed格式的私钥是未加密的,可以直接解码为原始的随机整数。
另一种方法是BIP38(Bitcoin Improvement Proposal 38),它建议使用AES算法对私钥进行加密。这种方案生成的私钥以字符6P开头,必须输入密码才能将其导入各种比特币钱包,这是我们通常使用的私钥保护方式。
接下来,我们使用椭圆曲线公式K = kG,其中k是私钥,G是基点(Base Point),它是secp256k1椭圆曲线的一个引数。
通过这个公式可以得到K 的两个座标,就是公钥的两种表达方式,分别为「Uncompressed format」 和「Compressed format」。

Uncompressed 形式,就是把两个座标x 和y 直接连线在一起,再在前面加个0x04 字首即可;
Compressed 形式,就是当y 为偶数时,编码为02 x,当y 为奇数时,编码为03 x;
比特币地址
比特币各种型别的地址如下图可示,共有四种表示方法:

1. Legacy (P2PKH) 格式
范例:1Fh7ajXabJBpZPZw8bjD3QU4CuQ3pRty9u
地址以「1」 开头,是比特币最初的地址格式,至今仍在使用。由公钥通过Hash 计算后得到,也被称为P2PKH 是Pay To PubKey Hash(付款至公钥hash)的缩写。
2. Nested SegWit (P2SH) 格式
范例:3KF9nXowQ4asSGxRRzeiTpDjMuwM2nypAN
地址以“3” 开头,P2SH 是Pay To Script Hash(支付至指令码hash)的缩写,它支援比Legacy 地址更复杂的功能。Nested P2SH,获取现有的P2SH 地址(以「3」 开头),并与SegWit 地址一起封装。

3. Native SegWit (Bech32) 格式
范例:bc1qf3uwcxaz779nxedw0wry89v9cjh9w2xylnmqc3
BIP0173引入了以"bc1"开头的地址格式,它们是用于原生隔离见证(SegWit)的地址。这种地址格式采用Bech32编码,专门为SegWit设计。Bech32格式的地址在BIP173中于2017年底定义,其主要特点之一是不区分大小写,因此在输入时更容易避免混淆,同时也更加易于阅读。
相较于传统的Base58编码,Bech32采用Base32编码,因此地址中所需的字符更少,计算更加高效,而且可以更紧凑地存储在二维码中。
此外,Bech32提供更高的安全性,并更好地优化了校验和错误检测,从而将无效地址的风险降至最低。
Bech32 地址本身与SegWit 相容。不需要额外的空间来将SegWit 地址放入P2SH 地址,因此使用Bech32 格式地址,手续费会更低。
总的来说,Bech32地址相对于传统的Base58地址具有多个优势:生成的QR码更小、更易于防错、更加安全、不区分大小写,且仅包含小写字母,因此在阅读、输入和理解时更为便捷。

4. Taproot 格式(P2TR)
Bech32 有个缺点:如果地址的最后一个字元是p,则在紧接着p 之前的位置插入或者删除任意数量的字元q 都不会使其checksum 失效。
为了缓解Bech32 的上述缺点,在BIP0350中提出了Bech32m 地址:
对于版本为0 的原生隔离见证地址,使用以前的Bech32;
对于版本为1(或者更高)的原生隔离见证地址,则使用新的Bech32m。
对于Bech32m地址,当其版本号为1时,它们始终以"bc1p"开头,这代表着它们是Taproot地址。类似于本地隔离见证,这些地址可以由种子短语和密码短语生成,用于产生扩展套房的公钥和私钥,从而能够在层次确定性钱包中推导出各种路径的地址。

这主要用于存储BRC-20代币以及比特币的NFT等数字资产。