走近 BTC:理解 BitVM 所需的背景知识(1) – 币界网

作者:Nickqiao、Faust、Shew Wang;来源:极客 web3 摘要:近期 Delphi Digital 发布了题为《The Dawn of Bitcoin Programmabilit

作者:Nickqiao、Faust、Shew Wang;来源:极客 web3

摘要:近期 Delphi Digital 发布了题为《The Dawn of Bitcoin Programmability: Paving the Way for Rollups 》的比特币二层相关技术研报, 系统的梳理了和比特币 Rollup 有关的核心概念,如 BitVM 全家桶、OP_CAT 和 Covenant 限制条款、比特币生态 DA 层、桥以及 Bitlayer、Citrea、Yona、Bob 等四大采用 BitVM 的比特币二层。

该研报虽然大体展示了比特币二层技术的大致图景,但整体比较泛泛而缺乏细节描述, 让人似懂非懂。 极客 web3 在 Delphi 研报基础上进行了展开式的深入挖掘, 尝试让更多人系统的理解 BitVM 等技术。

我们将与 Bitlayer 研究团队及 BitVM 中文社区共同开展一个名为「走近 BTC」的系列专栏,长期围绕 BitVM、OP_CAT 和比特币跨链桥等重点话题进行科普, 致力于为更多人祛魅比特币二层相关技术,帮更多爱好者铺平道路。

几个月前, ZeroSync 负责人 Robin Linus 发布了名为《BitVM: Compute Anything on Bitcoin》的文章 ,正式提出了 BitVM 的概念,推动了比特币二层技术的进展。可以说这是比特币生态最具革命性的创新之一,引爆了整个比特币二层生态,吸引了如 Bitlayer、Citrea、BOB 等明星项目的参与,为整个市场带来了生机。

之后, 更多研究人员参与改进了 BitVM,先后推出了 BitVM1、BitVM2、BitVMX、BitSNARK 等不同的迭代版本。其大致情况如下所示:

  1. Robin Linus 于去年最先提出的 BitVM 实现白皮书,就是基于虚构逻辑门电路的 BitVM 实现方案,被称为 BitVM0;

  2. Robin Linus 在后面几次演讲和采访中,又非正式的介绍了基于虚构 CPU 的 BitVM 方案(称为 BitVM1),类似于 Optimism 的欺诈证明系统 Cannon,可以用比特币脚本在链下模拟出一个通用 CPU 的效果。

  3. Robin Linus 还提出了 BitVM2,一个 Permissionless 的单步非交互式欺诈证明协议。

  4. Rootstock Labs 和 Fairgate Labs 的成员发布了 BitVMX 白皮书,与 BitVM1 类似,他们希望通过比特币脚本模拟出通用 CPU 的效果(在链下)。

Robin Linus 于去年最先提出的 BitVM 实现白皮书,就是基于虚构逻辑门电路的 BitVM 实现方案,被称为 BitVM0;

Robin Linus 在后面几次演讲和采访中,又非正式的介绍了基于虚构 CPU 的 BitVM 方案(称为 BitVM1),类似于 Optimism 的欺诈证明系统 Cannon,可以用比特币脚本在链下模拟出一个通用 CPU 的效果。

Robin Linus 还提出了 BitVM2,一个 Permissionless 的单步非交互式欺诈证明协议。

Rootstock Labs 和 Fairgate Labs 的成员发布了 BitVMX 白皮书,与 BitVM1 类似,他们希望通过比特币脚本模拟出通用 CPU 的效果(在链下)。

目前 BitVM 相关开发者生态的建设日渐明朗,周边工具的迭代完善也已肉眼可见,相比于去年,如今的 BitVM 生态已经从最初的「空中楼阁」变得「依稀可见」,这也吸引了越来越多的开发者和 VC 争相涌入比特币生态。

但对于大多数人而言,要理解 BitVM 和比特币二层相关的技术名词绝非易事,因为你要先对其周边的基础知识有系统性的理解,尤其是比特币脚本和 Taproot 等背景知识。目前网上已有的参考资料要么篇幅太长废话连篇,要么解释的不够透彻让人似懂非懂。 我们致力于解决上述问题,力求以尽可能清晰的语言,帮助更多人理解比特币二层的周边知识, 对 BitVM 体系建立起系统性认知。

