1. 程式人生 > >04.智慧合約與以太坊虛擬機器

04.智慧合約與以太坊虛擬機器

本章介紹智慧合約和以太坊虛擬機器,掌握智慧合約的作用和工作原理

4.1 智慧合約

  • 現實生活中經常遇到這樣的場景 買家與賣家要進行一筆交易,為了保證交易的順利進行,雙方簽訂了一份合約,合約中宣告雙方各自的身份、權利和義務(買家付錢、賣家交貨的時間節點和方式等),一式兩份,各自儲存 這樣,當交易出現糾紛時,合約將成為尋求法律援助的依據,而法律將成為確保合約執行的強制力保障

  • 雖然合約為交易的順利進行提供了一些保障,但是也存在很多不足之處 一旦交易中發生了糾紛,比如賣家拖延發貨或者買家拒絕付款,即使在法律的援助下解決了糾紛,交易的效率也會大大降低 甚至在一些情況下,合約將會失去約束效力,比如合約中存在歧義或者合約丟失等

  • 那麼有沒有一種更有效的方式來保證交易的進行呢?

  • 智慧合約就可以充當這樣一個代理人

  • 智慧合約就是區塊鏈上一個包含合約程式碼和儲存 間的虛擬賬戶 在這裡插入圖片描述

  • 智慧合約的行為由合約程式碼控制,而智慧合約的賬戶儲存則儲存了合約的狀態

  • 在以太坊平臺上,智慧合約的程式碼執行在以太坊虛擬機器( VM )中, EVM 個圖靈完備的虛擬機器,是以太坊協議的核心

  • 在以太坊的點對點( 2P )網路中,每個全節點上都包含 個以太坊虛擬機器,當節點需要打包或驗證區塊時,便將交易相關的可執行程式碼送入 EVM 中執行,執行的結果更新了以太坊賬戶的狀態並被記錄在區塊鏈上

  • 以太坊網路中的每個節點都需要在各自的EVM中執行程式碼,這就導致兩個問題。

    • 是這樣會產生大量的平行化計算,每個節點都必須執行程式碼以驗證區塊中的結果狀態,雖然犧牲了 定的計算效率,但保證了分散式網路中更高的安全性
    • 二是EVM 的執行結果必須有嚴格的確定性,所有節點必須得到同樣的執行結果 這就對智慧合約以及 EVM 造成定的侷限性,智慧合約目前仍無法實現 些可能會帶來不確定結果的簡單操作,如成隨機數、呼叫作業系統 PI 等,因為這些操作會因時間、系統等執行環境的差異而產不同的結果,進而使以太坊節點無法對區塊中的賬戶狀態達成共識

02. 智慧合約的操作

要建立一個智慧合約,需要經過編寫智慧合約、編譯成位元組碼 部署到區塊鏈等過程,呼叫智慧合約則是發起 筆指向智慧合約地址的交易,智慧合約程式碼分散式地執行在網路中每個節點的以太坊虛擬機器中

