譯者前言:由于比特幣腳本(Script)的存在,今天,比特幣可實(shí)現(xiàn)簡單的交易功能及各種多重簽名、原子互換、閃電網(wǎng)絡(luò)交易,然而,腳本的功能并非只有這些,但復(fù)雜性卻限制了更多應(yīng)用的可能,而Miniscript的提出,目的是讓比特幣腳本變得更易于訪問,并最終解鎖比特幣更多的應(yīng)用。
對此,Pieter Wuille和Andrew Poelstra撰寫了一篇《Miniscript: Streamlined Bitcoin Scripting》來解釋Miniscript的由來和作用,以及其未來的發(fā)展方向。
以下為譯文:
關(guān)于比特幣腳本的介紹
比特幣一直以來都有一種機(jī)制,它可通過更復(fù)雜的策略(而不僅僅是單個密鑰)來使幣可花費(fèi):這就是腳本(Script)系統(tǒng)。雖然腳本主要用于單密鑰支付,但它也是各種多重簽名錢包、原子互換結(jié)構(gòu)和閃電網(wǎng)絡(luò)的基礎(chǔ)。
然而,這些并不是腳本所能實(shí)現(xiàn)功能的全部。腳本可用于表示發(fā)布交易而所需的復(fù)雜條件,例如(A, B, C中的兩個)以及(D 或(E和F)) , 其中 A-F分別表示唯一的密鑰,以及哈希原像檢查、timelock(時間鎖)以及一些更奇特的構(gòu)造。
比特幣腳本的問題:難以驗(yàn)證
但我們還無法充分利用比特幣腳本的潛力,其中一個原因在于,為復(fù)雜任務(wù)構(gòu)建腳本是很麻煩的:很難驗(yàn)證它們的正確性及安全性,甚至很難找到最經(jīng)濟(jì)的方法來編寫它們。
這是問題的一部分:即使你知道正確的腳本、設(shè)計(jì)應(yīng)用及協(xié)議來協(xié)商和構(gòu)造交易,而每次設(shè)計(jì)新的構(gòu)造時,都需要大量額外的開發(fā)工作。而每次添加,都需要更多的工程資源以滿足分析和質(zhì)量保證。
那如果比特幣應(yīng)用可使用任何腳本,而不僅僅是為數(shù)不多的腳本設(shè)計(jì),這會是怎么樣的呢?我們將不再局限于使用一次性設(shè)計(jì),并且可開始設(shè)計(jì)基于用戶指定需求的應(yīng)用。錢包開發(fā)人員還可引入更多基于腳本的選項(xiàng),同時保持與其他錢包的互操作性。
Miniscript是什么
下面進(jìn)入Miniscript的世界,這是一種以結(jié)構(gòu)化方式表示比特幣腳本的語言,其支持高效的分析、合成、通用簽名等功能。
關(guān)于比特幣腳本的一個例子:
OP_CHECKSIG OP_IFDUP OP_NOTIF OP_DUP OP_HASH160 《hash160(B)》 OP_EQUALVERIFY OP_CHECKSIGVERIFY OP_CSV OP_ENDIF
其中A 和 B代表公鑰,而轉(zhuǎn)換成Miniscript的表示法就是:or_d(c:pk(A),and_v(vc:pk_h(B),older(144)))
這個例子清楚地表明,腳本的語義,允許在A簽名或144個區(qū)塊之后的B簽名發(fā)生時允許支付。而大部分有意義的腳本都可以用這種方式編寫。
而使得腳本可讀,只是Miniscript的其中一個特性,其主要目的是實(shí)現(xiàn)對腳本的自動化推理,如下面的應(yīng)用例子所示。
Miniscript的應(yīng)用
當(dāng)前我們?nèi)羰褂帽忍貛拍_本來構(gòu)建復(fù)雜的支出條件,這樣做的難度是非常大的,這需要為每個新的用例開發(fā)、測試和部署特殊用途的軟件。而Miniscript 可以一種跨越任意支出條件集的方式覆蓋這些條件,并且通常比專用解決方案要簡單得多,也更可靠。
應(yīng)用1、優(yōu)化腳本
而其中一個例子,是找到一個實(shí)現(xiàn)給定支出條件集的最佳腳本。
在比特幣腳本中,有很多不同的方法需要簽名,描述連接或分離,或?qū)崿F(xiàn)一個閾值。即使對經(jīng)驗(yàn)豐富的比特幣腳本開發(fā)者,正確的選擇也可能取決于滿足不同條件的相對概率,而且難以進(jìn)行計(jì)算。而我們的在線編譯器,其可立即找到與給定支出策略相對應(yīng)的最佳Miniscript。
介紹中的例子可通過以下編譯策略獲得:or(99@pk(A),1@and(pk(B),older(144)))
這是一種書寫方式,即左側(cè)A簽名發(fā)生的概率為99%,而右側(cè)(144個區(qū)塊后的B簽名)發(fā)生的概率為1%。
應(yīng)用2、通用支出
一旦找到了一個有效腳本,很多腳本使用存在的一個共同障礙就是,不同的支出機(jī)制之間缺乏互操作性。而希望實(shí)施長期時間鎖( timelock)或復(fù)雜多重簽名要求的用戶,可能會因此而擔(dān)心。
而Miniscript,通過直接表示支出條件,允許任意策略的表達(dá),以便任何人都可:
1. 計(jì)算腳本的相關(guān)地址;
2. 確定在給定時間,哪些簽名者進(jìn)行簽署是必要或足夠的;
3. 生成一筆有效交易,給定一個足夠的簽名集;
用戶不必?fù)?dān)心所有參與者是否在使用兼容的軟件,也不必?fù)?dān)心這些軟件在需要這樣的時間鎖(timelock)設(shè)置時會繼續(xù)存在。
他們也不必?fù)?dān)心自己的需求可能會以和簽名軟件不兼容的方式發(fā)生變化,從而保證使用比特幣腳本不會對他們造成限制。
應(yīng)用3、準(zhǔn)備金證明
與簽名問題相關(guān)的是證明儲備金的問題,這是一個公司證明其可在不實(shí)際使用儲備比特幣的情況下,可使用其中部分比特幣的過程。雖然當(dāng)前已經(jīng)存在這方面的工具,例如Blockstream的準(zhǔn)備金證明工具,但行業(yè)內(nèi)還沒有一個通用的標(biāo)準(zhǔn)。而沒有Miniscript,可能也不會有一個能夠涵蓋當(dāng)前多樣性托管解決方案的準(zhǔn)備金證明標(biāo)準(zhǔn)。
支出策略的構(gòu)成
讓我們來看看受互操作性需求約束的比特幣腳本開發(fā)者的一個具體例子。以一家托管大量BTC的公司為例,該公司希望這些比特幣只有在其大多數(shù)董事同意的情況下才能被動用。然而,一些獨(dú)立的董事希望使用他們自己現(xiàn)有的錢包軟件和硬件,并且不希望參與(要求他們使用專用應(yīng)用而提供的)單個密鑰簽名的方案。
在沒有Miniscript的情況下,生成一個包含所有簽名者要求的腳本,同時向所有簽名者保證完整的腳本是健全和完整的,并且他們的錢包軟件與結(jié)果兼容,這將是一個無法克服的難題。
而使用Miniscript,這些董事可簡單地在自己的錢包軟件中編寫策略,構(gòu)造一個描述閾值要求的單個策略,然后將其編譯為Miniscript。他們可直接驗(yàn)證編譯器的輸出是否與原始策略匹配,以及原始策略是否滿足每個人的需求。然后,他們可使用任何與Miniscript兼容的軟件來計(jì)算接收幣的地址,在消費(fèi)時收集簽名,并將這些簽名組合到一筆有效的交易。
舉一個簡單的假設(shè)性例子:一家公司正在用一個定制的多重簽名存儲錢包,其有兩位董事,其中一位董事使用的是Blockstream Green錢包(配置為2-of-2多簽,經(jīng)一些延遲后變?yōu)?-of-2),而另一位則使用的是Electrum錢包(標(biāo)準(zhǔn)1-of-1)。如果沒有允許組合安全、可互操作腳本策略的工具,使用Green錢包的董事就不可能將其策略作為“參與者”添加到公司的多重簽名方案中。而如果Green和用于構(gòu)建公司多重簽名的軟件都支持Miniscript,那么兩位董事就可直接使用他們自己喜歡的錢包,甚至不需要知道錢包底層的腳本到底是個啥。
動態(tài)聯(lián)盟(dynamic federation)
Miniscript的作用,我們可以在Blockstream的Liquid側(cè)鏈中找到一個具體的例子。Blockstream目前正在開發(fā)的一個功能(內(nèi)部稱為動態(tài)聯(lián)盟),這是一個允許現(xiàn)有Liquid成員管理新成員添加或更新控制聯(lián)盟托管比特幣可使用性的腳本。Miniscript為聯(lián)盟成員提供了快速、高效地構(gòu)建此類腳本的工具(事實(shí)上,Miniscript編譯器發(fā)現(xiàn)了現(xiàn)有Liquid腳本的一個22字節(jié)的較短版本,比我們原來的手工優(yōu)化腳本節(jié)省了5%的工作量)。但更重要的是,Miniscript允許成員自動驗(yàn)證提議腳本的重要屬性,從而減少了成員之間相互協(xié)調(diào)或?qū)μ嶙h腳本執(zhí)行昂貴的手動安全審核的需要。
特別是,成員可自動驗(yàn)證任何腳本提議是否包括:
1. 他們自己的密鑰;
2. 一個時間鎖緊急支出條件,確保其在未來是正確的和足夠遠(yuǎn)的。
它還允許他們驗(yàn)證新聯(lián)盟的參與者是否有能力花費(fèi)舊聯(lián)盟控制的幣。此檢查對于確保這種轉(zhuǎn)變不會導(dǎo)致幣丟失而言是至關(guān)重要的,即使對在轉(zhuǎn)換時將幣轉(zhuǎn)移到系統(tǒng)中的用戶也是如此,如果沒有 Miniscript,這幾乎是不可能實(shí)現(xiàn)的。
Miniscript的歷史
關(guān)于Miniscript的想法,最早可追溯到2018年夏天。那年7月中旬,Pieter Wuille為Bitcoin Core引入了輸出描述符(output descriptor)方案,這是一種描述Core支持的多種不同地址類型的通用方法。與此同時,當(dāng)時還是Blockstream實(shí)習(xí)開發(fā)者的Andy Chow在開發(fā)部分簽名比特幣交易(PSBT,也被稱為BIP 174)方案,這是一種錢包互操作性協(xié)議,而這種提議在錢包領(lǐng)域獲得了廣泛關(guān)注。
PSBT的一個重要組成部分是 finalizer(完成者),其是從PSBT中包含的簽名者數(shù)據(jù)集合中,組裝實(shí)際比特幣交易的參與者。這種裝配需了解滿足的腳本,這意味著支持PSBT的錢包必須實(shí)現(xiàn)自己的專用finalizer(完成者),而這就需要額外的開發(fā)并會限制互操作性。
而那個時期,Andrew Poelstra在努力嘗試把PSBT實(shí)現(xiàn)引入到rust版比特幣(通過Rust編程語言編寫的通用比特幣庫)軟件(這種實(shí)現(xiàn)最初是由Carl Dong提出的)。Poelstra在 IRC 交流頻道上觀察到:
“如果你有高度結(jié)構(gòu)化的腳本模板,你就不需要再去真正理解腳本?!?/p>
正是這一想法,最終成為了Miniscript的核心。
實(shí)際上,Poelstra和Wuille一直在從事一個與托管相關(guān)的項(xiàng)目,但由于缺乏可用于復(fù)雜多參與者腳本的標(biāo)準(zhǔn)工具,他們感到非常沮喪。兩人于2018年8月會面討論此事,Wuille建議實(shí)現(xiàn)這些“高度結(jié)構(gòu)化的腳本模板”,以此作為Bitcoin Core輸出描述符的擴(kuò)展。
隨著擴(kuò)展的形成,其演化為比特幣腳本的結(jié)構(gòu)化子集,最終成為Miniscript,以及一種更簡單的“策略語言”來直接表示支出條件,并且可編譯成Miniscript。2019年1月,Wuille在斯坦福區(qū)塊鏈會議上介紹了該方案的初步結(jié)果。
今年5月份,Sanket Kanjalkar加入Blockstream進(jìn)行了為期三個月的實(shí)習(xí)工作,而其重點(diǎn)就是實(shí)現(xiàn)Miniscript工具,并幫助它與Bitcoin Core集成。在他的幫助下,MiniScript變得更小、更高效、更容易分析、更好地防止延展性問題。
經(jīng)過這些迭代工作,最終形成了今天的Miniscript。
相關(guān)工作
Miniscript是建立在比特幣生態(tài)系統(tǒng)中很多其它項(xiàng)目的基礎(chǔ)上的,并與它們形成互補(bǔ)。特別是,如上所述,Miniscript 擴(kuò)展了Bitcoin Core的錢包輸出描述符,并補(bǔ)充了PSBT,以實(shí)現(xiàn)完全通用的更新者(updater)和完成者(finalizer)。
Miniscript可以與Ivy進(jìn)行比較,后者是另一種旨在使比特幣腳本的高級功能易于訪問的語言。然而,相比Ivy,Miniscript 是腳本(子集)的直接表示,這意味著可有效地驗(yàn)證“miniscript”的正確性和可靠性。Miniscript還可接受很多其它形式的靜態(tài)分析,而這是腳本(Script)和(Ivy)都無法做到的。
Miniscript的策略語言與Ivy相似,因?yàn)閮烧叨际浅橄蟮?,它們都必須?jīng)過編譯后才能在區(qū)塊鏈上使用。然而,Miniscript的策略語言在結(jié)構(gòu)上與Miniscript本身非常相似,因此可以很容易地驗(yàn)證編譯器的輸出是否與編譯器的輸入匹配(事實(shí)上,這甚至可手動檢查),并且可以很容易地驗(yàn)證是否符合用戶的期望。
另一種與Miniscript相關(guān)的區(qū)塊鏈語言是Blockstream的Simplicity。與Miniscript一樣,Simplicity是一種低level語言,其旨在直接嵌入到區(qū)塊鏈交易當(dāng)中。此外,Simplicity也支持很多形式的靜態(tài)分析,這些分析在部署區(qū)塊鏈合約時是非常重要的,但這在以太坊EVM等替代產(chǎn)品中卻難以甚至不可能實(shí)現(xiàn)。
另外,Miniscript 不像simplicity那樣強(qiáng)大到可以表示任何可計(jì)算函數(shù),它的作用域非常有限:它可以表示簽名需求、時間鎖(timelock)、哈希原像(hash preimage)以及它們的任意組合。這種范圍的縮小,使得Miniscript更容易對它所涵蓋的用例進(jìn)行解釋,而且重要的是,這允許它在現(xiàn)有的比特幣區(qū)塊鏈上工作。相比之下,Simplicity則是對比特幣腳本的徹底背離,其目前仍處于發(fā)展的早期階段。
未來的工作和結(jié)論
在設(shè)計(jì) Miniscript時,我們著手讓比特幣腳本更容易訪問。雖然很多工作都集中在調(diào)查和提議未來對腳本及比特幣共識規(guī)則的修改,以添加額外功能,但我們也看到,基礎(chǔ)設(shè)施甚至沒有以通用、安全、可組合和可互操作的方式使用已存在的功能,這是當(dāng)前所欠缺的。
這項(xiàng)工作還沒有徹底完成。我們有兩種Miniscript實(shí)現(xiàn)(分別是C++和Rust版本)和策略編譯器,但是為了該技術(shù)易于訪問,我們需要在常用軟件中集成它。通過與Miniscript兼容的PSBT 實(shí)現(xiàn)(updater和finalizer),即使沒有明確的支持,許多PSBT簽名器(包括基于硬件錢包的簽名器)也可以用于復(fù)雜的腳本。此外,編譯器也可以進(jìn)行改進(jìn),因?yàn)椴呗缘降侥_本轉(zhuǎn)換中有很多優(yōu)化尚未被考慮。
這一路走來,我們學(xué)到了很多東西:
1. 腳本資源限制使得策略優(yōu)化復(fù)雜化:眾多共識和標(biāo)準(zhǔn)性強(qiáng)加資源限制的存在(最大opcode、最大腳本大小、最大堆棧大小……),使得我們一旦接近這些限制,就很難找到給定策略的最佳腳本。這是有趣的,因?yàn)樗赡軙笇?dǎo)未來腳本的改進(jìn)建議。與此相關(guān)的是,我們還驚訝地了解到,比特幣共識規(guī)則實(shí)際上將參與執(zhí)行的OP_CHECKMULTISIG(VERIFY)的密鑰數(shù),計(jì)算為每個腳本201個非推送(non-push)opcode的限制。
2. 可變的驗(yàn)證內(nèi)容(witness)大小使費(fèi)用估算復(fù)雜化:簡單的支付和多簽結(jié)構(gòu)具有獨(dú)立于現(xiàn)有密鑰精確集合的驗(yàn)證內(nèi)容(witness)大小。而一旦我們轉(zhuǎn)移到更復(fù)雜的腳本中,驗(yàn)證內(nèi)容(witness)大小就會變大,可能會使費(fèi)用估算復(fù)雜化。特定交易輸出的潛在簽名者,可能需要樂觀地猜測將采用的廉價路徑,并構(gòu)造相應(yīng)的交易。如果不是該路徑的所有密鑰或哈希最終都可獲得,則可能需要更改交易本身以考慮增加的費(fèi)用。
3. 隔離見證(Segwit)的堆棧編碼使得優(yōu)化復(fù)雜化:因?yàn)閟egwit的輸入堆棧不再編碼為腳本,而是直接編碼為堆棧元素列表。這帶來了不幸的副作用,它會把“true”的編碼從1字節(jié)更改為2字節(jié)。因此,Miniscript 需要關(guān)心哪些子表達(dá)式進(jìn)入if/else/endif結(jié)構(gòu)的哪一邊。
4. 可擴(kuò)展性:由于segwit,交易可擴(kuò)展性不再是協(xié)議正確性的破壞者,但它仍然可能有不利影響(例如廣播交易時對收費(fèi)率的不確定性、減慢致密區(qū)塊(compact block)傳播以及干擾哈希鎖作為全局發(fā)布機(jī)制的使用)。基于這些原因,我們在設(shè)計(jì)Miniscript時,考慮了不可延展性問題,并學(xué)習(xí)了一般驗(yàn)證內(nèi)容(witness)不可延展性的推理。為了實(shí)現(xiàn)這一點(diǎn),Miniscript依賴于某些segwit特定的規(guī)則。
5. 常見子表達(dá)式的消除是困難的:盡管嘗試了很多次,Miniscript依然不支持優(yōu)化重復(fù)的子表達(dá)式。雖然這在某些特定的情況下是可能的,但在一般的腳本中似乎很難做到。添加某些堆棧操作opcode可能會改變這種情況。
來源: 巴比特
評論
查看更多