『學概念找員外』比特幣腳本

比特幣 腳本語言 程序員 中本聰 劉員外999 2019-04-03

「力場 lichang.io」公鏈挖礦第一社區!

『學概念找員外』比特幣腳本

作為一個程序員,經常遇到的一個問題就是已經上線的系統總是會出現各種各樣的莫名其妙的問題,有些問題能提前規避,但是總有那麼少數的意外是無法避免的,所以需要不定時的維護更新自己寫的程序,這種頻率一般還挺高的,所以對一套系統來說,它的運營維護成本總是要高出開發成本若干倍。你可能會說,那還是你的技術水平不行,你看人家中本聰08年開發出來的比特幣,能平穩的運行到現在,算起來的有10個年頭了,人家是怎麼做到的呢?當然不可否認,這是所有的程序員都打心底裡傾佩的一個地方,都認為中本聰就是一個神級的人物。所以接下來員外給大家說道說道這個比特幣的腳本到底是怎麼做到安全運行10餘載的。

腳本的樣子

可能有很多小夥伴不理解腳本是什麼,比特幣的腳本其實就是比特幣的控制語言。最常見的比特幣交易,就是通過某人的簽名去取得他在前一筆交易中獲得的資金。這種情況下,交易的輸出包含這樣的信息:“憑藉地址X的所有者的簽名,才可以獲得這筆資金。”我們知道地址其實就是一個公鑰的哈希值,所以僅僅說地址X並沒有告訴我們公鑰在哪裡,也沒有給我們一個檢查簽名的方法。所以,交易輸出必須這樣描述:“憑藉哈希值為X的公鑰,以及這個公鑰所有者的簽名,才可以獲得這筆資金。”這實際上就是最常見的比特幣腳本。

例如:

OP_DUP
OP_HASH160
69e02e18...
OP_EQUALVERIFY
OP_CHECKSIG

誰執行腳本

那麼誰執行這個腳本?這一系列指令是如何完成的呢?其實交易的輸入包括了腳本(而不是簽名)。為了確認一筆交易正確地獲取了上一筆交易所輸出的資金,我們把交易的輸入腳本和上一筆交易的輸出腳本串聯起來,這個串聯腳本必須被成功地執行後才可以獲取資金。這兩個腳本,一個是輸出腳本(scriptPubKey),另一個是輸入腳本(scriptSig)。輸出腳本只是指定了一個公鑰(或是公鑰哈希值的地址),輸入腳本指定了一個對應公鑰的簽名。

例如:

<sig>
<pubKey>
------------------
OP_DUP
OP_HASH160
<pubKeyHash?>
OP_EQUALVERIFY
OP_CHECKSIG

為了確認當前交易是否正確地獲取了前一筆交易輸出的資金,我們把兩個腳本鏈接起來,把上一筆交易的輸出腳本(虛線下方)添加到當前交易的輸入腳本(虛線上方)之後,形成一個新的腳本。請注意<pubKeyHash?>裡面有一個“?”,用作標識來確認它是否與當前交易提供的公鑰的哈希值一致。

比特幣語言的介紹

這個腳本語言是專門為比特幣開發的,它是一種簡單的堆棧式編程語言。比特幣的腳本語言設計原則就是簡明扼要,並內生地支持加密操作。比如,腳本里面有目的性的指令用來計算哈希值和檢驗簽名。這種腳本語言因為是堆棧式的,意味著每個指令只被執行一次,是線性的,無法循環執行。所以指令的數目給了我們一個執行時間與內存使用的上限。這個語言不是圖靈完備的,意味著不能隨意運行強大函數功能。但這是有意設計的,因為礦工需要去執行這些網絡上任意交易提交者所遞交的腳本,設計者並不希望讓他們提交可能無限循環的腳本,那樣的話會增加很多意想不到的工作量。

執行比特幣腳本只能產生兩個結果:要麼被成功執行,這種情況下,交易有效;要麼腳本執行出現錯誤,這種情況下,整個交易無效,拒絕記入區塊鏈。這個腳本語言十分簡單。只有256個指令,每個只用一個字節。256個指令中,有15個目前不可用,有75個被保留還沒有具體定義(以後或許可以被用來擴展),剩下的才是可用的。

許多在其他語言裡常見的基本指令這裡面都有。例如,基本的算數、邏輯語句(如If、then)、拋出錯誤、過早返回等。而且,還有密碼指令,比如哈希函數語句、簽名驗證語句等。

員外覺得也正是因為比特幣腳本的簡單,越是簡單的語言在運行起來也就能將報錯率降到最低,或許這才是比特幣能安全運行10年的一個最根本的原因吧。

相關推薦

推薦中...