在這裡插入圖片描述

  1. 智慧合約的編譯過程,左邊是使用Solidity語言編寫的智慧合約,右邊是使用操作碼錶示的位元組碼 在這裡插入圖片描述
  2. 位元組碼由 連串的位元組組成,每 位元組表示一個操作 基於開發效率等多方面考慮,通常都不會直接書寫以太坊虛擬機器位元組碼,而是選擇一門高階語言編寫智慧合約程式碼,再編譯成以太坊位元組碼部署到區塊鏈上
  3. 當編譯完成得到 以太坊位元組碼之後,需要建立一個交易將合約部署到區塊鏈上
  4. 交易的“ data ”欄位儲存的是以太坊位元組碼,“ 。”的地址為一個空的賬戶 當該交易被“礦工”打包加入區塊鏈時,這個合約就建立完成了
  5. 區塊鏈上將出現 個與該智慧合約相對應的合約賬戶,井擁有一個特定的地址,而合約程式碼將儲存在該合約賬戶中
  6. Solidity 還提供了 個整合開發環境( IDE )一-Remix
  7. 測試是非常重要的,將一個包含缺陷的智慧合約部署到以太坊公有鏈上可能會造成災難性後果
  8. 呼叫一個智慧合約時,只需要發起一個指向合約地址的交易,並將合約需要的引數作為“ data ”欄位儲存在交易中即可
  9. 為了方便合約的呼叫和引數的傳遞,以太坊擁有一套互動的標準
  10. 使用 Solidity 語言編寫的智慧合約在編譯時都會自動生成 ABI8 (程式進位制介面) ABI 一個固定格式的字串,包含了合約中各函式的函式名 、引數數目和型別、返回值數目 和型別等資訊
  11. 作為服務提供者,合約建立者需要向用戶提供合約的 ABI、和合約地址,這樣使用者才能使用合約定義的功能
  12. 有些合約的邏輯中還包含銷燬功能,我們只需要像呼叫其他函式一樣呼叫這個功能就可以銷燬合約
  13. 當一個合約被銷燬後,合約賬戶的儲存和程式碼都將被清空,這裡的清空是指從當前狀態清空合約賬戶井產生新的狀態,並沒有對過往的區塊資料造成任何改變,所以在過往的區塊資料中仍然存在這部分資料的記錄
  14. 在軟體開發中有一個不得不提的過程,那就是軟體升級,無論是進行 bug 修復,還是增加新的功能,都需要對軟體進行升級
  15. 無法重新部署一個新的合約到相同的地址上,可以部署 個擁有呼叫轉發功能的智慧合約,將收到的呼叫轉發到另外 個包含邏輯功能的合約地址 當進行合約升級時,只需要部署一個新的合約並修改轉發的目標地址,以指向新的合約

03. 儲存方式

以太坊虛擬機器的儲存方式分為三類:

  • 棧( Stack )
  • 賬戶儲存(Storage )
  • 記憶體(Memory)
  1. 棧是一種常見的線性資料結構,支援兩種操作:將一個元素放到錢的頂部和從攏的頂部取出 個元素,元素具有先進後出的性質 以太坊虛擬機器是基於錢的虛擬機器,這意味著虛擬機器上的所有運算都執行在枝上 戰中每一個元素的長度是 256 位( bit 棋是以太坊虛擬機器的底層執行機制,當我們使用高階語言(比如 Solidity )編寫智慧合約程式碼時,並不需要直接對棧進行操作
  2. 賬戶儲存是作為賬戶的一個屬性儲存在區塊鏈上的,所以與硬碟一樣都是持久化儲存,並不會隨著合約執行結束而被釋放
  3. 記憶體是以太坊虛擬機器在執行程式碼時臨時分配的一塊線性空間,會隨著合約呼叫的結束自動釋放

04. 指令集和訊息呼叫

  • 以太坊虛擬機器有 套專門設計的指令集,包括了大多數常用的算術運算 位運算輯運算和比較運算,同時還支援條件跳轉和無條件跳轉
  • 為了便於開發者編寫功能更加豐富的智慧合約,以太坊允許合約在執行過程中通過創條“訊息”的方式來呼叫其他合約 -代理呼叫該:它與訊息呼叫的區別是它只從目標合約獲取程式碼並執行,卻不會改變當前的上下文環境,包括msg.sender msg.value 、當前賬戶、儲存、記憶體等,這使得智慧合約可以在執行時動態地從其他地址載入程式碼

05. 日誌

  • 日誌是以太坊虛擬機器提供的一項功能。
  • 開發者可以在合約程式碼執行過程中記錄各種事件產生的日誌,這些日誌可以幫助開發者除錯程式碼,或者作為在區塊鏈上發生交易的證據

在以太坊平臺上,智慧合約是儲存在區塊鏈上的邏輯程式碼,執行在以太坊虛擬機器中。使用智慧合約,使用者可以在以太坊平臺上面建立去中心化應用,Soidity是一門用於編寫智慧合約的高階語言,可以極大的提供智慧合約的開發效率,通過一個簡單的場景講述了智慧合約的原理以及優勢,部分智慧合約的底層工作機制,包括以太坊虛擬機器,儲存方式,指令集,和訊息呼叫等內容, 編寫一個合格的智慧合約。