Taproot 升级对比特币脚本限制的放宽,从技术上让基于 Taproot 的各类协议的制定打开的大门

作者:Mtyl

原用标题:BTC L2 研究

封面:Photo by Shubham’s Web3 on Unsplash

本文于 2023 年 4 月在 BRC-20 刚兴起时写于 ABCDE Capital,分为六个部分:

  1. 比特币交易与脚本技术原理
  2. Segwit 和 Taproot 升级
  3. Ordinals 协议与 BRC-20
  4. 比特币 Rollup
  5. 闪电网络相关进展
  6. 阶段性研究小结 &讨论

BTC 生态与 BTC L2

狭义的 L2:把比特币当做 DA 层,在上面构建 Rollup

广义的 L2:泛指所有在 BTC 生态中除了 BTC 原初转账交易以外的部分,包括 Lightning Network、Sidechain,甚至包括 Ordinals 和 BRC-20

(类比:Polygon POS 算不算 ETH L2?)

要详细理解 BTC Rollup 究竟是怎么做的,对比特币脚本和两个关键升级的理解非常重要。

一、比特币交易与脚本技术原理

交易事务的生命周期

交易的生命周期从被创建出来的时候就开始了,基础上和支票一样:比如,我写一张 Alice 送 Bob 100 元的支票,而你写一张 Alice 送 Bob 100 元的支票,这在还没有签名之前,两张支票会长的一个模样。所以任何人都可以做创建交易这件事,因为刚创建出来的交易只记载着发送方要给接收方多少比特币而已。

而交易创造出来之后,第二步检验就是签名,跟支票一样的签名需要发送方亲自过来执行,这个步骤别人就无法代替你了,例如 Alice 送 Bob 100 比特币的交易就一定要是 Alice 亲自签名,否则会出问题。一旦完成签名之后这个交易就有所有需要的信息了,准备发送到比特币网路。

第三步步骤就是签过名的交易发出去。

交易结构

交易由两个部分组成,分别是输入和输出,而输出由一个叫做锁定脚本的保护起来,有了这个输出的人就可以提供密匙(私钥)来产品解锁脚本组成输入把它花掉。

最经典的比特币交易范例拆解如下:

01000000  // 4 bytes version

/* input */

01  // number of inputs
e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c  // tx id
00000000  // input index
00  // unlocking script length
ffffffff  // unlocking script

/* input end */
/* output */

02  // number of outputs
a025260000000000  // amount
19  // locking script length
76a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac  // locking script
5062250000000000  // amount
19  // locking script length
76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac  // locking script

/* output end */

00000000  // 4 bytes locktime

输出

基础上交易输出就是一个不可分割可以让所有使用者花钱的比特币集合,也就是 UTXO(未花费的交易输出):

  1. amount,这个输出是有多少比特币的意思,但单位是 satoshi,比特币值的最小单位
  2. locking script,它确定义这个输出要可以被花费所需要的足够的条件,就是一个锁来保护这个输出不会被其他人花费

回到上面比特币的范例交易拆解来看,output 一开始会有 1 byte 的大告告诉我们总共有几个 output,这边范例是 2 个,接下来来 amount 的部分原因是这个旁边是小端,00e40b5402000000 转成 big endian 的话就是 10000000000 satoshi。最后是锁定脚本 locking script。

输入

一般会先有 1 个字节的大小告诉我们在这个交易中有多少个输入,可能不只是一个输入的原因比如我手上有很多小额的 UTXO 要凑起来买一个贵的东西。

接下来就是告诉我们要去 transaction id 是多少的第几个输出找到这个 UTXO,最后就是解锁脚本。

脚本语言

基于栈的语言 Script:

2 3 OP_ADD 5 OP_EQUAL

比特币语言是图灵不完备的,主要是因为它不支持 “循环”。

在图灵完备的语言中,如 Python、Java 或 C++,程序员可以编写循环,使得一段代码可以反复执行,直到满足某个条件。然而,比特币脚本语言没有这个特性。

这样做的原因是安全性和预测性。在一个公开、无信任的网络中(如比特币),允许任意复杂的程序(尤其是那些可以无限运行的程序)可能会带来安全风险。恶意的攻击者可能会试图通过提交一个设计成无限循环的交易来拖慢或卡住网络。而因为比特币脚本语言是图灵不完备的,所以这种攻击是不可能的。

此外,由于比特币脚本语言的简单性,它可以更容易地进行形式化验证。这意味着,你可以通过检查一段脚本,来准确地预测它的行为,而无需实际执行它。这在设计安全和可靠的金融系统时非常重要。

交易类型与脚本语言

