EOS合约基础教程--开发智能合约`Hello World`
1 开发工具
使用eosio-cpp
工具来进行开发
$ brew tap eosio/eosio.cdt
$ brew install eosio.cdt
2 创建合约目录 hello
mkdir hello
cd hello
注意: 合约目录非常重要,因为 EOS 的合约部署是以目录来进行的。
3 创建一个合约文件 hello.cpp
touch hello.cpp
文件名无所谓,惯例是合约名 +
.cpp
4 Hello World 合约
vim hello.cpp
合约内容
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;
class hello : public contract {
public:
using contract::contract;
[[eosio::action]]
void hi() {
print("Hello World");
}
};
EOSIO_DISPATCH( hello, (hi))
5 合约详解
5.1 引入头文件
最重要的头文件是 <eosiolib/eosio.hpp>
,该头文件包含了大量的其它头文件。
#pragma once
#include <eosiolib/action.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/contract.hpp>
源代码在 https://github.com/EOSIO/eosio.cdt/blob/master/libraries/eosiolib/eosio.hpp
5.2 宏定义
#define CONTRACT class [[eosio::contract]]
#define ACTION [[eosio::action]] void
#define TABLE struct [[eosio::table]]
这三个宏定义分别用来修饰一个 **合约** 、**动作** 、**表**
5.3 命名空间
引入命名空间 eosio
。EOS 把所有的类和函数都放在 eosio
命名空间下。
#include <eosiolib/eosio.hpp>
using namespace eosio;
5.4 继承
EOS 中所有的合约都必须继承自一个基础合约 eosio::contract
。 该基础合约在 <eosiolib/contract.hpp>
头文件中定义
#include <eosiolib/eosio.hpp>
using namespace eosio;
class hello : public contract {};
5.5 动作 action
EOS 合约可以包含一些动作 ( action
) 和一些用于存储数据的表 table
,这些表都是一个结构体 struct
。 如果不用存储数据,那么表是可以忽略的。
EOS 合约中的动作都需要 [[eosio::action]]
属性来修饰。
#include <eosiolib/eosio.hpp>
using namespace eosio;
class hello : public contract {
public:
using contract::contract;
[[eosio::action]]
void hi( name user ) {}
};
5.6 输出
需要输出信息,比如一些字符串等,可以使用 eosio::print()
方法。
eosio::print()
方法在 <eosiolib/print.hpp>
头文件中定义
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;
class hello : public contract {
public:
using contract::contract;
[[eosio::action]]
void hi() {
print("Hello World");
}
};
5.7 定义动作
一个 EOS 合约中可以有多个动作 action ,当 EOS 接收到一个事务后,会将该事务分发给相应的合约,或者说,调用相应的合约的动作。
为了确保合约的哪个动作可以调用,需要使用 EOSIO_DISPATCH
宏来告诉 EOS。
EOSIO_DISPATCH
宏在 <eosiolib/dispatcher.hpp>
头文件中定义,该宏的第一个参数是合约的名字,第二个参数,是多个小括号 ()
扩起来的多个动作的方法名。
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;
class hello : public contract {
public:
using contract::contract;
[[eosio::action]]
void hi() {
print("Hello World");
}
};
EOSIO_DISPATCH( hello, (hi))
6 编译合约
使用 eosio-cpp
命令来编译合约
eosio-cpp -o hello.wasm hello.cpp --abigen
6.1 选项说明
选项 | 说明 |
---|---|
-o hello.wasm | 该选项用于指定合约编译后的输出文件。必须是以 .wasm 作为文件扩展名 |
hello.cpp | 合约源文件 |
--abigen | 该选项用户指定合约编译时同时生成 abi 文件 |
运行该命令输出结果如下
$ eosio-cpp -o hello.wasm hello.cpp --abigen
Warning, empty ricardian clause file
Warning, empty ricardian clause file
Warning, action <hi> does not have a ricardian contract
编译完成后,当前 hello
目录就会多出两个文件
$ ls
hello.abi hello.cpp hello.wasm
7 部署合约
部署合约的前提就是需要存在一个账户。在前面的章节中,我们创建了一个 hello
账户,接下来我们就使用在这个账户上部署合约
部署合约需要使用到 cleos set contract
命令。
cleos set contract hello ../hello -p hello@active
7.1 选项说明
选项 | 说明 |
---|---|
cleos set contract | 部署合约的命令 |
hello | 部署合约的账户,必须已经存在 |
../hello | 合约所在的目录名,该目录下必须包含和目录相同的 .wasm 和 .abi 文件 |
-p hello@active | 该选项用于指定权限,该权限必须包含 hello 账户的 active 权限 |
该命令的运行结果如下
Reading WASM from ../hello/hello.wasm...
Skipping set abi because the new abi is the same as the existing abi
Publishing contract...
executed transaction: e3863e68840c354c67b4955e14bed8792fb37f7b7166e1df4b5a30e0a7f714f2 1344 bytes 518 us
# eosio <= eosio::setcode {"account":"hello","vmtype":0,"vmversion":0,"code":"0061736d0100000001300960017f006000017f60027f7f01...
8 运行合约下的动作
只能说是 hello
账户下部署了一个合约,该合约下有一个动作 hi
。
如果我们要执行这个账户下的合约的 hi
动作,需要使用到 cleos push action
命令。该命令的语法如下
cleos push action hello hi '[]' -p hello@active
8.1 参数说明
选项 | 说明 |
---|---|
cleos push action | 执行合约动作的命令 |
hello | 合约所在的账户名 |
hi | 要执行的合约的动作,必须是已经导出的,也就是 EOSIO_DISPATCH( hello, (hi)) 中定义的 |
-p hello@active | 用于执行合约的权限,可以是任意权限,只要该合约运行 |
运行上面的命令,输出结果如下
executed transaction: 843a65cd56420c6f749a10cf221fdf36716067cd1718c8348c38a304ba752ab0 96 bytes 270 us
# hello <= hello::hi ""
>> Hello World
看到最后的那个 >> Hello World
吗? 这个就是 print("Hello World");
的输出结果
- 本文作者:Jack Yao
- 本文链接: eos_contract_basic_hello
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!