EOS 合約探索筆記

安裝 EOS :

$ brew tap eosio/eosio

$ brew install eosio

安裝 EOS 工具鏈:

$ brew tap eosio/eosio

$ brew install eosio

工具鏈文檔:https://eosio.github.io/eosio.cdt/1.6.0/

開發環境搭建

啓動節點

  • 啓動 keosd : keosd &
  • 啓動 nodeos :
nodeos -e -p eosio \
--plugin eosio::producer_plugin \
--plugin eosio::chain_api_plugin \
--plugin eosio::http_plugin \
--access-control-allow-origin='*' \
--contracts-console \
--http-validate-host=false \
--verbose-http-errors >> nodeos.log 2>&1 &

創建開發錢包(Create Development Wallet):

  • 1.創建錢包(僅測試用):cleos wallet create --to-console
    return_password :PW5J3thuJq6RuoeuAj4YvinoccKaKQsyJmc8UfqkZGUthVe5vimvK
    錢包(Wallet) 並不存儲 token ,僅僅存儲私鑰,並用私鑰來簽署交易
  • 2.打開錢包:
    cleos wallet open
    cleos wallet list

    1. 解鎖 : cleos wallet unlock
    1. 在錢包中創建私鑰: cleos wallet create_key
      return_public_key : "EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W"
    1. Development Public Key : EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W
    1. Import the Development Key
      每個新的 EOSIO 鏈都有一個默認的系統用戶叫 “eosio” ,這個用戶按協議來初始化鏈,包括治理和共識,每一個鏈都有一個相同的 dev key,系統用戶 “eosio“ 需要導入這個 key 去簽署交易
      執行:cleos wallet import
      輸入:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
      返回: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

創建測試賬戶(Create Test Account)

wallet裏可以導入private-key, 由private-key可以推導出public-key,一個賬號有個最長12個字符的account name,賬號對應的權限是有其對應的key決定的,基本的有ownneractive這兩類key.
TODO:owner/active分別代表什麼?

帳戶是一組授權,存儲在區塊鏈上,用於識別 from / to。
我們將使用 cleos create account 創建兩個賬戶 bob 和 alice

    1. Create Test Account
      cleos create account eosio bob EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W
      cleos create account eosio alice EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W
    1. Public Key
      cleos get account alice

創建hello合約 (1.6.0):

在當前目錄創建名爲 hello 的合約模版:
編譯合約:編譯後會在 build/hello 目錄下生成 wasm 和 abi 等信息

eosio-init -path=./ -project=hello
cd hello/build ; cmake .. 
make 

編譯結果包含 hello.wasm 和 hello.abi 文件在 hello/build/hello 中,

部署hello合約

合約部署是指部署到一個 account 上,這個賬戶將成爲合約的接口

查看本地已解鎖的可用公鑰 : cleos wallet keys

$> cleos wallet keys
[
  "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
  "EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W"
]

爲合約創建一個 account : cleos create account

$> cleos create account eosio hello EOS7rKrA84f8R16Z9mhG3aU7tUQsVuTi4hwjPKabtxU1RAEpQd51W -p eosio@active