支付公钥哈希 (P2PKH)

绝大部分的比特币交易都是采用这个脚本,就像是 Alice 的地址送钱给 Bob 的地址这种交易。P2PKH 的锁定脚本会长的像这样

OP_DUP OP_HASH160 < 公钥散列> OP_EQUAL OP_CHECKSIG

上面的 Public Key Hash 其实就等同于拥有者的地址,只是还有没有做 Base58Check 编码的版本,这也是为什么他叫做 P2PKH,因为他是付钱给 Public Key Hash,说穿了就是付钱给一般的地址。而如果需要花费这个 UTXO,输入的解锁脚本只要长的像

< 签名> < 公钥>

所以我们把 P2PKH 的解锁脚本和锁定脚本接起来就会长这样。

整个验证过程长这个样子:

  • 一开始先依顺序把签名和公钥推送上去堆栈。
  • 再来看 DUP
    • 把栈顶的东西,也就是公钥,多次制作一次。
  • 接下来是 HASH_160HASH160
    • 把 stack 最上面的公指针 pop 出来,做一次,再 push 返回 stack 上面。
  • 接下去遇到 Public Key Hash,当然是直接 push 上去 stack。

P2PKH 要在做两件事情

  1. 你要给出公钥来证明,这个 UTXO 所属的地址就是你的,因为公钥可以生成唯一的地址(这边其实是 Public Key Hash,但意思和地址一样拉)。
  2. 除了给公钥还不够安全,你还要再给一个签名证明你手上握有密钉,因为签名的产品需要密钉,但试验证明却只需要公钉。

支付公钥 (P2PK)

他其实很简单就是简化版的 P2PKH,他的 locking script 长的像下面这样

< 公钥 A> OP_CHECKSIG

而他对应的解锁脚本长的像这样

< 私钥 A 签名>

他直接把公钥放在 locking script 了,所以你的 unlocking script 不用再给公钥了,给 Signature 来验证就好了。

数据输出(OP_RETURN)

第三个标准类型的交易叫做数据输出,他就是我们上面所说不能花钱的输出,它的用途是拿来记录的,因为区块链有公开透明不可被窥改的好的地方,因此这种状态的 output 就产生了,纯的资料记录不用于转钱。而他的脚本(严格要说的是锁定脚本)就长这样

OP_RETURN < 数据>

他不能被解锁所以不会有解锁脚本,又因为这种输出不能被花费,所以他也不会计算 UTXO,在记忆体里的那个资料库也不会有这种输出。

但是,OP_RETURN 后数据的长度被限制在 80 字节,因为中本聪并不希望大家把 BTC 宝贵的区块空间单纯用来存数据。

多重签名

多签:现在有一个脚本他是由 N 个公钥组成的,而且如果要解锁他所保护的 UTXO 只需其中 M 个提供签名即可。而 M 在比特币里目前最大限制为 15 个公钥,他的锁定脚本长的像这样

M < 公钥 1> < 公钥 2> ... < 公钥 N> N OP_CHECKMULTISIG

例如 2–3 多重签名 就如下

2 < 公钥 A> < 公钥 B> < 公钥 C> 3 OP_CHECKMULTISIG

然后要解锁他的解锁脚本就会是

OP_0 < 签名 B> < 签名 C>

支付给脚本哈希 (P2SH)

从上面的多签来延展,如果现在是 2–5 的架构 locking script 会有多长,如果是 3–7 呢?locking script 太长会造成什么负担?我们知道 locking script 是用来保护的保护 UTXO 不被盗用的,locking script 的增长会导向 UTXO 的肥大,而我们刚说过 UTXO 为了方方便会存在昂贵的记忆体里面,因此如果 UTXO 越来越大比特币节点对记忆体的消费也会越来越多凶猛,因此 P2SH 就登场了。

P2SH 的作用其实就是把很长的 locking script 做一次 hash 之后来代替他,来缩小 locking script, 把这部分移到 Unlocking Script。简单来说差异如下图

另外一个 P2SH 很重要的特点是,因为 locking script 现在夹住的是一个经过 HASH160 的产物,这个跟生成地址的过程是一样的,如果再把他做 Base58 检查编码,也可以得到一种地址,就是大家很常说的 multisig 地址,这种地址固定 3 开头,他跟一般的地址可以做到的事情一样,别人可以送钱到这个地址,而这个地址也可以转钱出去,差别只在这种地址 送钱的交易签名时需要 redeem script 并且可能不仅仅是一个签名的参与。