MATT 和承诺:BitVM 的基础思想

首先我们要强调,BitVM 的基础思想是 MATT,含义是 Merkleize All The Things,主要指通过 Merkle Tree 这种树状的数据存储结构来展示复杂的程序执行过程,设法让比特币 Native 的验证欺诈证明。

MATT 虽然可以表达出一段复杂程序及其数据处理痕迹,但不会直接在 BTC 链上发布这些数据,因为这些数据的总体规模非常庞大。 采用 MATT 的方案只在链下的 Merkle 树中存储数据,只把 Merkle 树最顶部的摘要(Merkle Root)发布到链上。 这棵 Merkle 树主要包含三大核心内容:

  • 智能合约脚本代码

  • 合约所需的数据

  • 合约执行中留下的痕迹(智能合约在 EVM 等虚拟机中执行时对内存、CPU 寄存器产生的变更记录)

智能合约脚本代码

合约所需的数据

合约执行中留下的痕迹(智能合约在 EVM 等虚拟机中执行时对内存、CPU 寄存器产生的变更记录)


(一个简单的 Merkle Tree 默克尔树示意图 其 Merkle Root 是由图中底部的 8 个数据片段经过多层 hash 计算得到的)

MATT 方案下,只有尺寸极小的 Merkle Root 存储在链上,Merkle Tree 包含的完整数据集存储在链下,这用到了一种被称为「承诺」的思路。 这里解释下什么是「承诺」(Commitment)。

承诺类似于一种简洁化的声明 ,我们可以把它理解为一大批数据压缩后得到的「指纹」。一般而言,在链上发布「承诺」的人会声称,某些存放在链下的数据是准确无误的,这些链下数据要对应一个简洁化的声明,这个声明就是「承诺」。

在某些时候,数据的 hash 可以作为对数据本身的「承诺」,其他的承诺方案还有 KZG 承诺或 Merkle Tree 等。在 Layer2 惯用的欺诈证明协议中, 数据发布者会在链下发布完整数据集,在链上发布数据集的承诺。如果有人发现链下的数据集中存在无效数据,就会针对链上的数据承诺进行挑战。

通过承诺(Commitment),二层能够把大量数据压缩处理,只在比特币链上发布其「承诺」。当然,还要保证发布在链下的完整数据集可以被外界观测到。

目前几大 BitVM 方案如 BitVM0、BitVM1、BitVM2 和 BitVMX,基本都采用了类似的抽象结构:

1.程序分解和承诺:首先将复杂的程序分解为大量的、较基础的操作码(编译),然后把这些操作码在具体执行时产生的痕迹记录下来 (说白了就是一段程序跑在 CPU 和内存中时,整个的状态变化记录,称为 Trace)。之后,我们对包括 Trace 和操作码在内的所有数据进行整理,组织成一个数据集,然后生成该数据集的承诺。

具体的承诺方案可以有多种形式,如:Merkle 树、PIOPs(各种 ZK 算法)、哈希函数

2.资产质押和预签名:数据发布者和验证者需要通过预签名的形式,把一定金额的资产锁定在链上,并且会有限制条件。 这些条件会针对未来可能发生的情况而针对性的触发,如果数据发布者作恶,验证者可以提交证明把数据发布者的资产拿走

3.数据和承诺发布: 数据发布者在链上发布承诺,链下发布完整的数据集,验证者检索数据集并检查是否有任何错误。链下数据集中的每个部分都与链上的承诺有关联性。

4.挑战和惩罚:一旦验证者发现数据发布者提供的数据有错误,它会把这部分数据拿到链上去直接验证 (要先把这部分数据切的特别细),这就是欺诈证明的逻辑。如果验证结果显示,数据发布者的确在链下提供了无效数据,它的资产就会被挑战他的验证者拿走。

总结下就是, 数据发布者 Alice 在链下公开二层交易执行过程中产生的所有痕迹,把对应的承诺发布到链上。如果你要证明某部分数据有误,先向比特币节点证明这部分数据和链上的承诺相关联,也就是证明这些数据是 Alice 本人对外公开的,然后让比特币节点确定这部分数据有错误。

