智能合約教學(1) HelloWorld合約
雖然之前也改過某山寨幣的錢包兼挖礦程式,不過感覺這年頭沒寫個智能合約都沒臉跟人說自己在幣圈中也是懂點技術的人,所以接下來打算寫幾篇簡單的智能合約介紹,以及講解能和智能合約互動的Web3網頁
按照慣例,第一篇就來寫個HelloWorld程式,智能合約的HelloWorld程式就是設置一個合約的狀態變數value,然後設一個函數get()用來讀取,再設一個函數set()用來寫入,這裡的解說會假設閱讀者已經對程式語言有基本的了解,會寫簡單的程式只是沒碰過智能合約程式,所以不會從程式的基本開始講解
以下為完整程式碼:
https://github.com/vcckvv/SmartContract/blob/gh-pages/HelloWorld/HelloWorld.sol
--------------------------------
pragma solidity ^0.4.0;
contract HelloWorld {
string value;
constructor() public {
value = "HelloWorld!";
}
function get() public view returns (string memory) {
return value;
}
function set(string memory v) public {
value = v;
}
}
--------------------------------
解說:
pragma solidity ^0.4.0;
這一行是用來指示編譯器的最低版本,設定後可以用的版本是0.4.X,另外更新的版本會有些新功能可以使用,不過有些地方的寫法也會不太一樣,這裡作為練習就先使用這個版本,之後才打算換成新版本來寫
--------------------------------
contract HelloWorld {
這一行用來設定合約的名字HelloWorld,被大括號{}圍住的部份就是合約的內容
--------------------------------
string value;
放在合約內宣告的變數即為合約的狀態變數,代表這筆字串資料value會存在區塊鏈上
--------------------------------
constructor() public {
value = "HelloWorld!";
}
constructor()函數只會在合約發布時執行一次,之後就不能再呼叫,主要用來對一些變數進行初始化設定,這裡就把value設定成"HelloWorld!"這個字串
--------------------------------
function get() public view returns (string memory) {
return value;
}
讀取的函數get()用view returns修飾詞後面再接上想回傳的變數型態
這裡的string如果是區域變數則要加上memory的修飾詞,代表執行完後就會消失的暫時變數資料,反過來如果是會留在鏈上的變數資料則是加storage的修飾詞,不過使用上比較像是指標,之後有用到的話再去詳細解釋
函數後面加上public修飾詞,代表這些函數可以被自由地公開呼叫,後面有機會的話還會再提到其他的修飾詞,有些只能被內部使用、無法公開呼叫
--------------------------------
function set(string memory v) public {
value = v;
}
寫入的函數就只需要加上public修飾詞就好,也不用進行回傳
--------------------------------
這裡使用的編譯器是Remix:https://remix.ethereum.org/ ,因為是線上網頁編譯器,所以打開就可以用,個人用起來的經驗是覺得還算方便,就算網頁當掉也有自動存檔,缺點大概就是虛擬機跑得很慢、容易當掉
介面打開後如上圖,點選左邊的File explorers按鈕後會出現檔案列表:
一開始會有些範例檔案,因為不重要所以可以全刪掉,接著點選裡面Create New File的按鈕來新增檔案HelloWorld.sol:
接著會自動開啟新的編輯視窗,之後就可以把上面的合約的程式碼複製進去,按Ctrl+S可以存檔加自動編譯
然後按左邊的Solidity Compiler按鈕,就會出現編譯器介面:
因為會自動判斷程式碼指示的編譯器版本,所以應該會自動轉成0.4.26的編譯器版本,如果沒有就自己點選版本,確定沒問題就按下Compile HelloWorld.sol的按鈕,成功的話就不會出現錯誤,且Solidity Compiler按鈕上會出現一個勾號
接著進到發布智能合約的環節,按下左邊的Deploy & run transactions按鈕:
一開始測試的時候先在內建的虛擬機上運行會比較方便,所以ENVIRONMENT是選Remix VM,ACCOUNT代表要發布合約的帳號,直接用預設的就好,CONTRACT應該是顯示HelloWorld - HelloWorld.sol這個合約,如果之後要寫內含多個contract的程式碼,要注意一下這個地方不要選錯主要發布的合約,免得之後實際發布的時候浪費錢
全部確定之後就按下Deploy按鈕,接著下面會產生一個操作函數介面,一開始是縮起來的,點選>箭頭按鈕打開後會呈現下圖的樣子:
按下get按鈕後會執行get()函數,然後顯示出回傳的值:「0: string: HelloWorld!」
在set按鈕旁邊可以輸入字串,這裡填入test然後按下set按鈕,這樣的話就會把test當作輸入字串執行set()函數
為了要檢查結果,我們再按下get按鈕,然後顯示出回傳的值:「0: string: test」,這樣就代表value的值在虛擬機中有確實地被改變成設定的值
--------------------------------
當然,如果只有在虛擬機上玩玩實在沒什麼意思,接下來我們開始發布到測試鏈上,然後在EtherScan的介面上也來實際操作看看
首先開啟MetaMask,然後換到Goerli的測試鏈上,如果沒找到的話代表被隱藏起來,此時把Show test networks選項打開就能看到,如果沒Goerli的幣的話,可以先去水龍頭網站領取:https://goerlifaucet.com/ (這個要用google帳號登入alchemy才能領,有要填資料的話隨便填填就好)、https://faucets.chain.link/goerli (很方便領取的水龍頭,不過有時會沒辦法領,剛才點進去看又變404了,可能要有緣才能領到)
這次發布時ENVIRONMENT選擇Injected Provider - MetaMask
按下Deploy按鈕後MetaMask會跳出視窗要求簽署交易
按下Confirm之後,底下結果視窗會顯示出一個view on etherscan的連結
點進去就會看見自己剛發布在測試鏈上的創立合約的交易資料:
https://goerli.etherscan.io/tx/0x43ea64aec24415cac0d0d4f15c90de68001d355a2855792913d174a203c18022
如果馬上點進去看,可能這筆交易會顯示還沒上鏈,那樣的話要再等一段時間
之後頁面中有一個[Contract 0x8abb77ff22f8966729603bd49c5c049c4294efd5 Created],0x8abb77ff22f8966729603bd49c5c049c4294efd5就是這次合約的位址,接著再點進其中的連結:https://goerli.etherscan.io/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5
連結頁面底下有個Contract按鈕,按了會顯示合約編譯後的十六進位資料,不過裡面還有個Verify and Publish連結,可以把我們的程式碼輸入進去,EtherScan會自動產生操作函數的介面
點進Verify and Publish連結後,Contract Address會自動填好,Compiler Type因為是單一檔案所以選Solidity(Single file),Compiler Version選和編譯時相同的0.4.26,Open Source License Type隨便選個喜歡的就好,之後按下Continue按鈕
下一個頁面在Enter the Solidity Contract Code below底下的輸入框中複製程式碼進去
接著驗證不是機器人後就可以點下Verify and Publish按鈕,成功的話就會顯示Successfully generated ByteCode and ABI for Contract Address
之後回到https://goerli.etherscan.io/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5#code 頁面就可以看到輸入的程式碼和互動介面了
點選Read Contract按鈕開啟讀取合約互動頁面,會顯示一個項目get,按下去就會顯示現在的value資料是什麼,第一次會顯示:HelloWorld! string,如果想要更新就按旁邊的[Reset]連結
接著點選Write Contract按鈕開啟寫入合約互動頁面,首先點那個Connect to Web3,選擇MetaMask錢包進行連結,會變成Connected - Web3 [...],之後就可以開始操作下面的set函數,打開項目set後在v (string)的輸入框中輸入test
然後點下Write按鈕,MetaMask會跳出交易要你簽署,按下Confirm後就完成寫入的操作,之後就會如下圖那樣,多一個View your transaction按鈕可以看這次寫入的交易
接著等到交易成功上鏈的訊息出現後就可以再到Read Contract頁面那裡,可以看到資料變成test string
--------------------------------
另外一提,在Remix中也可以在Deploy介面中的At Address旁邊的輸入框輸入我們發布好的鏈上合約位址0x8abb77ff22f8966729603bd49c5c049c4294efd5,然後點選At Address按鈕後下面也會出現合約互動介面,這個介面可以用來和鏈上合約互動,這樣就不用每次測試時都要到etherscan那邊做Verify and Publish才能有合約互動介面
--------------------------------
以上操作完就代表我們的合約運作沒有問題,不過我們的HelloWorld還沒結束,下一篇要來介紹一下如何寫一篇網頁來和這個合約進行互動