总结 P2SH 来说他有以下几个优点

  1. 虽然 input 和 output 都会在区块链上,但是因为 redeem script 被放到 input 了,所以也只有等到被花费时才会增加区块链的大小,而不是现在就立即增加大小。
  2. 他可以将送钱目标改成一种 3 开头的地址,而不是一个显示的多签地址,这样可以保护那些没有参与拿钱的人的隐私
  3. 他可以让手续费的压力转移到拿钱的人身上

二、Segwit 和 Taproot 升级

Segwit-BIP141

简单理解:Segwit 就是想方设法地把 scriptSig 给移出去,从而实现区块扩容 1MB→4MB

进一步理解:

中本聪之前的代码中写到,在审核统计区块大小的时候,每一个区块大小不超过 1M

隔离见证就是把脚本签名 (scriptSig) 信息从基本结构 (base block) 里拿出来,放在一个新的数据结构当中。做验证工作的节点和矿工也会验证这个新的数据结构里的脚本签名,以确保交易是有效的。

当审核统计区块大小不能超过 1M 的时候。脚本签大小不会被计算在内。因此这是一个软升级

技术原理:

BIP141 选择在前一笔输出的 locking script 动点手脚,只需要看到 scriptPubKey 是 0x00 开头,他就被赋予了新的意义。

P2WPKH

witness: <signature> <pubkey>
scriptSig: (empty)
scriptPubKey: 0 <20-byte-key-hash>
              (0x0014{20-byte-key-hash})

全名是 public key 被放入了 witness program,因此输入的 scriptSig 就可以是空的。简单来说,scriptPubKey 的开头为 0 让脚本引擎知道这是一个 segwit 交易,而接下来的 20 字节让脚本引擎更明确知道这是一个 P2WPKH 输出,因此脚本引擎就会去见证程序拿签名和公钥,最后的验证就和普通 P2PKH 一样了。

为什么旧版本能兼容:

如果你不升级,你看到的就是一个空的输出签名,表面含义是 “这是个谁都能花的输出”。但你真想花的时候,大部分升级过的节点会检查你提供的签名脚本,这是旧版本客户端所无法提供的。

Segwit 采用率已经达到了 96%

Taproot BIP340-342

Taproot 是 2021 年比特币的一次升级,它是基于 Segwit 的。

这次升级其实夹了三个主要的变化,而且其中因为要支持 Schnorr 签名,所以比特币的脚本系统势必要做一些改动(BIP- 342 ),在废弃一些低效率的操作码和新增加一些新的操作码的同时,Bitcoin Core 也顺便取消了 Bitcoin script size 的限制

(来自 BIP-342 维基)

从脚本视角上来看,Taproot 继承了 Segwit 脚本,给了一个新的脚本 version,如果看到新的版本号那么这就是 Taproot 脚本。

Taproot 脚本取消了 script size 的限制,很大的增加比特币能做到的事。这个改动倒是给了把图片放上去比特币一个很好的解决方法,以下是 Ordinals 协议的脚本示例:

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

上面这段脚本拿掉中间全部的操作码跟数据的话,就是一般标准的签名,而中间这段脚本在做什么?

  • OP_FALSE 会将一个空数组 push 到栈中,注意这边是有 push 东西的,只是它是空的。
  • OP_IF 检查堆栈顶部,如果为真才会做接下来的事情,因为前面 OP_FALSE 的动作,导致这个如果不会立。
  • 接下来是 OP_PUSH … 等一系列操作都会被忽略,因为为上一个如果条件没有达成。
  • OP_ENDIF 结束这个 if 块。

可以看出来中间这些操作因为 OP_IF 一定不会成立,所以等等什么状态都没有改变,于是就可以把图片的完整资料都放在 OP_IF 里面而不是影响本比特币脚本的验证。因此在 taproot 升级后,脚本现在是没有多大限制了。所以只需要交易的大小关于块的大小 (4 MB),脚本你要多少都可以,也就是说我们可以达到类似 OP_RETURN 的效果,把无关的资料放上比特币,还没有 80 字节的大小限制。

Taro 协议

Taro 是由 Lightning Labs 开发的一种新的 Taproot 支持的协议,它允许用户在比特币区块链上创建资产,然后通过闪电网络发送,以最小的成本进行快速,大量的交易。它既可以用来发行同质化的资产(比如稳定币),也可以发行非同质化的、独一无二的代币(比如 NFT,或者说收藏品)。

Taro 的核心是利用比特币网络的安全性和稳定性加上 Lightning 的速度、可扩展性和较低的成本。它旨在改变数字资产大多在放在其它区块链上的情况。

Taproot 采用率, 目前已经超过了 50%

三、Ordinals 协议与 BRC-20

(更多介绍参考前面的 insight weekly 内部研究分享)