现在我们大致理解了 BitVM 的整体思路,所有的 BitVM 变体基本都脱离不了上述范式。那么接下来,让我们开始学习和理解上述流程中用到的一些重要技术,先从最基础的比特币脚本和 Taproot 以及预签名开始。

什么是 Bitcoin Script 脚本

比特币相关的知识要比以太坊的更难理解,就连最基础的转账行为都涉及到一系列概念,包括 UTXO(未花费的交易输出)、锁定脚本(也称为 ScriptPubKey)和解锁脚本(也称为 ScriptSig)。我们先对这几个主要概念进行讲解。

(一段比特币脚本代码的示例 由比高级语言更底层的操作码组成 )

以太坊的资产表达方式,更像支付宝或者微信,每次转账只是对不同账户的余额做加减法,这种方法是以账户为核心,资产余额只是账户名下的一个数字;比特币的资产表达形式更像黄金,每块黄金(UTXO)都会标记出主人, 转账实际上是把旧的 UTXO 销毁,把新的 UTXO 产生(主人会变更)。

比特币 UTXO 包含两个关键字段:

  • 数额,以「聪(satoshi)」为单位(一亿聪为一 BTC);

  • 锁定脚本,也称「脚本公钥(ScriptPubKey)」,会定义 UTXO 的解锁条件。

数额,以「聪(satoshi)」为单位(一亿聪为一 BTC);

锁定脚本,也称「脚本公钥(ScriptPubKey)」,会定义 UTXO 的解锁条件。

需要注意的是 ,比特币 UTXO 的所有权是通过锁定脚本来表达的,如果你要把自己的 UTXO 转让给 Sam,可以发起交易销毁自己的某个 UTXO,把新生成的 UTXO 的解锁条件写为「只有 Sam 可解锁」。

之后, Sam 如果要使用这些比特币,需要提交一个解锁脚本(ScriptSig),在这个解锁脚本中 Sam 要出示自己的数字签名, 证明自己是 Sam 本人。如果解锁脚本和前述锁定脚本相匹配,Sam 就可以解锁并把这些比特币再转给别人。

(解锁脚本要和锁定脚本相匹配才行)

从表现形式的角度看, 比特币链上的每笔交易都对应着多个 Input 和 Output, 每个 Input 中要声明自己想解锁的某个 UTXO,并提交解锁脚本,解锁并销毁该 UTXO;Output 中会展示新生成的 UTXO 信息,对外公示锁定脚本的内容。

比如,在一笔交易的 Input 中,你证明自己是 Sam,把别人给你的多个 UTXO 解锁,统一销毁,再生成多个新的 UTXO 并声明让 xxx 在未来去解锁。

具体而言,在交易的 Input 数据中,你要声明自己要解锁哪些 UTXO,并指出这些 UTXO 数据的「存储位置」 。这里要注意,比特币和以太坊截然不同,以太坊提供了合约账户和 EOA 账户两种账户来存储数据, 资产余额作为数字,记录在合约账户或 EOA 账户名下,统一放置在名为「世界状态」的数据库中,转账时直接从「世界状态」中对特定账户进行修改,便于定位到数据的存储位置;

比特币没有世界状态的设计,资产数据分散存储在过往的区块中(就是未解锁的 UTXO 数据,在每笔交易的 OutPut 中单独存放)。

如果你想解锁某个 UTXO,要说明该 UTXO 信息存在于过去哪笔交易的 Output 中,出示这笔交易的 ID(就是其 hash), 让比特币节点去历史记录中寻找。如果要查询某个地址的比特币余额,需要从头遍历所有区块,找出和 xx 地址关联的未解锁 UTXO。

平时用比特币钱包时,可以快速检查某地址拥有的比特币余额,很多时候是因为钱包服务自身通过扫描区块,对所有地址建立了索引,方便我们快速查询。

(当你生成一笔交易声明把自己的 UTXO 送给别人时,要根据这些 UTXO 所属的交易 hash/ID 来标记出该 UTXO 在比特币历史记录中的位置)

有意思的是, 比特币交易的结果是在链下计算完成的, 用户在本地设备上生成交易时,就要直接把 Input 和 Output 全部创建好,相当于把交易的输出结果计算完了。交易在广播到比特币网络中,被节点验证后才上链。这种 「链下计算—链上验证」 的模式与以太坊是完全不同的,在以太坊上,你只需要提供交易输入参数,交易结果由以太坊节点计算并输出。

