智慧合約程式碼結構
我們都知道一個智慧合約其實就是一段程式碼,最終執行的是相應的編譯器編譯出的二進位制程式碼。這個執行二進位制程式碼的環境就叫 虛擬機器 。如果一條區塊鏈系統上集成了相應平臺的虛擬機器,就可以說這個區塊鏈系統支援了某個平臺的智慧合約。
我們知道第一個實現智慧合約的公鏈是以太坊,而以太坊實現智慧合約的技術原理來源於比特幣的指令碼程式碼。比特幣的指令碼的執行原理是基於 堆疊 這種資料結構的。具體可以去看 《精通比特幣》 的交易章節---比特幣交易指令碼和指令碼語言。
所以一個虛擬機器裡最基本也是最核心的資料結構就是要實現一個 堆疊(stack); 如同CPU結構裡的暫存器。我們知道CPU的結構包括: 計算單元,儲存單元,控制單元 。其實一個虛擬機器也是一個CPU,也包括這三個部分;在我們的程式碼結構中,這三個部分被封裝在了ExecutionEngine這個類中。

上面的程式碼可以看到。其實ExecutionEngine就是 控制單元 。用於在不同資料棧(單元)中的資料的協調。我們介紹一下在引擎中的作用:
invocationStack: 呼叫棧,在呼叫其他函式時或呼叫其他合約都會有一個新的呼叫棧。
EvaluationStack:計算棧,相當於CPU中的計算單元。儲存的是程式中的opCode指令。
AltStack:備用棧,計算棧算出的中間結果可以儲存在備用棧.
table:儲存單元,持久化合約程式碼的hash或其他資料的資料庫。
從上面的程式碼可以看出,除了上面的基本運算單元外,還有其他資料結構,我們也簡單介紹下:
crypto:區塊鏈系統用到的加密演算法。一般是ECDSA(橢圓加密)
dataContainer:觸發此合約的資料物件,通常是一個交易(transaction)
state:合約指令執行結果的狀態。(是否成功)
opCode:當前執行的指令碼。
service:虛擬機器互動層,用於一些系統指令的呼叫。
gas: 合約執行指定的燃料。
gasConsumed:當前已經消耗的燃料.
現在我們對相應資料的程式碼檔案進行簡單的介紹:

虛擬機器程式碼結構圖
上面的圖忘記了最重要的資料結構(堆疊)在utils包中:

堆疊
有了上面的內容,基本上就是一個虛擬機器了,可以執行一些簡單的邏輯處理了。但是我們除了基本的運算功能之外,既然智慧合約是執行在區塊鏈上的。就要訪問區塊鏈的資料。比如:BlockChain.GetHeight();獲取當前區塊鏈的高度。這樣的指令我們稱為 系統指令 。其實這部分指令也就是上面我們介紹的 互動層(service) :只要我們實現相應的資料結構,就要以當作引數傳入虛擬機器。然後虛擬機器就可以根據解析出的指令找到相應的邏輯處理。在我們的程式碼中是定義在了一個叫做StateReader(狀態讀取,就是對區塊鏈系統的相應資料讀取)的檔案中

狀態讀取器
上面的程式碼只是一部分,實現的是相應的執行時狀態讀取和區塊鏈資料的讀取。當然,除了讀取也會有寫入操作,區塊鏈中最寶貴的資源當然是空間。寫入資料我們是按照位元組收費的。相應的程式碼我們定義在stateMachine檔案中。

合約的一些操作
既然提到了收費,就簡單介紹下。我們的合約裡是按指令收費的:

合約指令費用
OK。到這裡,基本上一個虛擬機器執行所需的程式碼結構我們基本上有了個框架。其中的細節,就是相應的虛擬機器執行過程,還需要大家仔細閱讀相應的原始碼。