智慧合約開發(3)—— 以太坊虛擬機器(EVM)基礎

麥神無敵發表於2018-08-18

以太坊虛擬機器(EVM)是以太坊中智慧合約的執行環境。它不僅被沙箱封裝起來,事實上它被完全隔離,也就是說執行在EVM內部的程式碼不能接觸到網路、檔案系統或者其他程式。甚至智慧合約與其他智慧合約之間也只有有限的接觸

(1) 賬戶
以太坊有兩類賬戶,共用一個地址空間:外部賬戶(被公鑰——私鑰對控制),合約賬戶(被儲存在賬戶中的程式碼控制)。
外部賬戶的地址由公鑰決定,合約賬戶的地址在建立合約時確定(這個地址由合約創造者的地址和該地址發出過的交易數量計算得到,地址發出過的交易數量被稱作“nonce”)。
合約賬戶中儲存了程式碼,外部賬戶沒有。
每個賬戶都有一個key-value形式的持久化儲存。其中key和value長度都是256bits,名字都叫做storage。
每個賬戶都有一個以太幣餘額(單位為‘Wei’),該賬戶餘額可以通過向他傳送帶有以太幣的交易來改變。

(2)交易
一筆交易就是一條訊息,從一個賬戶傳送到另一個賬戶(可能是相同的賬戶或者零賬戶)。交易可以包含二進位制資料(payload)和以太幣。
如果目標賬戶包含程式碼,該程式碼會執行,payload就是輸入資料。
如果目標賬戶是零賬戶(賬戶地址是0),交易將建立一個新合約。正如上文所講,這個合約地址不是零地址,而是由合約建立者的地址和該地址發出過的交易數量(被稱為nonce)計算得到。建立合約交易的payload被當做EVM位元組碼執行。執行的輸出作為合約程式碼被永久儲存。這意味這,為了建立一個合約,你不需要向合約傳送真正的合約程式碼,而是傳送能夠返回真正程式碼的程式碼(注意這句話很重要)。

(3)Gas
以太坊上每筆交易都會被收取一定數量的gas。

(4)儲存,主存和棧
每個賬戶都有一塊持久化記憶體區域被稱為儲存。形式為key-value。一個合約只能對他自己的儲存進行讀寫。
第二個記憶體區被稱為主存。合約每次執行訊息呼叫時,都有一塊新的,被清除過的主存。
EVM不是基於暫存器,而是基於棧的虛擬機器。

(5)指令集
EVM的指令集被刻意保持在最小規模,以儘可能避免可能導致共識問題的錯誤實現。

(6)訊息呼叫
合約可以通過訊息呼叫的方式來呼叫其他合約或者傳送以太幣到非合約賬戶。

(7)程式碼呼叫/庫
存在一種特殊型別的訊息呼叫,被稱為callcode。它跟訊息呼叫幾乎完全一樣,只是載入自目標地址的程式碼將在發起呼叫的合約上下文中執行。
這意味著一個合約刻意在執行時從另外一個地址動態載入程式碼。儲存,當前地址和餘額都指向發起呼叫的合約,只有程式碼是從被呼叫地址獲取的。Soli可以實現‘庫’。

(8)日誌
在區塊層面,可以用一種特殊的可索引的資料結構來儲存資料。這個特性被稱為日誌,solidity用它來實現事件。合約建立之後就無法訪問日誌資料,但是這些資料可以從區塊鏈外高校的訪問。因為部分日誌資料被儲存在布隆過濾器(Bloom fliter)中,我們可以高效並且安全的搜尋日誌,所以那些沒有下載整個區塊鏈的網路節點(輕客戶端)也可以找到這些日誌。

(9)建立
合約甚至可以通過一個特殊的指令來建立其他合約(不是簡單的向零地址發起呼叫)。建立合約的呼叫跟普通的訊息呼叫的區別在於,負載資料執行的結果被當做程式碼,呼叫者/建立者在棧上得到新合約的地址

(10)自毀
只有在某個地址上的合約執行自毀操作時,合約程式碼才會從區塊鏈上移除。合約地址上剩餘的一臺幣會傳送給指定的目標,然後其儲存和程式碼被移除
注意,即使一個合約的程式碼不包含自毀指定,依然可以通過程式碼呼叫(callcode)來執行這個操作。

相關文章