系列文章:
1. 在你的contract目錄下面建立一個新的文件夾helloWorld。
cd /Users/yourUserName/Documents/EOS/contracts
mkdir helloWorld
cd helloWorld
2. 在剛剛新建的文件夾裏面創建一個C++文件。
touch helloWorld.cpp
3. 在其中編寫以下內容。
#include <eosio/eosio.hpp> //導入eosio頭文件
using namespace eosio; //使用命名空間,可以使代碼更加簡潔,因爲eos中所有類跟函數都在eosio命名空間下;
class [[eosio::contract]] helloWorld : public contract { //合約需繼承自eosio::contract(因爲使用了命名空間,此處可以簡寫爲public contract);
//同時使用[[eosio::contract]]來指定編譯器生成主調度程序並用來生成ABI。
public:
using eosio::contract::contract; //繼承eosio::contract中的構造函數,可省略eosio::;
[[eosio::action]] //用eosio::action來修飾該方法爲一個動作;
void hello( name user ) { //name是eosio中的一種常用數據類型;
print( "Hello World", user );
}
};
注: #warning "<eosiolib/eosio.hpp> is deprecated use <eosio/eosio.hpp>" ,eoiso.hpp源文件中寫明以上警告。
4. 編譯該文件。合約需要編譯成wasm格式才能部署到區塊鏈網絡上。
eosio-cpp helloWorld.cpp -o helloWorld.wasm
會出現以下警告,無需理會。
Warning, empty ricardian clause file
Warning, empty ricardian clause file
Warning, action <hello> does not have a ricardian contract
編譯成功後在.cpp同目錄下會多出.abi和.wasm兩個文件。 .abi全稱爲application binary interface,是基於json的接口說明文檔。.wasm爲二進制文件,是Web Assembly的一種格式,其有另一種可讀的文本格式wast,兩者等價。
5.創建一個叫hello的賬戶,後續將把上面的合約部署到該賬號上。
cleos create account eosio hello EOS6GwYrUANGhouVRR97W8ukiCPX49Z74toqMTTxGH8mViYiPuuPi -p eosio@active
意思是賬戶eosio創建類賬戶hello,並使用公鑰EOS6G...uPi賦予了其active權限。如果使用 cleos get account hello後會發現owner權限公鑰也被設置爲與active權限同樣的公鑰
同時創建賬戶bob。此處爲了簡便使用了同樣的公鑰。
cleos create account eosio bob EOS6GwYrUANGhouVRR97W8ukiCPX49Z74toqMTTxGH8mViYiPuuPi -p eosio@active
6. 將helloWorld合約部署到賬號hello上。
cleos set contract hello /Users/yourUserName/Documents/EOS/contracts/helloWorld -p hello@active
命令行解釋:set contract accountName contractDirect. 即部署到hello用戶,合約地址爲/...../helloWorld. 權限爲hello用戶到active權限。
輸出如下,因爲我已經運行過了,所以這裏顯示abi與已存在的相同。
Reading WASM from /Users/yourUserName/Documents/EOS/contracts/helloWorld/helloWorld.wasm...
Skipping set abi because the new abi is the same as the existing abi
Publishing contract...
executed transaction: b73420d8256676389aaeffbcd8f6e0d30d76d3cdaebae8ada5988844f3098cde 640 bytes 358 us
# eosio <= eosio::setcode {"account":"hello","vmtype":0,"vmversion":0,"code":"0061736d0100000001370b6000017f60027f7f0060037f7f...
warn 2020-04-22T01:24:38.839 thread-0 main.cpp:506 print_result warning: transaction executed locally, but may not be confirmed by the network yet
7. 執行helloWorld合約。
cleos push action hello hi '["bob"]' -p bob@active
結果如下。
executed transaction: 8857adbe3a2671c98f39ec7dc212313163092eea09f096f4c3c14bbc64e396ae 104 bytes 154 us
# hello <= hello::hello {"user":"bob"}
>> Hello Worldbob
warn 2020-04-22T01:27:29.754 thread-0 main.cpp:506 print_result warning: transaction executed locally, but may not be confirmed by the network yet
另外,下面添加了一行用戶驗證,即輸入name參數必須與接收人一致,否則合約無法執行。
#include <eosio/eosio.hpp> //導入eosio頭文件
using namespace eosio; //使用命名空間,可以使代碼更加簡潔,因爲eos中所有類跟函數都在eosio命名空間下;
class [[eosio::contract]] helloWorld : public contract { //合約需繼承自eosio::contract(因爲使用了命名空間,此處可以簡寫爲public contract);
//同時使用[[eosio::contract]]來指定編譯器生成主調度程序並用來生成ABI。
public:
using eosio::contract::contract; //繼承eosio::contract中的構造函數,可省略eosio::;
[[eosio::action]] //用eosio::action來修飾該方法爲一個動作;
void hello( name user ) { //name是eosio中的一種常用數據類型;
require_auth( user );
print( "Hello World", name{user} );
}
};
注:本文參考自官方開發文檔,並加入適當註解。