1. 程式人生 > >第一行程式碼:以太坊(2)-使用Solidity語言開發和測試智慧合約

第一行程式碼:以太坊(2)-使用Solidity語言開發和測試智慧合約

智慧合約是以太坊的核心之一,使用者可以利用智慧合約實現更靈活的代幣以及其他DApp。不過在深入講解如何開發智慧合約之前,需要先介紹一下以太坊中用於開發智慧合約的Solidity語言,以及相關的開發和測試環境。

智慧合約就是執行在以太坊上的程式。客戶端可以通過Web3.js API呼叫智慧合約,而智慧合約本身又可以直接訪問以太坊網路,也就是說,智慧合約前面連線著客戶端,後面連線著以太坊網路,起到了承前啟後的作用,而且通過智慧合約,可以讓整個以太坊網路更靈活,可控性更強。其實智慧合約的作用相當於微軟Office中的VBA,一個功能強大的領域指令碼語言。智慧合約的開發語言是Solidity,那麼Solidity是什麼呢?應該如何在以太坊網路上執行用Solidity語言編寫的智慧合約呢?本文將會揭曉這些問題的答案。

1. 什麼是Solidity語言

Solidity是一種用於編寫智慧合約的高階語言,執行在Ethereum虛擬機器(以太坊虛擬機器,EVM)之上。那麼Solidity到底是怎樣一種程式語言呢?或者說Solidity語言的主要特性是什麼呢?請繼續往下看。

Solidity語言的語法接近於JavaScript,是一種面向物件的語言。但作為一種真正意義上執行在網路上的去中心智慧合約,它又有很多的不同,下面列舉一些Solidity語言的主要特性。

  • 以太坊底層是基於帳戶的,因此在Solidity語言中有一個特殊的Address資料型別。用於定位使用者,定位合約,定位合約的程式碼(合約本身也是一個帳戶)。
  • 由於Solidity語言內嵌框架是支援支付的,所以提供了一些關鍵字,如payable,可以在語言層面直接支援支付。
  • Solidity語言可以將資料儲存在區塊鏈上,資料的每一個狀態都可以永久儲存,所以需要確定變數使用的是記憶體,還是區塊。
  • 執行環境是在去中心化的網路上,會比較強調合約或函式執行的呼叫的方式。因為原來一個簡單的函式呼叫變為了一個網路上的節點中的程式碼執行。
  • 最後一個非常大的不同則是Solidity語言的異常機制,一旦出現異常,所有的執行都將會被回撤,這主要是為了保證智慧合約執行的原子性,以避免中間狀態出現的資料不一致。有點類似於資料庫中的事務回滾。

2. 用Solidity語言開發智慧合約

Solidity是一種圖靈完備的程式語言,所以程式設計的方式與Java、C++類似。不過Solidity語言中並沒有類的概念,但有一個合約的概念,用關鍵字contract表示。任何一個Solidity程式,都必須至少有一個合約(contract)。在合約中可以編寫Solidity函式,類似於類中的方法。Solidity原始碼檔案的副檔名是sol,下面的例子給出了一個簡單的使用Solidity語言編寫的智慧合約的例子,以便讀者對Solidity語言和智慧合約有一個感性的認識。

下面的例子給出了一個名為Calc的智慧合約程式,在該智慧合約中有一個add函式,用於將兩個無符號整數相加,並返回相加的結果。

pragma solidity ^0.4.0;
contract Calc{
    function add(uint a,uint b) returns (uint){
        return a + b;
    }
}

儘管現在還沒有正式講解Solidity語言和智慧合約,不過從這段簡單的智慧合約程式碼也可以瞭解Solidity語言的結構。首先,智慧合約的第1行需要使用pragma solidity指定Solidity編譯器的最低版本,本例是0.4.0,也就是說,要編譯這段Solidity程式,Solidity編譯器的版本不能低於0.4.0。要記住,在版本號前面要加上“^”。

接下來就是用contract關鍵字宣告智慧合約,語法與類非常接近,智慧合約的名字跟在contract關鍵字後面,智慧合約中的程式碼用一對花括號括起來。

