头条
探索热门的铭文生态的技术原理和可能存在的安全问题。
撰文:Simon shieh
2023 年 12 月 6 日,在比特币投资者们都在为铭文(Inscriptions)给比特币带来的涨幅而欢呼的时候,Bitcoin Core 节点客户端的开发者 Luke Dashjr 浇来了一盆冷水。他认为铭文是一种「垃圾邮件」攻击,并提交了修复代码及 CVE 漏洞报告(CVE-2023-50428)。随后比特币社区炸开了锅,继 2017 年硬分叉的混乱之后,比特币社区再次陷入激烈的辩论中。
那么比特币应该更注重安全性而舍弃掉一些意料之外的 feature 呢,还是应该更加包容意料之外的创新而稍微容忍一点可能的安全性问题呢?
我们知道,比特币的旅程不仅仅是投机和炒作,更是其生态系统和安全格局不断演化的历程。本文旨在深入探讨比特币增长的双重叙事:其生态系统内不断扩展的效用和安全措施的强化。我们将探索创新与强大的安全协议的协同作用,如何为数字资产的新时代铺平道路。
我们知道作为加密货币革命的基石,比特币一直被人们当做黄金一样进行价值存储,在其他公链 DEFI 创新如火如荼之时,人们似乎都已经忘了比特币的存在。
然而,恰恰是在比特币上,先驱者们最早开启了稳定币、Layer2、甚至 DEFI 的实验,比如现在币圈的硬通货 USDT 最早就是发行在比特币 Omnilayer 网络上,下图就是从技术实现角度对比特币生态的一个基本分类。
包括基于双向锚定的侧链、基于输出脚本(OP_RETURN)的文本解析、基于 Taproot 脚本的铭刻、基于 BIP300 更新升级的驱动链和基于状态通道的闪电网络等技术。
上面可能很多术语大家还不了解,不着急,我们先熟悉以下的基础知识,然后再一一讲解这些生态的技术原理并探讨其中的安全问题。
与以太坊的账户余额体系不同,比特币的系统中并没有账户这个概念。以太坊引入了四颗棵复杂的 Merkle Patricia Trie 来存储和验证账户状态的变化。与之相比,比特币巧妙的利用 UTXO 来更加简洁的解决了这些问题。
以太坊的四棵树
比特币的输入与输出
UTXO(Unspent Transaction Outputs,未花费的交易输出),这个名字听上去特别拗口,但其实搞清楚输入、输出和交易这三个概念后,就很好理解了。
熟悉以太坊的朋友应该知道,交易(transaction)是区块链网络中基本通信单位,一旦交易被打包出块和确认,就意味着链上状态变更的确定。而在比特币的交易中,并不是单一的地址对地址的状态操作,而是多个输入脚本和输出脚本构成。
上图是一笔非常典型的比特币 2 对 2 交易。理论上,输入的 BTC 数量和输出的 BTC 数量应该相等,实际上输出比输入少的部分的 BTC 就作为矿工的手续费由出块矿工赚取,等同于以太坊中的 Gas Fee。
我们可以看到两个输入地址在转移 BTC 的同时,需要在输入的脚本中做验证,证明这两个输入地址可以花费这两笔输入(也就是上一笔的未花费输出,UTXO),而输出脚本,则规定了花费两笔输出比特币的条件,也就是在下一次将这笔未花费的输出作为输入时,应满足什么条件(一般普通转账,条件就是输出地址的签名,例如上图,P2wPKH 表示需要 taproot 地址的签名验证,P2PKH 则表示需要 legacy 地址私钥的签名)。
具体来说,比特币交易其数据结构如下:
在比特币交易中,基本结构由两个关键部分组成:输入和输出。输入部分指明了交易的发起方,而输出部分则指明了交易的接收方和找零(如果有的话)。交易费用则是输入总额与输出总额的差额。由于每一笔交易的输入都是之前某笔交易的输出,因此交易的输出成为了交易结构的核心要素。
这种结构形成了一种链式连接。在比特币网络中,每一笔合法的交易都可以追溯到之前的一个或多个交易的输出。这些交易链的起点是挖矿奖励,而终点则是当前尚未被花费的交易输出。网络中所有未花费的输出统称为比特币网络的 UTXO(Unspent Transaction Output)。
在比特币网络中,每笔新交易的输入必须是未花费的输出。此外,每个输入还需要前一笔输出的对应私钥签名。比特币网络中的每个节点都存储着当前区块链上的所有 UTXO,以此来验证新交易的合法性。通过 UTXO 和签名验证机制,节点能够在不追溯整个交易历史的情况下验证新交易的合法性,从而简化了网络的运行和维护过程。
比特币独特的交易结构是符合其白皮书《Bitcoin: A Peer-to-Peer Electronic Cash System》设计的,比特币是一个电子现金系统,其交易结构就是在模拟现金的交易过程,一个地址上可以花费的数量取决于之前收到的现金数量,每笔交易都是要把这个地址上的所有现金都整体花费出去,而交易的输出地址通常一个是接收地址,一个是找零地址,就像在超市使用现金交易时的找零。
在比特币网络中,脚本扮演着至关重要的角色。事实上,比特币交易的每个输出实际上是指向一个脚本,而不是一个具体的地址。这些脚本就像一组规则,定义了接收方如何才能使用输出中锁定的资产。
交易的合法性验证依赖于两种脚本:锁定脚本和解锁脚本。锁定脚本存在于交易的输出中,用于定义解锁该输出所需的条件。解锁脚本则与之相对应,必须遵循锁定脚本定义的规则来解锁 UTXO 资产,这些脚本位于交易的输入部分。这种脚本语言的灵活性使得比特币可以实现多种条件组合,展示出其作为「部分可编程货币」的特性。
在比特币网络中,每个节点都运行着一个堆栈解释器,用于基于「先进先出」的规则解释这些脚本。
最经典的比特币脚本主要有两种常用类型:P2PKH(Pay-to-Public-Key-Hash)和 P2SH(Pay-to-Script-Hash)。P2PKH 是一种简单的交易类型,其中接收方只需用相应的私钥签名即可使用资产。P2SH 则更为复杂,例如在多重签名的情况下,需要多个私钥的组合签名才能使用资产,或者。
这些脚本和验证机制共同构成了比特币网络的核心运作方式,确保了交易的安全性和灵活性。
比如在比特币中,P2PKH 的 output 脚本规则如下:
Pubkey script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
Input 则需要提供签名
Signature script: sig
而 P2SH 的 output 脚本规则如下:
Pubkey script: OP_HASH160 OP_EQUAL
Input 需要提供多签列表
Signature script: [sig] [sig...]
在上述的 2 种脚本规则里,Pubkey script 代表着锁定脚本,Signature script 代表着解锁脚本。OP_开头的单词是相关的脚本命令,也是节点所能解析的指令。这些命令规则根据 Pubkey script 的不同来进行划分,它也决定着解锁脚本的规则。
比特币中的脚本机制相对简单,只是一个基于堆栈式的,解释相关 OP 指令的引擎,能够解析的脚本规则并不是太多,不能实现很复杂的逻辑。但它为区块链可编程提供了一个原型,后续一些生态项目其实是基于脚本的原理发展起来的。而随着隔离见证和 Taproot 的更新,OP 指令的类型变得更加丰富,每笔交易可包含的脚本大小得到了扩容,比特币生态迎来了爆发式的增长。
铭文技术的火爆,离不开比特币的隔离见证和 Taproot 更新。
技术上看,区块链的去中心化程度越高,其效率通常越低。以比特币为例,它的每个区块的大小仍然维持在 1MB,与中本聪最初挖出的第一个区块大小相同。面对扩容的问题,比特币社区并没有选择简单直接地增加区块大小这一路径。相反,他们采取了一种名为「隔离见证」(Segregated Witness,简称 SegWit)的方法,这是一种不需要进行硬分叉的升级方案,旨在通过优化区块中的数据结构来提高网络的处理能力和效率。
在比特币交易中,每笔交易的信息主要分为两个部分:基础交易数据和见证数据。基础交易数据包括了诸如账户资金结余等关键财务信息,而见证数据则用于验证用户的身份。对用户来说,他们主要关心的是与资产直接相关的信息,如账户资金结余,而身份验证的细节并不需要在交易中占用太多资源。换句话说,接收资产的一方主要关注的是资产是否可用,而不必过分关注发送方的详细信息。
然而,在比特币的交易结构中,见证数据(即签名信息)占据了大量的存储空间,这导致转账效率降低和交易打包成本增加。为了解决这个问题,隔离见证(SegWit)技术被引入,它的核心思想是将见证数据从主要的交易数据中分离出来,并单独存储。这样做的结果是优化了存储空间的使用,从而提高了交易效率并减少了成本。
这样,原有的 1M 大小区块不变的情况下,每个区块可以容纳的交易更多,而隔离见证数据(也就是各种签名脚本)则可以占用额外的 3M 空间,为 Taproot 脚本指令的丰富奠定了存储基础。
Taproot 是比特币网络的一个重要软分叉升级,旨在提高比特币脚本的私密性、效率,以及智能合约的处理能力。这次升级被认为是自 2017 年 SegWit 升级之后的一个主要进步。
这次 Taproot 升级包括了三个不同的比特币改进提案(BIP):Taproot(默克尔抽象语法树, MAST)、Tapscript,以及一个全新的多签友好的数字签名方案,称为「Schnorr 签名」。Taproot 的目的是为比特币用户提供多种好处,包括提高交易的私密性和降低交易成本。此外,它还将增强比特币在执行更复杂交易方面的能力,从而扩展其应用范围。
Taproot 更新直接影响了 3 个生态:一个是 ordinals 协议,它利用了 Taproot 的 script-path spend scripts 脚本来实现附加数据;另一个是闪电网络升级为 Taproot Asset,从简单的点对点 BTC 支付进化为点对多且支持发行新的资产;还有一个就是新提出的 BitVM,通过 Taproot 中的 op_booland 和 op_not 来把 bool 电路「蚀刻」到 Taproot 脚本里,从而实现智能合约虚拟机功能。
Ordinals 是 Casey Rodarmor 在 2022 年 12 月发明的协议,它为每个聪(Satoshi)赋予独特序列号,并在交易中追踪它们。任何人都可以通过 Ordinals 在 UTXO 的 Taproot 脚本中附加额外的数据,包括文本、图片、视频等。
熟悉 Ordinals 的朋友一定知道:比特币总量是 2100 万个,每个比特币包含 10^8 个 Satoshi(聪),所以比特币网络上一共有 2100 万 *10^8 个聪,Ordinals 协议会将这些聪区分出来,每个聪都有一个唯一的编号。这是理论上可以做到的,但是实际上做不到。
因为 BTC 网络出于抵御粉尘攻击的原因,转账有一个最少 546 聪(segwit 最少 294 聪)的限制,也就是不可以 1 聪 1 聪的转账,根据转账的地址类型,至少要转 546 聪或 294 聪,而根据 Ordinals 先进先出的编号理论,至少每个区块的 1 号~294 号聪是不可分割。
所以所谓的铭刻,并不是铭刻在某个聪上的,而是铭刻在一笔交易的脚本中,而这笔交易至少要包含 294 聪的转账,然后由中心化的 indexer(比如 unisat)来追踪和识别这 294 聪或 456 聪的转移情况。
原则上 Taproot 脚本的花费只能从现有的 Taproot 输出中进行,所以铭文理论上应该是通过一个两阶段的提交 / 揭示程序来进行的。首先,在提交交易中,创建一个基于 script path spend 的内容的 Taproot 输入,并在输出中指明花费 / 掲示的签名条件。其次,在揭示交易中,由提交交易创建的输出被花费,揭示链上的铭文内容。
不过在现实的 indexer 场景中,并不十分关注掲示交易的作用,而是直接在输入脚本中读取由一个 OP_FALSE OP_IF ... OP_ENDIF 组成的脚本片段,从其中读取铭文的内容。
因为 OP_FALSE OP_IF 的指令组合会导致该段脚本不会被执行,所以可以在其中存储任意内容的字节,而不影响原本脚本的逻辑。
一个包含字符串「Hello, world!」的文本铭文被序列化如下:
OP_FALSE OP_IF OP_PUSH "ord"OP_1OP_PUSH
"text/plain;charset=utf-8"OP_0OP_PUSH "Hello, world!"OP_ENDIF
Ordinals 协议本质上就是将这一段代码序列化到 Taproot 脚本里面。
我们从链上找一笔交易来详细说明 ordinals 的编码原理:
https://explorer.btc.com/btc/transaction/885d037ed114012864c031ed5ed8bbf5f95b95e1ef6469a808e9c08c4808e3ae
我们可以查看这个交易的详细信息:
我们对 witness 字段从 0063(OP_FALSE OP_IF)开始的编码进行分析,可以了解序列化的编码内容:
所以只要我们能把这见证脚本中的这部分的代码解码出来,就能知道铭刻的内容了。这里编码的是纯文本信息,其他数据比如 html、图片、视频等也都是类似的。
理论上你也可以定义自己的编码内容,甚至是只有自己知道的加密内容,只不过这些内容不能在 ordinals 浏览器中显示。
2023 年 3 月 9 日,一位名叫 domo 的匿名 Twitter 用户在推特上发布了一条推文,在 Ordinals Protocol 之上创建一个同质化代币标准,称之为 BRC20 标准。这个想法是可以通过 Ordinals 协议将 JSON 字符串数据刻在 Taproot 脚本中,以部署、铸造和传输同质化的 BRC-20 代币。
图 1:BRC-20 代币的卑微开端(domo 关于该主题的第一个帖子)
来源:Twitter(@domodata)
图 2:BRC-20 代币可能的三个初始操作(p = 协议名称,op = 操作,tick = 股票代码 / 标识符,max = 最大供应量,lim = 铸造限制,amt = 数量)
来源:https://domo-2.gitbook.io/brc-20-experiment/,币安研究
Token 的发起方通过 deploy 将 brc20 代币部署上链,然后参与者通过 mint 来几乎无成本的获取 Token(只有矿工费),当 mint 数量超过 max 后,mint 铭文的铭刻会被 indexer 认为是无效的。这之后,拥有 Token 的地址可以通过 transfer 铭文来转移 Token。
值得注意的是,Ordinals 的创始人 Casey,对 BRC-20 的交易占据了 Ordinals 协议的大部分比例非常不爽。他曾公开表示 BRC-20 给他创造的 Ordinals 带来了一堆垃圾。所以,Casey 团队公开发信,让币安把 ORDI 代币介绍中的 Ordinals 删掉,他不想让 Ordinals 协议和 ORDI 扯上关系。
BRC20 swap
目前铭文交易最大的市场、indexer 以及钱包供应商 unisat 针对 BRC20 的交易提出了 BRC20 swap 协议,现在已经可以允许早期用户进行试用。
之前的铭文交易,只能通过一种叫做 PSBT(部分签名的比特币交易)的方式来进行,和 Opensea 的链下签名方案类似,通过中心化的服务来「撮合」买卖双方的签名。这就导致 BRC20 资产只能像 NFT 资产那样通过挂单方式来交易,流动性和交易效率都很低。
brc20 swap 通过在 brc20 协议的 json 串中,引入了一种叫模块的机制,这个模块中可以部署一套类似智能合约的脚本。以 swap 模块为例,用户可以通过 transfer 将 BRC20 锁入模块中,也就是发起一笔给自己的转账交易,但是交易中的铭文被锁在模块中,用户在完成交易,或撤出 LP 后,可以发起一笔交易,再把 brc20 代币提取出来。
目前,brc20 swap 采用黑模块的扩展模式运行,黑模块是出于安全考虑,在未经共识和验证的情况下,通过模块中的资金总和来确定用户可以提取的资金,也就是任何用户不能提取超过锁入模块资产总和的资产。
当黑模块的行为被用户理解和执行,逐步变得可靠,逐渐被更多索引者接受后,产品从黑模块过渡到白模块,达成共识升级。用户也就可以自由充提资产。
此外,因为 brc20 协议乃至整个 Ordinals 生态依然处于早期,Unisat 占据较大影响力和声誉,其为协议提供了完整的交易和余额查询等索引服务,有一家独大的中心化风险。其模块化运行的架构,使得更多服务商可以参与进来,从而实现索引更加去中心化。
BRC420
Brc420 协议由 RCSV 开发。他们在原有铭文的基础上,增加了递归索引的扩展。通过递归的方式定义了更复杂的资产格式。同时,Brc420 在单个铭文的基础上建立了使用权和版税之间的约束关系。当用户 mint 资产时,需要给创作者支付版税,并且拥有一个铭文时可以分配其使用权并为其设定价格,此举可激励 Ordinals 生态更多创新。
Brc420 的提出为铭文生态提供了更广阔的想象空间,除了可以通过递归引用构建更复杂的元宇宙外,也可以通过代码铭文的递归引用,来构建智能合约生态。
ARC20
ARC20 代币标准是由 Atomicals 协议提供的,在这个标准中,「原子」是基本单位,构建在比特币的最小单位聪(sat)之上。这意味着每个 ARC20 代币始终由 1 个 sat 支持。此外,ARC20 还是首个通过工作量证明(PoW)铭文铸造的代币协议,允许参与者通过类似挖掘比特币的方式直接挖掘铭文或 NFT。
将 1 个 ARC20 代币等同于 1 个 sat 带来了多个好处:
1. 首先,每个 ARC20 代币的价值永远不会低于 1 个 sat,这使得比特币在此过程中充当了一种「数字黄金锚定」的角色。
2. 其次,验证交易时只需查询与 sat 相对应的 UTXO,这与 BRC20 需要链下账本状态记录和第三方排序器的复杂性形成对比。
3. 此外,ARC20 的所有操作都可以通过比特币网络完成,不需要额外的步骤。
4. 最后,由于 UTXO 的可组合性,理论上可以实现 ARC20 代币与比特币的直接交换,这为未来的流动性提供了可能性。
Atomicals 协议为 ARC20 代币设置了 Bitwork Mining 的特殊前缀参数。代币发行者可以选择特殊前缀,而用户要通过 CPU 挖矿计算出匹配的前缀后,才能获得铸造该 ARC20 代币的资格。这种「一 CPU 一票」的模式与比特币原教旨主义者们的理念相符。
铭文看上去只是一段「无害」的文本上链,并通过中心化的 indexer 来解析,似乎安全问题只是中心化服务上的安全考虑,但在链上安全方面,还是需要注意以下几点:
1. 增加节点负担
铭文会增加比特币区块的大小,这会增加节点在网络传播、存储和验证区块时所需的资源。如果铭文过多,会降低比特币网络的去中心化程度,使网络更容易受到攻击。
2. 降低安全性
铭文可以用于存储任何类型的数据,包括恶意代码。如果恶意代码被添加到比特币区块中,可能会导致网络安全漏洞。
3. 交易需要构造
铭文的交易需要进行交易的构造,并且关注 ordinals 的先入先出规则,以防止由于疏忽导致铭文的索引性被破坏。
4. 买卖存在风险
铭文的交易市场,不论是 OTC 还是 PSBT,都存在资产损失风险。
以下是一些具体的安全问题:
1. 孤块率和分叉率增加
铭文会增加区块的大小,这会导致孤块率和分叉率增加。孤块是指没有被其他节点承认的区块,分叉是指网络中存在多个竞争的区块链。孤块和分叉会降低网络的稳定性和安全性。
2. 攻击者篡改铭文
攻击者可以利用铭文的开放性进行篡改攻击。
例如,攻击者可以将铭文中存储的信息替换为恶意代码,从而在渗透进 indexer 的服务器或通过木马入侵用户设备。
3. 钱包使用不当
如果钱包使用不当,钱包不能索引铭文的情况下,很可能错误的转移走铭文,导致资产损失。
4. 钓鱼或诈骗
攻击者可能通过假冒的 unisat 等 indexer 网站,来诱导用户进行铭文交易,从而窃取用户资产。
5. PSBT 签名疏漏
Atomicals Market 曾经因为错误的签名方法使用,而导致用户资产受损。
相关阅读:
<The Analysis of the Atomicals Market User Asset Loss>
https://metatrust.io/company/blogs/post/the-analysis-of-the-atomicals-market-user-asset-loss
为了解决这些安全问题,可以采取以下措施:
1. 限制铭文的大小
可以限制铭文的大小,以减少对节点负担的影响,这一点文章开头提到的 Luke 已经在做了。
2. 对铭文进行加密
可以对铭文进行加密,以防止恶意代码的攻击。
3. 使用可信的铭文来源
可以使用可信的铭文来源,以防止签名问题和被钓鱼。
4. 使用支持铭文的钱包
使用支持铭文的钱包来进行转账活动。
5. 注重铭文代码及相关脚本的审核
在 brc20-swap 及递归铭文的新型实验中,由于代码和相关脚本的引入,需要确保这些代码及脚本的安全性。
从技术和安全的角度说,比特币铭文本质上还是一种规则绕过的漏洞,taproot 脚本并不是为了存储数据而出现的,其安全性也存在一些问题。Luke 对 bitcoin core 代码的修改从安全角度来说是正确的。Luke 并未对比特币的共识层进行直接修改,而是选择调整 Spam Filter(策略过滤器)模块,使得节点在接收到 P2P 广播消息时,能够自动过滤掉 Ordinals 交易。在这个策略过滤器中,有多个名为 isStandard() 的函数用于检查交易的各个方面是否符合标准。如果交易不符合标准,节点接收到的这笔交易将会被迅速丢弃。
换言之,尽管 Ordinals 交易最终还是可以被加入区块链,但大多数节点不会将这类数据加入交易池,这将增加 Ordinals 数据被愿意将其打包上链的矿池接收的延时。然而,如果某个矿池广播了一个包含 BRC-20 交易的区块,其他节点仍然会对其进行认可。
Luke 已经在 Bitcoin Knots 客户端中推出了对策略过滤器(policy)的修改,并且计划在 Bitcoin Core 客户端中引入类似的更改。在这次修改中,他引入了一个新的参数,名为 g_script_size_policy_limit,用于在多个不同的位置限制脚本的大小。这一改动意味着在处理交易时,脚本大小将受到额外的限制,影响着交易的接受和处理方式。
目前,该参数的默认值是 1650Bytes,任何节点客户端都可以在启动时通过参数 -maxscriptsize 来设置:
不过即使代码更新,距离矿工节点全部更新为新版本还有很长的一段时间,这段时间,铭文社区的创新者们应该可以创造出更安全的协议。
Metatrust Labs 通过链上数据和资产追踪,在 metaScore 平台上已经对铭文投资风险进行了评分和监控,同时在 metaScout 平台上也推出比特币网络监控的规则引擎,可以帮助投资者监控比特币铭文的实时数据。
这一期,我们探索现在热门的铭文生态的技术原理和可能存在的安全问题,下一期,我们将为大家带来更加复杂的 Taproot 电路蚀刻技术——bitVM,敬请期待。