Hello World!
在先前创建的contracts
目录中创建一个名为“hello”的新目录,或者通过系统GUI或cli创建一个名为“hello”的目录并进入目录。
cd CONTRACTS_DIR
mkdir hello
cd hello
创建一个新文件“hello.cpp”并在你喜欢的编辑器中打开它。
touch hello.cpp
将所需的库包含在文件中。
#include
#include
为了使合约中的内容更简洁,请使用命名空间eosio
。
using namespace eosio;
-
eosiolib/eosio.hpp
将EOSIO C和C++ API加载到合约范围内,这是你的新战争。
创建一个标准的C++ 11类,合约类需要继承eosio::contract
。
#include
#include
using namespace eosio;
class hello : public contract {};
空合约没有多大好处,添加public
访问修饰符和using
声明,using
声明将允许我们编写更简洁的代码。
#include
#include
using namespace eosio;
class hello : public contract {
public:
using contract::contract;
};
这份合约需要做点什么,本着hello world的精神编写一个接受“name”参数的action,然后输出该参数。
#include
#include
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
参数可打印。
同样,eosio.cdt
中的abi生成器不知道没有属性的hi()
action,在action上方添加C++ 11样式属性,这样abi生成器可以产生更可靠的输出。
#include
#include
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
合约的操作。
EOSIO_DISPATCH( hello, (hi))
一切都在一起,这是完成的hello world合约。
#include
#include
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