如何使用?Merklized?抽象語(yǔ)法樹壓縮智能合約
Merklized 抽象語(yǔ)法樹 MAST(又名 Merklized 替代腳本樹)是一種使用 Merkle 樹壓縮比特幣智能合約的技術(shù)。我們?cè)诒忍貛?SV 上實(shí)施了 MAST。與所有其他實(shí)現(xiàn)不同,我們利用原始比特幣協(xié)議,沒有任何共識(shí)更改。
問題
通常有不止一種方法可以解鎖鎖定在比特幣智能合約中的硬幣。在 sCrypt 中,每種方式都被建模為一個(gè)公有函數(shù),代表一種條件的解鎖分支。例如,在 TimedCommit 合約中,可以通過 Alice 的原像和她的簽名,或者通過 Alice 和 Bob 的簽名來解鎖合約。
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));
}
}隨著合約變得越來越復(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 帶來了巨大的好處,尤其是當(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í),它本身和它的默克爾路徑被用來解鎖。在壓縮合約中,我們首先使用其默克爾根驗(yàn)證分支是否來自原始合約。接下來,使用 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-08
git之如何把本地文件上傳到遠(yuǎn)程倉(cāng)庫(kù)的指定位置
這篇文章主要介紹了git之如何把本地文件上傳到遠(yuǎn)程倉(cāng)庫(kù)的指定位置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

