1. 程式人生 > >比特幣的腳本系統 | 區塊鏈技術普及9.7

比特幣的腳本系統 | 區塊鏈技術普及9.7

從區塊到交易,再從交易到輸入輸出,我們越來越深入比特幣的“內臟”了,今天再往前走一步,看看比特幣的腳本系統是個什麼樣子。

比特幣的腳本系統是智慧合約的一個雛形,但它不是圖靈完備的,因為它沒有跳轉語句和迴圈語句,這兩種語句特別容易引發安全漏洞,而比特幣的設計是把安全放到第一位的,所以做出了這樣的妥協。 比特幣的腳本系統是後進先出的堆疊模型。

什麼叫堆疊?

你可以想象一個箱子,你往箱子裡一層層地堆木板,堆完後要拿出來時,只能先拿最頂上的那塊,也就是最後堆上去的那塊,再拿倒數第二塊,依次類推,後進先出。

比特幣的鎖定指令碼和解鎖指令碼,就是將資料一層一層壓入堆疊,然後再從上往下進行處理的過程。 我們從區塊瀏覽器上找一筆交易來對照進行學習。
這裡寫圖片描述

這筆交易裡有1個輸入(注意:輸入右邊括號裡的“輸出”,是指你點進去,可以看到是哪筆交易輸出給這個輸入的),兩個輸出,大家看看能不能找到對應的交易欄位?

不過,今天我們的重點不在這裡,重點在下面這個圖,這筆交易的解鎖指令碼和鎖定指令碼:

這筆交易只有1個輸入,所以只有1個輸入指令碼,也就是鎖定指令碼;有2個輸出,所以有2個輸出指令碼,也就是鎖定指令碼。

鎖定指令碼和解鎖指令碼是成對使用的,成對並不是指上圖那樣同一筆交易裡的輸入和輸出,而是指這筆交易的輸入和上筆交易的輸出,或者這筆交易的輸出和下筆交易的輸入。

因為這筆交易輸出的比特幣是“未使用”狀態(見上圖),還沒有下一筆交易。所以,我們只能拿這筆交易的輸入和上筆交易的輸出來學習了,點選上圖的“輸出”可以找到對應的輸出。我們把這對輸入輸出的鎖定指令碼和解鎖指令碼提取到一起。
這裡寫圖片描述


鎖定指令碼:
這裡寫圖片描述

解鎖指令碼:

這裡寫圖片描述
別看這些指令好像高深莫測,但我們前面已經積累了大量基礎知識,所以學習起來並不難,學完後你會發現這些指令實現的功能其實很簡單。

執行時,先執行解鎖指令碼的指令,再執行鎖定指令碼的指令。

ScriptSig就是解鎖指令碼的意思,因為在原始交易程式碼中,就是“ScriptSig”這個欄位來表示簽名部分,簽名部分包含簽名和公鑰。所以,這只是一個說明而已,不用管;

PUSHDATA(71)的意思是將後面的71個位元組壓入堆疊(堆疊就是一個箱子);

[]裡的這72個位元組就是簽名,所以,先把簽名壓到棧底了;

PUSHDATA(33)就是將後面的33個位元組壓入堆疊,[]裡的33個位元組是一個公鑰。

解鎖指令碼執行完畢,堆疊裡有了一個簽名和一個公鑰,簽名在棧底,公鑰在棧頂。 繼續執行鎖定指令碼的程式碼。

DUP的意思是把棧頂的資料複製一份,這樣,堆疊裡就有了3個數據,從底往上是:簽名+公鑰+公鑰;

HASH160是對棧頂資料進行雜湊運算,於是得到一個公鑰Hash,堆疊從底往上變成:簽名+公鑰+公鑰雜湊;

PUSHDATA(20)將後面[]裡的20個位元組放到棧頂,這20個位元組也是公鑰雜湊,堆疊從底往上變成:簽名+公鑰+公鑰雜湊+公鑰雜湊;

EQUALVERIFY是比較棧頂的兩個資料是否相等並彈出,如果不等,說明本次交易的傳送地址並不是上筆交易指定的目的地址,執行失敗;如果相等,指令碼會繼續執行,堆疊只剩:簽名+公鑰;

CHECKSIG的功能就是利用公鑰對簽名進行驗證,本來是一件挺複雜的事,但一條指令搞定。驗證通過後,交易才是有效的。

是不是很簡單?還是一臉懵逼?沒關係,多看幾次,再結合前面的文章,就懂了。網上有完整的比特幣指令大全,有興趣的童鞋可以去看看。