如何使用?Merklized?抽象語(yǔ)法樹壓縮智能合約
Merklized 抽象語(yǔ)法樹 MAST(又名 Merklized 替代腳本樹)是一種使用 Merkle 樹壓縮比特幣智能合約的技術(shù)。我們?cè)诒忍貛?SV 上實(shí)施了 MAST。與所有其他實(shí)現(xiàn)不同,我們利用原始比特幣協(xié)議,沒有任何共識(shí)更改。
問(wèn)題
通常有不止一種方法可以解鎖鎖定在比特幣智能合約中的硬幣。在 sCrypt 中,每種方式都被建模為一個(gè)公有函數(shù),代表一種條件的解鎖分支。例如,在 TimedCommit 合約中,可以通過(guò) Alice 的原像和她的簽名,或者通過(guò) Alice 和 Bob 的簽名來(lái)解鎖合約。
contract TimedCommit { bytes aliceHash; PubKey alice; PubKey bob; public function open(bytes aliceNonce, Sig aliceSig) { require(sha256(aliceNonce) == this.aliceHash); require(checkSig(aliceSig, this.alice)); } public function forfeit(Sig aliceSig, Sig bobSig) { require(checkSig(aliceSig, this.alice)); require(checkSig(bobSig, this.bob)); } }
隨著合約變得越來(lái)越復(fù)雜,一個(gè)合約中可能有數(shù)十個(gè)甚至數(shù)百個(gè)公有函數(shù)/分支。最終只調(diào)用其中一個(gè),但所有這些都必須包含在區(qū)塊鏈中,即使他們根本沒有被執(zhí)行。這會(huì)增加鏈上的足跡并增加交易費(fèi)用。
contract ContractOfManyBranches { public function branchA() { } public function branchB() { } public function branchC() { } public function branchC() { } // ... more branches }
MAST
抽象語(yǔ)法樹 MAST 可以從區(qū)塊鏈中刪除未執(zhí)行的分支。未壓縮的合約(原始合約)被拆分為單獨(dú)的分支并組織成 Merkle 樹,其中每個(gè)分支的腳本都是一片葉子。壓縮后的合約并不存儲(chǔ)所有分支,只存儲(chǔ)了所有分支的 merkle root,用于驗(yàn)證某個(gè)特定分支是否屬于原始合約。
以下是 MAST 帶來(lái)了巨大的好處,尤其是當(dāng)分支數(shù) n 很大時(shí):
可擴(kuò)展性: 部署的合約大小按 log(n)¹ 縮小,因?yàn)橹恍枰x定的分支及其默克爾路徑,而不是所有分支。在下面的例子中,當(dāng)分支 Tc 被調(diào)用時(shí),只需要黃色的默克爾路徑。
隱私性: 未使用的分支不會(huì)在鏈上發(fā)布。在下面的示例中,僅顯示 Tc,隱藏所有其他分支。
默克爾樹和默克爾路徑
實(shí)現(xiàn)
我們已經(jīng)在比特幣中實(shí)現(xiàn)了 MAST。當(dāng)一個(gè)分支被執(zhí)行時(shí),它本身和它的默克爾路徑被用來(lái)解鎖。在壓縮合約中,我們首先使用其默克爾根驗(yàn)證分支是否來(lái)自原始合約。接下來(lái),使用 P2SH 技術(shù),將當(dāng)前支出交易中的新鎖定腳本設(shè)置為該分支的腳本,該腳本將在后續(xù)交易中被解鎖。合約代碼如下:
contract MAST { static const int DEPTH = 4; Sha256 merkleRoot; public function main(bytes branchScript, MerklePath merklePath, SigHashPreimage txPreimage) { require(Tx.checkPreimage(txPreimage)); // validate branchScript is from the merkle tree require(calMerkleRoot(branchScript, merklePath) == this.merkleRoot); // "P2SH": use branch script as the new locking script, while maintaining value bytes output = Util.buildOutput(branchScript, Util.value(txPreimage)); require(hash256(output) == Util.hashOutputs(txPreimage)); } static function calMerkleRoot(bytes leaf, MerklePath merklePath) : Sha256 { Sha256 root = sha256(leaf); loop (DEPTH) : i { Sibling s = merklePath[i]; root = s.left ? sha256(s.hash + root) : sha256(root + s.hash); } return root; } }
腳注
[1] 假設(shè)所有分支的大小相似。
到此這篇關(guān)于如何使用 Merklized 抽象語(yǔ)法樹壓縮智能合約的文章就介紹到這了,更多相關(guān)Merklized 抽象語(yǔ)法樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
git 報(bào)錯(cuò):OpenSSL SSL_read: Connection was&
這篇文章主要介紹了git 報(bào)錯(cuò):OpenSSL SSL_read: Connection was reset, errno 10054 解決方法,涉及git配置信息及緩存相關(guān)操作技巧,需要的朋友可以參考下2023-04-04搭建一個(gè)開源項(xiàng)目?jī)煞N方式安裝git的詳細(xì)教程
這篇文章主要介紹了搭建一個(gè)開源項(xiàng)目?jī)煞N方式安裝git,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08git之如何把本地文件上傳到遠(yuǎn)程倉(cāng)庫(kù)的指定位置
這篇文章主要介紹了git之如何把本地文件上傳到遠(yuǎn)程倉(cāng)庫(kù)的指定位置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07