理解比特币 Miniscript(二):工作原理
作者:benma
来源:https://shiftcrypto.ch/blog/understanding-bitcoin-miniscript-part-2/
本文为 “理解比特币 Miniscript” 系列的第二篇。
在本系列的第一篇文章中,我们检视了使用 Bitcoin Script(比特币的原生编程语言)来编程 (1 号人物可以随时解锁) or (2 号人物可在一年后解锁)
这样精心设置的资金锁定条件的例子。这些例子证明了,因为 Bitcoin Script 的缺点以及陷阱,这样的条件构造起来、使用起来多么地难。既难以开发出能够编码我们想要的花费条件的脚本,也难以为这样的脚本构造有效的见证数据(从而花费资金)。
Miniscript 通过引入封装了 Bitcoin Script 代码的片段、运用这些片段来编写脚本,解决了上面说的问题。
本文将深入讲解 Miniscript 的工作原理,以及它是如何映射成 Bitcoin Script 的。
如果你还没读过本系列的第一篇文章,请务必花上一点时间,因为我们将依赖于那篇文章介绍过的 Bitcoin Script 的概念,例如 Bitcoin Script 是如何执行,以决定资金是否可被花费的。
什么是 “Miniscript”?
Miniscript 编程语言由两个独立的部分组成:
Policy 语言
Policy(“花费策略”)语言是一种抽象的表达式语言,是可以组合且易于直接阅读和编写的。Policy 句子可以由编译器自动编程成合适的 Miniscript 代码。Policy 句子的一个例子是 or(pk(key_1),pk(key_2))
,意思是 “公钥 1 和公钥 2 都可花费”。
Miniscript
Miniscript 表达式,举例来说,是这样的: or_b(pk(key_1),s:pk(key_2))
,这是使用 sipa 的编译器,从上面那个花费策略编译而来的;它是 or_b
、pk
这样的片段的组合。
每一种片段都可以映射成特定的 Bitcoin Script 代码。 比如说, pk(key)
会映射成 <key> OP_CHECKSIG
,而 or_b(X, Y)
会映射成 [X] [Y] BOOLOR
。
Miniscript 自身也是一种表达式语言,容易用计算机读取,也易于被人类阅读。
对于计算机来说,这是很重要的,这样你的钱包应用可以解码一个 Miniscript 表达式,并转化成收款地址、让你能够花费其中的资金。
对于人类来说,它的意义在于你只需在纸上记录下来,就可以备份你的钱包的描述符,而且还可以使用同一个描述符跟不同的应用和工具交互。举个例子,你可能想要将你的钱包描述符导入一个投资组合监控工具中,或者一个报税工具中,或是导入一个移动端的观察钱包。钱包描述符可以包含一个 miniscript 表达式,然后就能推导出地址。
Miniscript 表达式语言看起来跟 policy 语言很像,所以很容易将两者搞混。但你要理解,它们是两种完全独立的语言:
Policy 语言是一种帮助开发者创建花费条件的工具,因为它是很容易编写的。它只有少数几种元件,例如 and(X,Y)
、or(X,Y)
和 older(time)
;而且这些元件彼此之间可以完美组合。Policy 语言只是一种给开发者使用的工具,并不是标准。不能保证同一个 policy 表达式总能产生同一个 Miniscript 表达式。
相反,Miniscript 是得到充分说明的。只有 Miniscript 会被用于推导 Bitcoin Script 代码、有效的见证数据,以及执行正确性分析。
那么,为什么开发者不直接编写 Miniscript 表达式呢?为什么我们还要依赖于 policy 编译器?原因是,手写 Miniscript 表达式并不容易,而且,因为它是 Bitcoin Script 的一种封装,它也继承了 Script 的复杂性:
Miniscript 语言比 policy 语言有更多的片段。举个例子,在 Miniscript 中,至少有如下几种表达
X or Y
的方式:or_b(X,Y)
、or_c(X,Y)
、or_d(X,Y)
和or_i(X,Y)
,每一种都对应着不同的表示X or Y
的 Script 代码,这些代码的脚本体积、见证数据体积、与其它代码的组合方式,都各不相同。可能有许多 Miniscript 表达式可以编码同一种花费条件。而 policy 编译器可以帮助你优化表达,例如,通过降低脚本体积来减少所需的交易手续费。
不是所有的 Miniscript 表达式都能产生有效的脚本:这些片段必须以某些方式组合起来,才能获得正确性。policy 编译器可以确保只会产生有效的 Miniscript 表达式。
实际操作:映射成 Bitcoin Script
为了理解一个 Miniscript 表达式是如何编码一个 Bitcoin Script 代码的,我们看看下面这个表达式:
or_b(pk(key_1),s:pk(key_2))
每一个片段都可以映射成特定的 Bitcoin Script 代码。 pk(key)
映射成 <key> OP_CHECKSIG
,而 or_b(X, Y)
映射成 [X] [Y] BOOLOR
。
每一种片段都可以用封装器来封装,这是用冒号 :
来表示的: s:X
封装器会映射成 OP_SWAP [X]
。封装器跟其它片段基本上是一样的,不过更准确一些。如此一来,它们就只是语法上的点缀。你可以认为(比如说)s:X
跟 s(x)
是一样的, dv:older(144)
跟 d(v(older(144)))
是一样的。
所以,整个 Miniscript 可以翻译成这样的 Bitcoin Script 代码:
<key_1> OP_CHECKSIG OP_SWAP <key_2> OP_CHECKSIG OP_BOOLOR \_________________/ \ \________________/ / \ X \ X / / \ \__________________/ / \ Y=s:X / \_______________________________________________/ or_b(X,Y)
在这一个案例中,可以花费这笔资金的见证数据的形式将是 <signature2> <signature1>
这样的,其中至少要有一个签名是有效的。需要 OP_swap
,这样 <key2> OP_CHECKSIG
才不会对栈顶的元素操作 —— 这时候的栈顶元素将包含 <signature1> <key_1> OP_CHECKSIG
的结果 ——而是对栈顶之下的第一个元素操作,这个元素包含的是第二个公钥的签名。
Miniscript 总共有 22 种定义好的片段和 11 种封装器,每一种都可以准确映射成 Bitcoin Script 代码。可在这份规范中了解这些片段以及它们的映射。
我们再分析一个更复杂的表达式:我们在本系列的第一篇文章中提到的那个一针见血的例子:
pubkey1 OR (pubkey2 in one year)
我们用来编码这个花费条件的 Script 代码是非常复杂的,而且很难手动开发出来:
<pubkey1> OP_CHECKSIG OP_IFDUP OP_NOTIF <pubkey2> OP_CHECKSIGVERIFY <52560 (one year)> OP_CHECKSEQUENCEVERIFY OP_ENDIF
但是,使用 Miniscript,上述的花费条件就可以用这样的 policy 语句来表达:
or(10@pk(pubkey1),and(pk(pubkey2),older(52560)))
编程成 Miniscript 表达式:
or_d(pk(pubkey1),and_v(v:pk(pubkey2),older(52560)))
通过将表达式中的片段映射成对应的 Script 代码,我们就可以得到上面的复杂 Script 代码:
older(52560)
概括了<52560> OP_CHECKSEQUENCEVERIFY
v:pk(pubkey2)
概括了<pubkey2> OP_CHECKSIGVERIFY
and_v(X,Y)
概括了[X] [Y]
,在这个例子中就是<puybey2> OP_CHECKSIGVERIFY <52560> OP_CHECKSEQUENCEVERIFY
pk(pubkey1)
概括了<puybey1> OP_CHECKSIG
or_d(X,Y)
概括了[X] OP_IFDUP OP_NOTIF [Y] OP_ENDIF
,最终得到上面那段复杂的代码
这里的 10@
给了 policy 编译器一个提示:我们预计,这种花费路径比其它路径更有可能被使用。编译器可以使用这个信息来优化总的脚本大小。
一旦我们有了最终的 Bitcoin Script 代码,钱包应用就可以将它转化为一个 bc1...
这样的收款地址,然后你就可以拿它来收款。这些资金将使用上面的 policy/Miniscript 表达式所表达的花费条件。
生成见证数据
对应的有效见证数据也可以从 Miniscript 表达式中自动生成出来,因为每一种片段都定义了如何构建有效的 “满足(satisfaction)” 和 “避开(dissatisfaction)”(译者注:分别指能够通过验证的数据,以及不能通过但不会让脚本终止执行的数据)。一种运用了 Miniscript 的钱包应用,将使用这种方法来允许用户发送交易。
所有片段的 satsifaction 和 dissatisfaction 的清单,可以在这个网页的 “Basic satisfactions” 找到。
举个例子, pk(key)
这个片段可以映射成 <key> OP_CHECKSIG
,这样的见证脚本可以用 <signature>
(签名)这样的见证数据来满足。最终的执行脚本将是 <signature> <key> OP_CHECKSIG
;如果签名有效的话,它会留下 1
在堆栈中 ,不然就会在堆栈中留下 0
。同一个片段,也可以用空的无效签名 <>
来 “避开”。“避开” 意味着脚本不会终止执行,只会在堆栈中留下一个 0
然后继续执行。
请参考本系列的第一篇文章,了解见证数据和见证脚本是如何组合在一起、通过执行来确定资金是否可被花费的。
我们为上面案例中的同一个表达式生成见证数据:
or_b(pk(key_1),s:pk(key_2))
pk(key)
片段可以用<signature>
来满足,也可以用空签名<>
避开or_b(X,Y)
片段([X] [Y] OP_BOOLOR
)有三种不同的满足方式:X 和 Y 都被满足,或者其中一个被满足(另一个被避开):[satisfaction for Y][satisfaction for X]
,或[dissatisfaction for Y][satisfaction for X]
,或[satisfaction for Y][dissatisfaction for X]
。结合两者:
or_b(pk(key_1),s:pk(key_2))
有这三种有效的见证数据 :<signature2> <signature1>
<> <signature1>
<signature2> <>
结论
在这篇文章中,我们看到了 Miniscript 是如何简化复杂花费条件的开发的,以及它是如何让钱包应用能够使用这些条件来收账和发账的。
在下一篇文章中,我们会使用 Go 语言编写一个真正成熟的 Miniscript 解析器和正确性分析器。他将能够从任意的 Miniscript 表达式中创建比特币收账地址。敬请期待!
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
相关资讯
-
我的一张大字报——为什么我要旗帜鲜明的批判BITTENSOR
BITTENSER是一种伪装成AI coin的memecoin,市值最高,但项目存在资源浪费、逻辑漏洞、虚假数据,抛售风险大。官方允许子网所有者操控奖励分配,验证者和矿工之间存在密切关系。平台提供交易工具,但存在问题。创始人发布了Kusanagi网络,但因共识问题暂停,计划在2023年发布Finney主网。Opentensor Foundation暂停Kusanagi,迁移到Nakamoto,计划在2023年发布Finney测试网。2023年3月发布Finney主网,BTLM是30亿参数语言模型,兼容移动
-
探索自治世界:数字物理法则和自然可组合性
本文总结了笔者在AW/FOCG领域实践的经验和思考,包括自治世界的起源、定义和现状,自治世界与全链游戏的关系,以及最具原语性的自治世界PixeLAW及其Solidity实现。还分享了智能合约的可组合性和互操作性。详细内容可在链接中查看。.....
-
又到一年519,币圈惨案大盘点!
币圈老韭菜经历过多次暴跌事件,包括门头沟、94、312、519、LUNA/FTX暴雷,提醒投资需谨慎。这些事件导致比特币价格大幅下跌,引发投资者信任危机。加密市场发展中也出现了多次挑战,但仍有发展前景。然而,加密市场最大的敌人是自身,管理不善可能导致市场崩溃。投资者应谨慎对待加密投资,避免重蹈覆辙。.....
-
伟大的脚本恢复:比特币的前进之路
Rusty Russell提出“伟大的脚本恢复”提案,旨在恢复比特币最初设计的完整脚本语言,以支持未来可能的安全用例。过去几年来,提案都是为了增加可扩展性或改进小功能,导致讨论没有取得进展。该提案的价值在于审视功能需求,而不是恢复所有功能,为未来的发展方向提供可能性。这是一个积极的变化,可以帮助我们决定未来的路线。.....
-
Farcaster/FT/UXLINK/Cyber,如何寻找Socialfi的北极星指标
社交产品旨在帮助用户建立社交关系、传递信息和拓展社交网络。Web3的社交产品具有金融化特点,如何基于社交网络发行资产是其核心。本文分析了几款发展良好的SocialFi产品,如Farcaster、FriendTech、UXLINK和CyberConnect,探讨了它们的增长路径。其中,UXLINK是最火爆的区块链社交基础设施,活跃钱包数量高达729.5k。未来,可以关注基于熟人社交网络的资产发行。.....
-
一览检查代币是否为诈骗的8种方法
本文介绍了八种方法来识别区块链项目中的诈骗,包括验证代币合法性、检查代码、查看评论、比对黑名单、检查流动性和使用第三方工具。使用DEX时,要检查交易量、交易笔数和用户数量。使用第三方工具可以帮助评估代币的真实价值。遵循这些建议可以避免被骗取资金。.....
-
Farcaster:SocialFi板块领导者
Farcaster是一个去中心化的社交网络协议,通过智能合约和混合存储技术实现用户之间的社交连接、内容分享和数据所有权。它的团队具有强大的行业背景,项目运行速度快,用户体验好。与其他SocialFi项目相比,Farcaster具有更多的能力和优势,使得用户更容易接受和使用。Farcaster的生态系统包括70%的代币分发给社区,15%分配给流动性池,剩余的15%将分配给团队、投资者和生态系统。Farcaster通过独特的框架和Frames插件,改变了传统SocialFi项目的数据存储方式,成为Social
-
Glassnode链上周报:跨多个时间框架识别卖方疲劳
长期投资者在牛市中获利,损失主要来自短期持有者。我们使用年龄分解指标来描述日交易者和每周-每月投资者群体中的卖方疲劳情况,并利用链上指标评估目标投资者群体的未实现和实现亏损。市场转折点从内向外展开,利用卖方疲劳框架识别修正和整合期间的转折点。通过评估MVRV比率、SOPR和实现亏损,我们可以识别卖方疲劳的时期。新发布的细分指标帮助我们隔离出个别投资者子集,并通过三个链上指标来识别微型投降点。该框架帮助我们思考在识别卖方疲劳点时应该看到的激励和行为。.....
- 成交量排行
- 币种热搜榜