EOS開發教程(2.1)

in #eos5 years ago

編寫第壹個智能合約
2.1 Hello World!
在之前創建的合約文件夾裏創建壹個新的文件夾,名字叫“hello”,或者通過妳系統的GUI或使用cli進入到這個文件夾。
cd CONTRACTS_DIR mkdir hello cd hello
創建壹個新文件,“hello.cpp”,然後用妳喜歡的編輯器打開它。
touch hello.cpp
在下面引入eosio.hpp頭文件。Eosio.hpp文件包含了編寫智能合約所需要的壹些類。

使用eosio命名空間能讓妳的代碼更整潔。比如,設置了using namespace eosio;後,eosio::print(“foo”)可以寫成print(“foo”)
using namespace eosio;
創建壹個標準的C++11類。合約類需要拓展eosio::contract類,這個類通過之前的eosio.hpp頭文件引入。

壹個空的合約並沒有什麽用。讓我們添加壹個public指示符和壹個using聲明。Using聲明能讓我們編寫更簡潔的代碼。
· C++

這個合約需要做點事情。讓我們寫壹個action,它接收壹個“name”參數,然後把這個參數打印出來。

上面的action接收壹個user參數,它是name類型的。EOSIO自帶很多類型定義,其中最常用的壹個類型定義就是name。使用 eosio::print來鏈接壹個字符串,並打印user參數。用括號把name括起來,這樣name才是可打印的。
不過,如果hi()action沒有屬性的話,eosio.cdt 中的ABI GLOSSARY:ABI 生成器就無法識別hi()action。在action前添加壹個C++11風格的屬性,這樣,abi生成器能打印更多可靠的輸出。

所有這些都寫好了後,就是完整的hello world合約了。

using namespace eosio; class [[eosio::contract]] hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( “Hello, “, user); } };
妳可以使用web assembly (.wasm)編譯妳的代碼。像下面這樣:
eosio-cpp hello.cpp -o hello.wasm
當合約被部署的時候,它是被部署到壹個帳號上的,那個帳號就變成了這個合約的接口。之前我們提過,在我們的教程中,所有的帳號我們都使用同壹個公鑰,簡化過程。
cleos wallet keys
使用 cleos create account為這個合約創建壹個帳號,
cleos create account eosio hello YOUR_PUBLIC_KEY -p eosio@active
使用cleos set contract命令,把編譯過的wasm部署到區塊鏈上。
cleos set contract hello CONTRACTS_DIR/hello -p hello@active
很好!現在合約已經部署好了,我們push壹個action給它。
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
我們看到,這個合約允許任何帳號向任何用戶說hi。
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作為參數,它會檢查執行action的user與提供的參數是否壹致。
void hi( name user ) { require_auth( user ); print( “Hello, “, name{user} ); }
重新編譯合約。
eosio-cpp -abigen -o hello.wasm hello.cpp
然後更新
cleos set contract hello CONTRACTS_DIR/hello -p hello@active
再次執行這個action,不過這次使用不壹致的授權帳號。
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 authority using -p option.
現在,我們做了修改,合約會驗證提供的name user與授權的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 #include <eosio/eosio.hpp> #include <eosio/eosio.hpp> using namespace eosio; class [[eosio::contract]] hello : public contract {}; #include <eosio/eosio.hpp> using namespace eosio; class [[eosio::contract]] hello : public contract { public: using contract::contract; }; #include <eosio/eosio.hpp> using namespace eosio; class [[eosio::contract]] hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( “Hello, “, user); } }; #include <eosio/eosio.hpp> using namespace eosio; class [[eosio::contract]] hello : public contract { public: using contract::contract; [[eosio::action]] void hi( name user ) { print( “Hello, “, user); } }; #include <eosio/eosio.hpp>