在先前建立的contracts
目錄中建立一個名爲「hello」的新目錄,或者經過系統GUI或cli建立一個名爲「hello」的目錄並進入目錄。git
cd CONTRACTS_DIR mkdir hello cd hello
建立一個新文件「hello.cpp」並在你喜歡的編輯器中打開它。github
touch hello.cpp
將所需的庫包含在文件中。segmentfault
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp>
爲了使合約中的內容更簡潔,請使用命名空間eosio
。編輯器
using namespace eosio;
eosiolib/eosio.hpp
將EOSIO C和C++ API加載到合約範圍內,這是你的新戰爭。建立一個標準的C++ 11類,合約類須要繼承eosio::contract
。ide
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public contract {};
空合約沒有多大好處,添加public
訪問修飾符和using
聲明,using
聲明將容許咱們編寫更簡潔的代碼。區塊鏈
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public contract { public: using contract::contract; };
這份合約須要作點什麼,本着hello world的精神編寫一個接受「name」參數的action,而後輸出該參數。測試
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( "Hello, ", name{user}); } };
上面的操做接受一個名爲user
的參數,它是一個name
類型,EOSIO附帶了許多類型定義,你會遇到的最多見的類型定義之一是name
,使用先前包含的eosio::print
庫,鏈接字符串並打印user
參數,使用name{user}
的支撐的初始化使user
參數可打印。ui
一樣,eosio.cdt
中的abi生成器不知道沒有屬性的hi()
action,在action上方添加C++ 11樣式屬性,這樣abi生成器能夠產生更可靠的輸出。google
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( "Hello, ", user); } }; EOSIO_DISPATCH( hello, (hi))
最後,添加EOSIO_DISPATCH
宏來處理調度hello
合約的操做。spa
EOSIO_DISPATCH( hello, (hi))
一切都在一塊兒,這是完成的hello world合約。
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( "Hello, ", user); } }; EOSIO_DISPATCH( hello, (hi))
eosio.cdt
中的ABI生成器支持幾種不一樣類型的屬性,請參閱
ABI使用指南。
你能夠將代碼編譯爲Web assembly(.wasm),以下所示:
eosio-cpp -o hello.wasm hello.cpp --abigen
部署合約時,會將其部署到一個賬戶,該賬戶將成爲合約的接口,如前所述,這些教程對全部賬戶使用相同的公鑰,以使事情更簡單。
cleos wallet keys
使用cleos create account
建立合約賬戶,使用下面提供的命令。
cleos create account eosio hello YOUR_PUBLIC_KEY -p eosio@active
使用cleos set contract
將已編譯的wasm
廣播到區塊鏈。
遇到錯誤?
你的錢包須要解鎖。
在以前的步驟中,你應該建立一個contracts
目錄並獲取絕對路徑,將下面命令中的「CONTRACTS_DIR」替換爲contracts
目錄的絕對路徑。
cleos set contract hello CONTRACTS_DIR/hello -p hello@active
很好!如今合約已經設定,向它推送一個操做。
cleos push action hello hi '["bob"]' -p bob@active
響應:
executed transaction: 4c10c1426c16b1656e802f3302677594731b380b18a44851d38e8b5275072857 244 bytes 1000 cycles # hello.code <= hello.code::hi {"user":"bob"} >> Hello, bob
如上所述,合約將容許任何賬戶向任何用戶打招呼。
cleos push action hello hi '["bob"]' -p alice@active
響應:
executed transaction: 28d92256c8ffd8b0255be324e4596b7c745f50f85722d0c4400471bc184b9a16 244 bytes 1000 cycles # hello.code <= hello.code::hi {"user":"bob"} >> Hello, bob
正如預期的那樣,控制檯輸出是「Hello,bob」。
在這種狀況下,「alice」是受權它的人,而user
只是一個參數,修改合約,以便受權用戶(在本例中爲「alice」)必須與合約響應「hi」的用戶相同,使用require_auth
方法,此方法將name
做爲參數,並將檢查執行操做的用戶是否與提供的參數匹配。
void hi( name user ) { require_auth( user ); print( "Hello, ", name{user} ); }
從新編譯合約:
eosio-cpp -o hello.wasm hello.cpp --abigen
而後更新它:
cleos set contract hello CONTRACTS_DIR/hello -p hello@active
嘗試再次執行操做,但此次受權不匹配。
cleos push action hello hi '["bob"]' -p alice@active
正如預期的那樣,require_auth
暫停了交易並引起了錯誤。
Error 3090004: Missing required authority Ensure that you have the related authority inside your transaction!; If you are currently using 'cleos push action' command, try to add the [relevant](**http://google.com**) authority using -p option.
經過咱們對合約的更改,驗證提供的name user
與受權用戶相同,再試一次,但這一次,十使用「alice」賬戶的權限。
cleos push action hello hi '["alice"]' -p alice@active
executed transaction: 235bd766c2097f4a698cfb948eb2e709532df8d18458b92c9c6aae74ed8e4518 244 bytes 1000 cycles # hello <= hello::hi {"user":"alice"} >> Hello, alice