此外, UTXO 的锁定脚本(Locking Script)是可以自定义的 ,你可以把 UTXO 设定为「某个比特币地址的主人可解锁」,该地址的主人需要提供数字签名和公钥(P2PKH)。而在 Pay-to-Script-Hash(P2SH)交易类型 中,你可以在 UTXO 锁定脚本中添加一个 Script Hash,谁能提交这个 Hash 对应的脚本原像,并满足该脚本原像中预设的条件,就可以解锁 UTXO。 BitVM 所依赖的 Taproot 脚本,用到了类似于 P2SH 的特性。

比特币脚本怎么触发

这里我们先以 P2PKH 为案例介绍比特币脚本的触发方式,只有理解了其触发方式才能理解更为复杂的 Taproot 和 BitVM。 P2PKH 全称「Pay to Public Key Hash」,在这种方案下,UTXO 的锁定脚本中会设置一个公钥 hash,解锁时需要提交对应该 hash 的公钥,这和常规的比特币转账思路基本一致。

此时, 比特币节点要确定解锁脚本中的公钥,和锁定脚本中指定的公钥 hash 能对上号, 也就是说, 要确定解锁人提交的「钥匙」和 UTXO 预设的「锁」彼此匹配。

进一步说,P2PKH 方案下,比特币节点收到交易后,会将用户给出的解锁脚本 ScriptSig,与要解锁的 UTXO 的锁定脚本 ScriptPubkey 拼接到一起,放在 BTC 脚本的执行环境内执行。下图给出执行前的拼接结果:

可能读者并不了解 BTC 的脚本执行环境,此处我们进行简单介绍。首先, BTC 脚本包含两种元素:

数据和操作码。 这些数据和操作码会按照从左到右的顺序,依次压入栈内按照指定逻辑来执行,得到最终结果(关于什么是栈 此处不展开详述 读者可以自行 Chatgpt)。

以上图为例, 左侧是某人上传的解锁脚本 ScriptSig,包含他的数字签名和公钥, 而右侧的锁定脚本 ScriptPubkey 中,包含 UTXO 创建者生成该 UTXO 时设置的一段操作码和数据 (此处我们不需要了解每个操作码的含义,理解个大概即可)

上图中右侧的锁定脚本中的 DUP、HASH160、EQUALVERIFY 等操作码,负责把左侧的解锁脚本中携带的 Public key 取哈希,和锁定脚本中预设的 Public key hash 做对比,若两者相等,说明解锁脚本中上传的公钥,和锁定脚本中预设的公钥哈希相匹配,这就通过了第一道验证。

但是,有个问题,UTXO 锁定脚本的内容其实是在链上公开的,任何人都能观测到其中包含的公钥哈希,谁都可以上传对应的公钥,谎称自己是那个被「钦定」的人。所以在验证完公钥和公钥 hash 后,还要验证交易发起人是否真是该公钥的实际控制者,这就要对数字签名进行核验。 锁定脚本中的 CHECKSIG 操作码,就是负责验证数字签名的。

总结一下,P2PKH 方案下,交易发起人提交的解锁脚本中,包含公钥和数字签名,该公钥要和锁定脚本中指定的公钥哈希匹配,且交易的数字签名正确,满足这些条件才能顺利解锁 UTXO。

(这个图是动态的:P2PKH 方案下比特币解锁脚本示意图

来源: )

当然,比特币网络中支持多种交易类型,不只有 Pay to public key/public key hash,还有 P2SH(Pay to Script hash)等, 一切取决于 UTXO 创建时自定义的锁定脚本被设置成什么样

这里需要注意的是, P2SH 方案下,锁定脚本中可以预设一个 Script Hash,而解锁脚本需要把 Script Hash 对应的脚本内容完整提交上来。比特币节点可以执行这段脚本, 如果这段脚本里定义了多签验证的逻辑,就可以在比特币链上实现多签钱包的效果。

当然,P2SH 方案下,UTXO 创建者要让未来解锁 UTXO 的人事先知道 Script Hash 对应的脚本内容,只要双方都知道这段 Script 的内容,那么我们就可以实现比多签更复杂的业务逻辑。