最後是在智慧合約中宣告若干個函式,函式的語法與JavaScript類似(都是使用function關鍵字宣告函式),不過也不完全相同,因為Solidity是強型別的程式語言,而JavaScript是弱型別的程式語言。也就是說,宣告Solidity變數需要指定資料型別,如本例的uint,表示無符號整數型別。函式的返回值型別需要在函式宣告的結尾通過returns關鍵字指定。如本例的returns(uint),函式返回值與C風格的程式語言相同,仍然使用return語句指定函式返回值。Solidity語言的每一條語句後面都要跟分號(;)。

3. 使用Remix執行智慧合約

學習編寫智慧合約最重要的一步就是執行智慧合約,否則無法知道我們編寫的智慧合約程式是否正確。在正常情況下,應該將智慧合約部署在以太坊網路上,然後通過以太坊客戶端呼叫,不過現在還沒有講如何將智慧合約部署到以太坊網路上,以及如何呼叫智慧合約。所以目前只能使用最簡單的方式測試智慧合約。以太坊官方提供了一個線上的智慧合約編寫和測試環境:Remix,通過這個工具,可以用不同的方式測試智慧合約。在瀏覽器位址列輸入如下的Url後,會進入Remix頁面。

Remix頁面主要包含如下4部分。

  • 智慧合約列表區域,位於Remix頁面的左側,如果第一次使用Remix,這個區域只有browser和config兩個節點,如果以前使用Remix建立過智慧合約,會在browser節點下方顯示曾經建立過的智慧合約檔案(.sol檔案)。
  • 程式碼區域,位於Remix頁面的中上部,用於編寫智慧合約程式碼。
  • 日誌區域,位於Remix頁面的中下部,執行智慧合約後,會將日誌資訊輸出到這一區域。
  • 設定區域,位於Remix頁面右側,在這一區域可進行各種設定,如將智慧合約部署在以太坊網路上,執行智慧合約等。

除了這4部分外,在Remix頁面左上角還有一排按鈕,其中最左側的加號按鈕用於新建智慧合約,最右側的加號和減號按鈕分別用於增加和減少智慧合約程式碼的字號。Remix頁面的整體佈局如下圖所示。

image.png

接下來單擊Remix頁面左上角的加號按鈕,會彈出一個如下圖所示的頁面,在“File Name”文字框輸入“Calc.sol”,然後單擊“OK”按鈕建立新的智慧合約。

image.png

將上一節給出的智慧合約程式碼輸入程式碼區域,可以點選加號和減號按鈕將程式碼字型調整到自己感覺舒服的程度,效果如下圖所示。在設定區域會出現一些警告,並不需要管它們。

image.png

在設定區域切換到“Run”頁面,所有的設定保持預設值即可,然後點選中間的“Deploy”部署Calc合約。成功部署Calc合約後,會在“Run”頁面下方根據Calc合約中的函式顯示相應的按鈕,如本例中只有一個add函式,並且該函式有兩個引數,所以在“Run”頁面下方會出現一個“add”按鈕,在按鈕旁邊的文字框輸入“3,4”,表示add函式的兩個引數值,如下圖所示。

image.png

最後單擊“add”按鈕執行add函式,會在日誌區域顯示相應的資訊,然後單擊日誌區域輸出資訊的向下箭頭,會在日誌區域顯示一個表格,在“decoded output”行會顯示add函式的返回值(計算結果),如下圖所示。

image.png

通過本節的若干步驟,終於成功運行了Calc智慧合約的add函式,並獲得了add函式的返回值(本例是7),不過這個智慧合約程式並沒有部署在以太坊網路上,而是在本地執行的,也就是說,本節其實是通過模擬的方式運行了本地合約,這種執行方式只能測試智慧合約中的函式的邏輯是否正確,並不能將以太坊客戶端、以太坊網路和智慧合約放到一起聯調,所以在實際的場景中,需要將智慧合約部署到以太坊網路上才能完整地對其進行測試。