當您作為Solidity 開發人員開始您的旅程並開始積極編寫以太坊時 智能合約,您將很快遇到對EVM(以太坊虛擬機)、字節碼和ABI(應用程序二進制接口)的引用。如果您是一名JavaScript 開發人員(就像我第一次學習編碼時一樣),您可能不熟悉這些術語,或者您可能在其他上下文中聽說過它們並且想知道它們在Solidity 和以太坊世界。
本博客提供了這三個概念中每一個的技術概述。與代碼中的所有事物一樣,對於這些概念中的每一個,很容易迷失在兔子洞中,這可能會適得其反。相反,本博客將為您提供每個概念的可靠思維模型,以便您擁有立即獲得生產力所需的一切。
讀完這篇博文,你不僅會了解EVM、字節碼和ABI 是什麼以及為什麼會這樣,而且還會了解如何在實際項目中快速生成和使用字節碼和ABI。
如果您願意,還可以在YouTube 上查看此博客的視頻版本。
虛擬機和EVM
讓我們從以太坊虛擬機(EVM) 開始。稍等片刻,讓我們放下“以太坊”,了解什麼是虛擬機(VM)。通俗地說,VM 是(與所有軟件一樣)在硬件(具有內存、存儲、處理器和連接到電源的操作系統的計算機)上運行的軟件。但與其他軟件不同的是,VM 旨在模仿硬件——該軟件偽裝成一台真實的機器,就像音樂應用程序是虛擬立體聲系統一樣。這就是為什麼它是“虛擬”機器的原因——它不是物理的,但它模仿了物理機器。
為什麼我們需要虛擬機?它們是擴展、管理和更新運行軟件應用程序的基礎架構的有效方式。與其使用1000 台物理服務器,不如只使用20 台並在每台上運行50 台虛擬機。您甚至可以讓每個VM 運行不同的操作系統,這樣一個VM 可以運行Windows Server,另一個可以運行Linux Debian,第三個可以運行Gentoo Linux,第四個可以運行ChromeOS!
這樣做的好處是,您可以在這些VM 上運行多個應用程序,所有這些應用程序都在單個硬件機器上運行,以便更徹底地利用機器,更有效地使用其處理能力和系統資源——這對基礎架構更好費用。
以太坊虛擬機也是一個虛擬機。但是EVM 的目的是創建一個 去中心化的“世界計算機”,而不是優化利用硬件資源。 EVM 是一組單獨的、聯網的機器,稱為“節點”,它們試圖充當一台機器。每個節點運行一個客戶端軟件,該軟件實現 以太坊規範,並且由於它們都相互連接,因此它們形成了一個網絡。然後,這個節點網絡會同步其狀態(數據),以便它們一起形成一個始終同步的巨型數據庫。數據狀態的協議必須通過節點網絡實現,這是通過一個 共識 算法。
EVM 作為分佈式虛擬計算機,運行稱為智能合約的程序。像所有應用程序一樣,首先我們編寫智能合約,然後編譯它以便可以部署(在以太坊區塊鍊網絡上)。一旦存在,代碼就無法更改,因為區塊鏈在設計上是不可變的。部署代碼後,EVM 將成為執行代碼的環境。 EVM 是運行我們部署到它的智能合約的虛擬機。
我們通常用人類可讀的編碼語言編寫程序(即使當我們開始學習時它們看起來不是很可讀!)這是因為人類需要閱讀、編輯、維護和調試軟件。但是執行代碼的機器不閱讀人類可讀的語言。機器最適合處理二進制數據,它看起來像一串1 和0。所以在我們寫完代碼之後,我們問 編譯器 (這也是軟件)來“編譯”它以便它在機器上運行。
在Solidity 中,當我們編譯代碼時,我們會得到兩個“工件”:字節碼和ABI。
Solidity 中的字節碼
字節碼是我們的Solidity 代碼被“翻譯”成的信息。它包含對計算機的二進制指令。字節碼通常是緊湊的數字代碼、常量和其他信息。每個指令步驟都是一個操作,稱為“操作碼,”通常是一字節(八位)長。 這就是為什麼它們被稱為“字節碼”——單字節操作碼。
編寫的每一行代碼都被分解為操作碼,以便計算機在運行我們的代碼時確切地知道要做什麼。
在以太坊世界中,字節碼實際上是部署到以太坊區塊鏈的內容。當我們部署到以太坊網絡並使用Metamask 等基於瀏覽器的錢包確認交易時,我們實際上可以看到被部署的字節碼。有辦法將字節碼分解成操作碼片段,但那是另一天的事了。
字節碼是存儲在以太坊網絡上並在我們與智能合約交互時執行的內容。有許多工具和庫(包括官方的Solidity 編譯器,solc)可以幫助您將Solidity 代碼編譯成字節碼。但是一種快速的方法是在瀏覽器中編譯智能合約 混音IDE 然後復制ABI 和字節碼。
這是一個方便的專業提示,可以快速生成和復製字節碼。你可以點擊 這個鏈接 並在您的Remix IDE 中打開支持Chainlink Price Feeds 的Solidity 智能合約。您可以編譯然後復製字節碼,如下所示。簡單的!
Solidity 中的ABI 是什麼?
您可能聽說過API(應用程序編程接口)。這些基本上是一組方法、函數、變量和常量,您可以使用它們與庫、網絡端點、後端服務或其他軟件服務和應用程序進行交互。 API 是一種以可控、穩定和直觀的方式公開軟件功能的方法。 API 定義了兩個軟件可以相互交互的方式——一個接口。
ABI 是應用程序二進制接口。它們定義了智能合約中可用的方法和變量,我們可以使用它們與該智能合約進行交互。由於智能合約在部署到區塊鏈之前會轉換為字節碼,因此我們需要一種方法來了解我們可以與它們啟動哪些操作和交互,並且我們需要一種標準化的方式來表達這些接口,以便任何編程語言都可以用於與智能合約交互。雖然JavaScript 是與智能合約交互最常用的語言(主要是因為JavaScript 是一種前端瀏覽器語言,我們經常使用前端網頁與智能合約進行交互),但您可以使用任何編碼語言與智能合約進行交互,只要您擁有該智能合約的ABI 和一個庫,可幫助您與任何一個節點進行通信,從而為您提供進入以太坊網絡的入口點。
Solidity 中ABI 的結構
因此,ABI 是幫助我們了解可用於與智能合約交互的方法名稱、參數和參數以及數據類型的定義,以及智能合約發出的事件的結構。對於函數,以下是ABI 中的屬性 (資源):
- 類型: 指定函數的性質,將是`function`、`constructor`、`receive` 或`fallback` 之一。
- 姓名: 該函數的名稱是什麼。
- 輸入:具有以下架構的對像數組:
- 姓名:參數的名稱。
- 類型: 該參數的類型。
- 成分: 當類型是元組時使用。
- 輸出: 類似於輸入的對像數組。
- 狀態可變性: 一個字符串,指定此函數的狀態可變性。值是`view`、`pure`、`view`、`nonpayable` 和`payable`。
自定義錯誤和事件具有非常相似的架構,您可以研究它們 這裡.
ABI 表示為JSON,看起來像這樣:
[ { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [], "name": "getLatestPrice", "outputs": [ { "internalType": "int256", "name": "", "type": "int256" } ], "stateMutability": "view", "type": "function" } ]
您可以通過打開相同的方式在Solidity 中生成您自己的ABI 在您的Remix IDE 中啟用Chainlink Price Feed 的Solidity 智能合約 再次。然後編譯正確的合約並獲取如下所示的ABI。
您將看到ABI 為您提供了有關某事物是常規方法還是構造方法、它接受什麼輸入、它產生什麼返回值和數據類型等的詳細信息。這是您可以用來確定如何與智能合約交互的模式。當然,你最終會使用像這樣的庫 以太坊JS 實際與智能合約交互,但要這樣做,您將需要ABI。
這是獲取ABI 和字節碼的另一種方式:您可以使用Remix 的“編譯詳細信息”選項卡來獲取該信息等等。只是要小心選擇正確的合約來編譯,就像你編譯一個導入的庫或智能合約一樣,你不會生成任何字節碼——這只適用於你編寫的智能合約!
您現在對EVM 是什麼、字節碼是什麼以及它的作用以及為什麼ABI 對智能合約如此重要有了一個堅實的心智模型。重要的是,您還學習了一些絕妙的技術,您可以立即使用這些技術來加快開發過程,並直接在瀏覽器中使用智能合約及其編譯的工件。
如果您是開發人員並希望將Chainlink 集成到您的智能合約應用程序中,請查看 區塊鏈教育中心, 開發者文檔 或者 聯繫專家. 你也可以 直接通過去中心化的預言機將您的智能合約與現實世界的數據聯繫起來。