executed transaction: 18b84d215c6aeebaf82050d1c7be64971995e2d257eed2916017880d1f7ddbfb  200 bytes  216 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"hello","owner":{"threshold":1,"keys":[{"key":"EOS7rKrA84f8R16Z9mhG3aU7tUQ...

部署hello合約到鏈上: cleos set contract
注意 CONTRACTS_DIR 需要是絕對路徑

$> cleos set contract hello CONTRACTS_DIR/hello -p hello@active

Reading WASM from /Users/liangc/bin/eosdemo/hello/build/hello/hello.wasm...
Publishing contract...
executed transaction: 9d8f62fe22c48d322459ac4c5136339aef0202d2616288c51a8ae6b270b4c349  760 bytes  3758 us
#         eosio <= eosio::setcode               {"account":"hello","vmtype":0,"vmversion":0,"code":"0061736d0100000001370b60027f7f0060017e0060017f00...
#         eosio <= eosio::setabi                {"account":"hello","abi":"0e656f73696f3a3a6162692f312e3100010268690001026e6d046e616d6501000000000000...
warning: transaction executed locally, but may not be confirmed by the network yet

執行hello合約(push an action): cleos push action

$> cleos push action hello hi '["bob"]' -p bob@active

executed transaction: eab9a201c73785b635d3e11c9aad3a137d0f462eaa56461b5aa63938f30a51bb  104 bytes  1458 us
#         hello <= hello::hi                    {"nm":"bob"}
>> Name : bob

EOS合約虛擬機

EOS-WASM 引擎代碼
https://github.com/EOSIO/eos/tree/master/libraries/wasm-jit

一個小玩具(非生產環境)
https://github.com/wasmerio/kernel-wasm

Building and running it

To build it, you'll need CMake and LLVM 4.0. If CMake can't find your LLVM directory, you can manually give it the location in the LLVM_DIR CMake configuration variable. Note that on Windows, you must compile LLVM from source, and manually point the LLVM_DIR configuration variable at <LLVM build directory>\lib\cmake\llvm.

ubuntu deps

sudo apt install -y git make bzip2 automake libbz2-dev libssl-dev doxygen graphviz libgmp3-dev autotools-dev libicu-dev python2.7 python2.7-dev python3 python3-dev autoconf libtool curl zlib1g-dev sudo ruby libusb-1.0-0-dev libcurl4-gnutls-dev pkg-config patch

build eos

依賴安裝完成後編譯:scripts/eosio_build.sh
會在如下路徑找到目標靜態庫:eos/build/libraries/wasm-jit/

到此爲止吧,因爲這個 wasm-jit 的 main 函數已經落後 WAVM 了,他是 fork 自 WAVM ,所以直接使用 WAVM 也可以運行 eos 的 wasm 合約

WAVM 引擎編譯與使用

這個模塊是 wasm 的執行引擎,可以單獨編譯成一套工具集
編譯這個模塊需要配置 LLVM_DIR 環境變量,指向 ${LLVM_HOME}/lib/cmake/llvm/
假設我們的 LLVM_HOME=/usr/lib/llvm
則 export LLVM_DIR=/usr/lib/llvm/lib/cmake/llvm/

編譯

$> git clone https://github.com/WAVM/WAVM.git
$> cd WAVM; mkdir build; cd build; cmake ..
$> make -j4
$> export PATH=`pwd`/bin:$PATH

這時在 bin 目錄下可以看到如下工具集

$> ll bin/
-rwxrwxr-x  1 liangc liangc  560472 7月  10 14:14 wavm-as*
-rwxrwxr-x  1 liangc liangc  630672 7月  10 14:15 wavm-compile*
-rwxrwxr-x  1 liangc liangc   22720 7月  10 14:14 wavm-c-test*
-rwxrwxr-x  1 liangc liangc  487944 7月  10 14:14 wavm-disas*
-rwxrwxr-x  1 liangc liangc  914784 7月  10 14:15 wavm-run*
-rwxrwxr-x  1 liangc liangc  691552 7月  10 14:15 wavm-run-wasi*
...

開發時主要會用到以下幾個工具

  • wavm-as : 將 wast 轉爲 wasm
  • wavm-disas : 將 wasm 轉爲 wast
  • wavm-run : 用來執行 wasm / wast

關於 wast 的 s 表達式

https://developer.mozilla.org/zh-CN/docs/WebAssembly/Understanding_the_text_format

emcc (emscripten) 編譯器

emcc 用於將 c/c++ 編譯成 wasm ,需要依賴 llvm

安裝:

$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install sdk-incoming-64bit binaryen-master-64bit
$ ./emsdk activate sdk-incoming-64bit binaryen-master-64bit

神祕的編譯指令:
https://github.com/emscripten-core/emscripten/blob/1.29.12/src/settings.js#L388

識別一個 wasm 文件的標識爲前 8 個字節

0000000: 0061 736d              ; WASM_BINARY_MAGIC
0000004: 0d00 0000              ; WASM_BINARY_VERSION

編寫測試代碼

研究到這,其實已經可以擺脫 eos 來使用 wavm 執行 eos 提供的 wasm 代碼了,但是 eos 封裝了一整套的庫文件,還有整個合約函數的代理函數,導致我們無法通過 eos 合約編譯出來的 wasm 的導出函數直接調用合約,因爲我們不知道正確的參數是什麼。

TODO :還要繼續閱讀 eos 提交一個 action 與參數到引擎執行並返回結果的一整套代碼邏輯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章