quentangle

Posted on Feb 18, 2023Read on Mirror.xyz

深度解析比特币NFT协议Ordinals:技术实现

如果你觉得本文有价值,欢迎转发。

关注作者推特:团长(https://twitter.com/quentangle_

我们在上一篇文章中介绍了Ordinals实现比特币NFT的基本原理,简单来说就是建立一套序数编号系统,给比特币中的每一个最小单位Satoshi做出区分,然后再将一下额外信息,铭刻(附加)到这些有编号的Satoshi上,从而在FT的基础上实现了NFT的功能。

今天我们继续深挖一下Ordinals得以实现的一些技术基础,以及ordinals的实现方式。

比特币脚本给Ordinals铭文提供了技术基础

比特币脚本(Bitcoin Script)是比特币网络内置的一套编程环境,它通过一些简单的操作码组成的一套基于堆栈的脚本代码,让比特币实现了可编程支付的功能。比如最基础的P2PK(Pay to Public Key)支付方式,就是通过脚本定义了如何向公钥支付的检查过程。

https://learnmeabitcoin.com/technical/p2pk

比特币脚本并不是一个图灵完备的编程语言,他的定义和功能主要是为完成各种支付场景而设置的,并不能更加复杂的业务逻辑。而且Bitcoin社区对于增加新的OP_CODE相当的克制。也是因为无法给予比特币脚本的可编程性做出更加复杂的功能,当时比特币社区对重要成员Vitalik才会想要构建一个可编程性更加完善的区块链,以支持更加复杂的去中心化应用的开发,这也是Ethereum诞生的原因之一。当然这是另一个故事了。

Ordinals铭文内容完全在链上,存储在taproot script-path spend scripts脚本路径的花费脚本中。Taproot脚本对其内容的限制非常少,而且还能得到见证者的折扣,使铭文内容的存储相对经济。Taproot是即隔离见证segwit之后比特币扩容的最新阶段,比特币的扩容是为了提高比特币的交易量,但是客观上也为ordinals的出现创造了条件。

比特币扩容给Ordinals铭文创造了实现条件

从技术角度来看,越是去中心化程度高的区块链,效率通常也是最低的。时至今日比特币的单个区块大小依然是1M,和中本聪挖出的第一个区块大小一样。比特币社区没有直接走加大区块大小的这种简单粗暴的方案,而是走了隔离见证这个不需要硬分叉的方式。

隔离见证

在比特币的每笔交易信息分为两个部分:基础交易数据+见证数据,前者记录账户资金结余,后者是验证用户身份。对于用户而言,最关心的是账户资金结余等事关资产的核心信息,验证用户身份环节无需在交易中占据过多成本。简单来说,转账接收方只需要确认资产可用,无需明了发起方详细信息。但是,在比特币交易结构中,见证数据,也就是签名信息占用了大量的存储空间,进而耽误了转账效率、增加了打包成本。隔离见证技术,就是将见证数据从交易信息中提出来单独存储。

Taproot

Taproot是一次优化比特币脚本的软分叉,提升私密性、效率以及网络处理智能合约的能力。这是自2017年SegWit升级之后,公认的比特币重大升级。

Taproot升级由3项不同的比特币改进提案(BIP)组成,其中包括:Taproot、Tapscript及其核心,即名为“Schnorr签名”的全新数字签名方案。Taproot旨在为比特币用户带来诸多好处,例如提升交易私密性和降低交易费用。还将让比特币执行更多复杂的交易,从而拓宽应用场景。ordinals协议就是利用的taproot script-path spend scripts脚本来实现的附加数据,所以想要使用ordinals首发铭文,需要使用P2TR脚本类型的地址。

闪电网络

闪电网络和ordinals协议的技术需求并无直接关系,但是因为ordinals地址是支持闪电网络的比特币地址,且闪电网络可以降低交易费用,加快交易确认速度,所以可以用在铭文的铸造过程。

铭文在交易中的编码方式

由于taproot脚本的花费只能从现有的taproot输出中进行,所以铭文是通过一个两阶段的提交/揭示程序来进行的。首先,在提交事务中,创建一个提交给包含题词内容的脚本的taproot输出。其次,在揭示交易中,由提交交易创建的输出被花费,揭示链上的铭文内容。

铭文内容在未执行的条件中使用数据推送进行序列化,称为 "封装"。包络由一个OP_FALSE OP_IF ... OP_ENDIF组成,包裹着任意数量的数据推送。因为封套实际上是无操作的,所以它们不会改变包含它们的脚本的语义,并且可以与任何其他锁定脚本相结合。

一个包含字符串 "Hello, world!"的文本铭文被序列化如下:

OP_FALSE
OP_IF
	OP_PUSH "ord"
	OP_1
	OP_PUSH "text/plain;charset=utf-8"
	OP_0
	OP_PUSH "Hello, world!"
OP_ENDIF

Ordinals协议本质上就是将这一段代码序列化到见证脚本里面。

我们用一个例子来对编码进行说明,这是编号为139342的铭文,它将一个时间字符串“Fri Feb 17 05:02:18 PM CET 2023”铭刻到编号为1324061169091174的sat上,下面是它在ordinals浏览器的链接。

https://ordinals.com/inscription/fcd5e53300cafa578c79c79a4718642fde25c8da9cdf88eb6af0dff4df2c5801i0

我们可以在mempool.space中查看这个交易的详细信息:

我们对witness字段对第二部分进行编码分析,可以了解序列化的编码内容:

所以只要我们能把这见证脚本中的这部分的代码解码出来,就能知道铭刻的内容了。这里编码的是纯文本信息,其他数据比如html、图片、视频等也都是类似的。

理论上你也可以定义自己的编码内容,甚至是只有自己知道的加密内容,只不过这些内容不能走ordinals浏览器中显示。

总结

以上就是我们对ordinals协议的技术实现做的一个简单的介绍,可以看到ordinals的可玩性和灵活性还是不错的,下一篇我们会介绍ordinals相关的工具和项目,以及未来我们可能围绕ordinals的可玩性做出哪些升级和优化。


参考:

Taproot: SegWit version 1 spending rules:https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki

Taproot: https://bitcoinops.org/en/topics/taproot/

Tapscript: https://bitcoinops.org/en/topics/tapscript/

NFT