fbpx

EOS 智能合約開發教學

EOS 區塊鏈基本架構

之前兩篇廢文已經介紹過 EOS (EOS 介紹 1EOS 介紹 2),最後一篇來介紹一下如何開發 EOS DApp (智能合約)。開始之前,先介紹一下基本架構與元件。EOS 由 cleos, keosd, nodeos 三個主要的元件所組成,架構圖如下:

EOSIO Architecture

先介紹一下三個主要的 Component:

Cleos 為提供給開發者操作的 CLI (Command Line Interface) 工具,所有區塊鏈操作與錢包操作,都可以透過 cleos 完成。

Nodeos 負責與區塊鏈溝通,並且提供 REST API 讓外部進行呼叫。

Keosd 為一項錢包管理工具,一樣會提供 HTTP API 進使用者進行呼叫,在我們使用 cleos 的時候可以指定處理錢包的 keosd 位置。透過 keosd 管理錢包,將 keosd 與 nodeos 互相隔離,在安全性上會有很大的幫助。

安裝與啟動 EOS

我們建議透過 Docker 直接安裝 EOS,安裝 Docker 的方法可以參考此篇「Docker 安裝」文章前面第一節。安裝好 Docker 之後,先透過 docker pull 拉下最新的版本 (可以從這裡取得最新 EOS Docker),範例中拉 1.4.3 只是為了確保執行過程可以一致,如下:

docker pull eosio/eos-dev:v1.4.3

然後透過以下命令先啟動 Nodeos 服務,如下:

docker run \
  --name nodeos -d -p 8888:8888 \
  --network eosdev \
  -v /tmp/eosio/work:/work \
  -v /tmp/eosio/data:/mnt/dev/data \
  -v /tmp/eosio/config:/mnt/dev/config \
  eosio/eos-dev:v1.4.3 \
  /bin/bash -c \
  "nodeos -e -p eosio \
    --plugin eosio::producer_plugin \
    --plugin eosio::history_plugin \
    --plugin eosio::chain_api_plugin \
    --plugin eosio::history_api_plugin \
    --plugin eosio::http_plugin \
    -d /mnt/dev/data \
    --config-dir /mnt/dev/config \
    --http-server-address=0.0.0.0:8888 \
    --access-control-allow-origin=* \
    --contracts-console \
    --http-validate-host=false"

啟動之後會將 Nodeos API 綁定到 8888 Port,我們可以直接透過 curl 嘗試呼叫 API,如下:

curl http://localhost:8888/v1/chain/get_info

接著我們要啟動管理錢包的 Keosd 服務,一樣透過 Docker 啟動,令命如下:

docker run -d --name keosd --network=eosdev \
  -i eosio/eos-dev:v1.4.3 /bin/bash -c "keosd --http-server-address=0.0.0.0:9876"

啟動後錢包服務 API ㄏ會綁定在 9876 Port,我們在 Container 內呼叫 API 測試看看,如下:

docker exec -it keosd bash -c "cleos --wallet-url http://127.0.0.1:9876 wallet list keys"

運氣好的就可以看到以下畫面,顯示一個空的錢包:

透過 Cleos 操作 EOS 區塊鏈

由於 nodeoc 與 keosd 是兩個 Container,為了操作方便,我們先建立好 Command 環境。首先確認一下兩個 Container 的 IP Address,如下:

docker network inspect eosdev

上圖 docker network 顯示 keosd Container Address 為 172.29.0.3,接著我們在 Host 這裡建立一個 Command Alias,如下:

alias cleos='docker exec -it nodeos /opt/eosio/bin/cleos --url http://127.0.0.1:8888 --wallet-url http://172.29.0.3:9876'

於 Linux 建立 alias 之後,我們就可以快速在 Host 執行 Docker Container 裡頭的 cleos 命令,讓 cleos 用起來就像在 Docker 內執行的感覺一樣,這樣方便多了。

建立 EOS 錢包與帳號

開始之前,我們先建立自己的錢包,令命如下:

cleos wallet create --to-console

執行之後畫面會顯示這個錢包的密碼,未來需要用這個密碼來管理錢包,記起來即可。建立錢包後,我們透過 cleos wallet list 顯示錢包,現在就可以看到一個名叫 default 的錢包,如下:

接著我們將測試需要使用的鑰匙匯入錢包中,命令如下:

cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

匯入成功後輸入 cleos wallet keys 顯示錢包中的私鑰

透過 eosio 帳號建立一個 sjtest 新帳號,如下:

cleos create account eosio sjtest EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

帳號建立完成後,我們可以透過 Call API 取得帳號資訊,如下:

curl http://127.0.0.1:8888/v1/chain/get_account -X POST -d'{"account_name":"sjtest"}'

此外,如果要產生一組 Key 可以用以下命令:

cleos create key --to-console

第一個 EOS HelloWorld 智能合約

我在測試的時候官方提供的文件有不少錯誤,整理了 Google 上面的一些做法,確定可以按圖施工撰寫智能合約。範例透過 C++ 寫一個 HelloWorld Smart Contract,首先先在 Container 內建立目錄:

docker exec -it nodeos bash -c 'mkdir hello'

接著產生 C++ 程式碼,執行結果如下:

docker exec -it nodeos bash -c '
cat << EOF > /hello/hello.cpp
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;

class hello : public eosio::contract {
  public:
      using contract::contract;

      [[eosio::action]]
      void hi( account_name user ) {
         print( "Hello, ", name{user} );
      }
};

EOSIO_ABI( hello, (hi) )
EOF'

完成後我們需要先將 cpp 編譯 wasm 檔案,編譯命令與結果如下:

docker exec -it nodeos bash -c 'eosiocpp -o /hello/hello.wasm /hello/hello.cpp'

上述的 warning 可以不用理會,接著繼續編譯 abi 檔案,如下:

docker exec -it nodeos bash -c 'eosiocpp -g /hello/hello.abi /hello/hello.cpp'

wasm 與 abi 檔案都成功編譯後,接著我們要發布智能合約到 EOS 區塊鏈上,如下:

cleos set contract sjtest /hello -p sjtest

訊息會告訴我們這個 transaction 還沒有發布至網路,但是一樣可以執行,我們就來 Run 看看,如下:

cleos push action sjtest hi '["user"]' -p sjtest
cleos push action sjtest hi '["me"]' -p sjtest

一個超簡單的 HelloWorld 就完成了,如果你在 EOS 公鏈有帳戶的話,也可以用一樣的方法發布命令。這裡還有很多 cleos 常用的命令,其他像是 EOS Storage 的玩法我還沒研究,有心得再分享了.......啊掰~