在先前建立的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