这里要说明一点,比特币链上(区块)并不直接记录哪些 UTXO 和哪些地址关联,它只记录 UTXO 可以被哪个公钥哈希 / 哪个脚本哈希解锁,但我们根据公钥 hash/ 脚本 hash 可以快速算出对应的地址(钱包界面显示的那一段像乱码的东西)。

我们之所以能在区块浏览器和钱包界面看到 xx 地址下有 xx 数额的比特币,是因为区块浏览器和钱包项目方帮你解析了这些数据,会扫描所有区块并根据锁定脚本中声明的公钥 hash/ 脚本 hash,计算出对应的「地址」,然后显示出 xx 地址名下有多少比特币。

隔离见证与 Witness

当我们理解了 P2SH 的思路后,便和 BitVM 所依赖的 Taproot 更近一步了。但在此之前,我们要了解一个重要的概念:Witness 和隔离见证。

复盘前面讲到的解锁脚本和锁定脚本,以及 UTXO 解锁流程,会发现一个问题:交易的数字签名包含在解锁脚本中,生成签名时不能把解锁脚本覆盖进去(生成签名用到的参数不能包含签名本身),所以 数字签名只能覆盖解锁脚本之外的部分,也就是只能与交易数据的主干部分建立关联,不能完整的覆盖交易数据。

这样一来, 就算交易的解锁脚本被中间人稍做手脚,也不会影响到验签结果。 比如说,比特币节点或矿池可以在交易的解锁脚本中,塞入其他数据,在不影响验签和交易结果的前提下,使得交易数据发生细微变化,最后算出的交易 hash/ 交易 ID 也会改变。这被称为 交易延展性问题

这带来的坏处是,如果你打算连续发起多笔交易,并且有次序上的依赖关系(比如,交易 3 引用了交易 2 的输出,交易 2 引用了交易 1 的输出),那么排后面的交易必然要引用前面交易的 ID(hash),矿池或比特币节点等任意中间人可以微调解锁脚本中的内容,使交易上链后的 hash 与你预期的不一致,那么你预先创建好的多笔有次序关联的交易会失效。

实际上,在 DLC 桥和 BitVM2 的方案中,会批量构建有先后次序关联性的交易,所以前面提到的场景并不少见。

简单来说, 交易延展性问题是因为,交易的 ID/hash 在计算时,会把解锁脚本的数据包含进去,而比特币节点等中间人可以微调解锁脚本中的内容, 导致交易 ID 与用户预期的不符合。 其实这是比特币在早期设计时考虑不周留下的历史包袱。

后来推出的 隔离见证 /SegWit 升级,其实就是把交易 ID 和解锁脚本彻底解耦, 计算交易 hash 时不需要把解锁脚本数据包含进去。遵循 SegWit 升级的 UTXO 锁定脚本,会默认在首位设置一个叫「OP_0」的操作码,充当标记;而对应的解锁脚本,从 SigScript 更名为了 Witness(见证)。

遵循隔离见证规则后,交易延展性问题会被妥善解决,你不需要担心发送给比特币节点的交易数据被微调。当然我们不需要想的太复杂,P2WSH 的功能和前面谈到的 P2SH 并无本质差异,你可以在 UTXO 锁定脚本中预设一个脚本哈希,等解锁脚本的提交者把 hash 对应的脚本内容提交到链上并执行。

如果你要实现的脚本内容特别庞大,包含特别多的代码,通过常规的方法无法把完整的脚本提交到比特币链上 (每个区块有大小限制)。那怎么办?这就需要 借助 Taproot ,针对上链的脚本内容进行精简化处理,而 BitVM 正是基于 Taproot 构建出的复杂方案。

微信里点“发现”,扫一下二维码便可将本篇文章分享至朋友圈

发布者:币下载 转转请注明出处:https://www.binancememe.com/367244.html

(0)
今日快讯的头像今日快讯
上一篇 2025年8月9日 下午6:05
下一篇 2025年8月9日 下午6:12

相关推荐

联系我们

QQ:11825395

邮件:admin@binancememe.com

联系微信
联系微信
客服QQ:905995598