深入學習位元幣指令碼之 OP PUSH TX(1)

2021-10-08 02:20:15 字數 2478 閱讀 3264

了解位元幣指令碼(bitcoin script)的朋友都知道,它是由一串計算指令(即操作碼 opcode)和資料組成的。指令碼執行就是使用指令對資料進行運算的過程,換言之,這個程式的輸入在它執行之前就已經確定了。也正是因為這種設定,很多人下意識地認為它的能力範圍也是非常有限的,因為它不夠「靈活」。

今天想給大家介紹的東西實則是突破了這種刻板印象,也讓我們可以更加深入地理解指令碼的強大和有趣。

我們設計了乙個演算法,使指令碼可以訪問正在被執行的指令碼所在的當前 transaction 資料。我們稱之為op_push_tx,它可以像乙個偽操作碼一樣把當前 transaction 放入棧中。我們用scrypt實現了它,scrypt 是乙個可以編譯成位元幣原生指令碼的的高階語言。我們會通過乙個例子來演示 op_push_tx 的用法。

op_checksig 是用來驗證 ecdsa簽名的操作碼。理論上講,它包括兩個步驟:

根據當前 transaction計算出乙個雜湊值。

對這個雜湊值進行簽名校驗。

注意,步驟1中的雜湊值只能是當前 transaction 的雜湊值,所以只有當被簽名的資料是當前 transaction 的雜湊值時 op_checksig 才會正常工作。對任何其他資料做的簽名都無法正常工作。

通常,op_checksig 中使用的簽名是鏈下生成的,作為引數傳入解鎖指令碼中。為了訪問當前 transaction,我們改為在鏈上用指令碼直接計算出簽名。為此,作為引數傳入解鎖指令碼的不再是簽名,而是當前 transaction。用於計算簽名的 ecdma 公私鑰對也作為引數被傳入解鎖指令碼。通過當前 transaction 引數和私鑰引數,可以計算出乙個 ecdma 簽名,op_checksig 就可以用公鑰引數對這個計算出的簽名進行校驗了。如果校驗通過,我們就能確定,傳入解鎖指令碼的當前 transaction 引數是真實的當前 transaction,因為op_checksig 只有在被簽名資料為當前 transaction 的雜湊值時才會通過

用指令碼實現 op_push_tx 的演算法如下:

把當前 transaction 放到棧頂;

把私鑰放到棧頂(該私鑰公開在指令碼中,僅用於計算簽名,不控制任何位元幣);

執行指令碼中的 ecdsa 簽名演算法,用第1步和第2步放入棧中的 transaction 和私鑰計算出簽名;

把第2步的私鑰對應的公鑰放到棧頂;

執行 op_checksig;

第1、2、4步在解鎖指令碼中,第3、5步在鎖定指令碼中。

如果第5步的 op_checksig 校驗簽名通過,那我們就可以確認在第1步放入棧中的 transaction 引數確實是真實的當前 transaction,因為只有當前 transaction 的簽名才會被 op_checksig 校驗通過1

。op_checksig 並不關心簽名是在鏈下外部程式生成的(如 p2pkh 的情況)還是在鏈上指令碼中生成的(如 op_push_tx 的情況)。

值得注意的是第2步中的私鑰,通常私鑰都是要保密的,但它是公開在指令碼中的。這樣做沒問題,因為這個私鑰並不控制位元幣,而只是參與簽名計算以證明第1步的引數確實是當前 transaction。實際上,這個私鑰甚至可以重複使用。

更準確地說,第1步中的 transaction 並不是完整的當前 transaction 資料,而是由完整資料生成的 preimage,在後續的計算中還會再做兩次 sha256 運算。preimage 的格式規定如下:

注意,input 指令碼沒有包括在內。

scrypt 實現了 op_push_tx 演算法,並把它封裝成標準合約函式tx.checkpreimage,用於校驗傳入引數是否為當前 transaction 的 preimage。下面演示乙個例子,我們用它開發乙個名為 checklocktimeverify 的合約,該合約可以確保裡面的幣在某個時間之前不能被花費,類似於 op_cltv。通過驗證(即require(tx.checkpreimage(sighashpreimage)))後,你就可以訪問當前 transaction 中的資料了。

contract checklocktimeverify 

function

fromleunsigned

(bytes b)

returns

(int)

}

使用 op_push_tx 可以讓合約**訪問整個 transaction 資料,包括所有的 input 和 output。我們可以在合約中對這些資料設定任何約束條件。這為在位元幣網路上執行各種智慧型合約開闢了無限可能,以後我們會展示更多示例。

特別感謝 nchain 提供的原創想法。

除非出現了雜湊碰撞(兩段不同資訊的雜湊值相同),這種碰撞被認為是幾乎不可能出現的。在數字簽名中,被簽名的資料是資訊的雜湊值,不是資訊本身。 ↩︎

深入學習之http

http協議是無狀態的,指的是協議對於事務處理沒有記憶能力,伺服器不知道客戶端是什麼狀態。也就是說,開啟乙個伺服器上的網頁和你之前開啟這個伺服器上的網頁之間沒有任何聯絡。http是乙個無狀態的面向連線的協議,無狀態不代表http不能保持tcp連線,更不能代表http使用的是udp協議 無連線 從 h...

深入學習之淺拷貝

let foo let bar object.assign bar,foo foo.a foo.a 2 true bar.a 1 true 乍一看,好像已經實現了深拷貝的效果,對foo.a進行的操作並沒有體現在bar.a中,但是再往後看 foo.c.d foo.c.d 2 true bar.c.d ...

深入學習之載入機制

onload事件是因為瀏覽器的非同步機制產生的 文件本身 html dom結構生成 載入js,css,window.nl ad function jquery.fn jquery.prototype window.jquery window.jquery 3 有些時候我們需要儲存乙個值,讓這個值不受...