Ordinals 提出了序数理论,给每一个 satoshi 打上了标记,并把每笔交易输出的 Taproot 脚本绑定到输出的第一个 satoshi 的序数上,称为铭刻 inscription,从而方便了 Taproot 脚本的标记,增强了 Taproot 脚本的可追踪性,而让 Taproot 脚本具备了 NFT 属性。

也就是说,Ordinals 本质上是一个解析规则系统,如果你所用的钱包/客户端不支持它,你可能会无意间把 Ordinals 协议认为的 “铭刻” 有 Taproot 脚本 (NFT)的 satoshi 给当做普通的 satoshi 花费掉。

BRC-20 创造了一种代币发行和转移的 Ordinal 铭文规则。理论上,可以设计各种各样的代币标准,可以基于 Ordinals(比如 ORC-20)也可以不基于(比如 Taro)。BRC-20 从技术上难以说有很强的特殊性和优势。

四、比特币 Rollup

思路:利用 Taproot 脚本,把比特币作为 DA 层

Rollkit

Taproot 脚本中,用” 信封 “包装 Rollup 数据

“Inscription content is serialized using data pushes within unexecuted conditionals, called an "envelopes". Envelopes consist of an OP_FALSE OP_IF … OP_ENDIF  wrapping any number of data pushes. Because envelopes are effectively no-ops, they do not change the semantics of the script in which they are included, and can be combined with any other locking script.”

OP_FALSE
OP_IF
	OP_PUSH "block"
	OP_1
	OP_PUSH $ROLLUP_BLOCK_HEIGHT
	OP_0
	OP_PUSH $BLOCK_DATA_PORTION
	...
OP_ENDIF

BTC Rollup 项目进度:提供了读/写 Rollup 数据到 Bitcoin 的模块

  • https://github.com/rollkit/bitcoin-da
  • Rollkit 本体项目主要提供 Sovereign Rollup 的 SDK,其官方文档上主要提供的说明是 Ethereum-based sovereign rollup that uses Cosmos-SDK and Ethermint + Celestia's Mocha testnet or Arabica devnet.
  • 目前没有发现有链真的用它的 BTC Rollup 工具

Trustless Computer

  • L2 用 Optimism 的开源代码,L1 用比特币的 DA
  • 项目进度:
    • 链已经在运行了,甚至有了区块浏览器;
    • 但并没有给出其 BTC DA 的具体实现,也没有说明这些区块被压缩打包到了 BTC 的哪个位置
    • 推测:目前还是一条 fork OP 的单机链,可能之后会公布更多细节?

BIOP

也是要用 OP Rollup 去做 BTC L2

但找不到项目的技术文档,项目的 github 上只有比特币代码

项目正在 IDO,可以买它的币……

五、闪电网络相关进展

闪电网络在 BTC 链上只会留下一个多签,并没有把 DA 放到 BTC 链上。

现在的闪电网络服务的提供方主要基于 2020 年成型的 OMNI 协议,那个时候还没有 Taproot 升级,也支持不了 Ordinals。这就是为什么 BRC-20 和 Ordinals 炒作热潮的时候和闪电网络没什么关系。

不过让闪电网络支持 Taproot、Ordinals,本质上是一个工程标准的兼容问题。OMNIBolt 称自己即将推出支持 BRC-20 的闪电网络。也咨询了其它技术人员,这个工作量大概是 1-2 个月。

六、阶段性研究小结 &讨论

  • Taproot 升级对比特币脚本限制的放宽,从技术上让基于 Taproot 的各类协议的制定打开的大门
  • BRC20 的出圈,让更多人看到了 BTC 作为叙事的潜力
  • 可以预见的是,未来一段时间会有很多基于 Taproot 的新” 实验 “出现
  • 怎么关注:更多 BTC Rollup 相关的实验;闪电网络支持 Ordinals 等协议以后的发展
  • BRC-20
    • Taproot 相关客户端、钱包数据直线上升;符合矿工利益
    • BRC-20 过于依赖外部中心化解析,相关基础设施可能是机会?
    • 行业本质还是造资产
  • BTC 衍生项目技术不可能超过 ETH,评估项目的思路和其它公链生态不一样(如 SOL、move),不能只看技术先进性
  • 闪电网络为什么不能起来?因为 BTC 就不是用来支付的
  • BTC NFT 可能有一波炒起来的机会

免责声明:作为区块链信息平台,本站所发布文章仅代表作者及嘉宾个人观点,与 Web3Caff 立场无关。文章内的信息仅供参考,均不构成任何投资建议及要约,并请您遵守所在国家或地区的相关法律法规。