在前两篇,我们已经成功的部署EOS的测试环境,并创建智能合约,成功转移资金
今天我们做一个智能合约的编写:
首先环境的准备:先配置一个环境变量。将下面的代码加入/etc/profile 中,每个人的路径不一样,大家注意就行,具体路径如下图所示;
#set EOS environment
export EOS_HOME=/home/devSoft/eos/build/install
export PATH=$EOS_HOME/bin:$PATH
Hello World
我是在/home路径下,创建了一个hello_contract的目录,进入该目录后执行下述命令,会得到一个hello的目录,进入该目录后可以看到三个文件:
命令:eoscpp -n hello
上面生成的文件就算是一个模板了,下面看看hello.cpp里面的内容
这里面定义了两个方法:init()和apply(uint64_t code, uint64 action)。根据文档的介绍我们可以知道,EOS对合约的处理是基于消息和状态机的,那这两个方法就不难理解了,init()就是做初始化用的,而apply是处理所有消息的入口。理论上这里可以实现任何业务逻辑。
将上面的合约部署到区块链上:
eoscpp -o hello.wast hello.cpp
编译出来的文件后缀为wast是wasm的文本形式
上传合约到区块链中
eosc set contract inita hello.wast hello.abi
返回:
执行完成后你会得到以上的返回,同时如果观察eosd的窗口,你会得到下面的输出:
主要,这里你会发行init方法被执行了3遍,根据文档,我们可以发现EOS在deploy一个智能合约时会执行三遍,都发生了什么呢:
1、eosd 收到了一个新的交易
-创建一个临时的session
-尝试应用该交易
-成功执行并打印“Init World!”
-或者失败撤销所有改动
2、eosd开始生产一个区块
-撤销所有未决状态
-将所有的交易放到这个构建的块内
-第二次打印“Init World!”
-结束创建块
-撤销所有在创建区块期间做的临时变更
3、eosd像从网络接收到块一样将产生的块放到链上
-第三次打印“Init World!”
我们向合约发送一个消息:
$ eosc push message inita hello '"hahahahahaha"' --scope inita
返回:
eosd窗口会打出如下图所示的消息
ABI - 应用二进制接口
我们产生的一个文件叫hello.abi,它内部定义了交易类型transfer,而且最终eos会提供工具来根据cpp代码来产生abi。下图显示的是hello.abi的内容:
根据该transfer交易类型,我们可以发送以下消息:
eosc push message inita transfer '{"from":"currency","to":"inita","amount":50}' --scope initc
eosd窗口会显示如下图所示的提示:
修改hello.cpp代码如下:
#include
extern"C"{
voidinit() {
eos::print("Init World!\n");
}
structtransfer {
uint64_tfrom;
uint64_tto;
uint64_tamount;
};
voidapply(uint64_tcode,uint64_taction ) {
eos::print("Hello World: ",eos::Name(code),"->",eos::Name(action),"\n");
if( action ==N(transfer) ) {
transfer message;
static_assert(sizeof(message) == 3*sizeof(uint64_t),"unexpected padding");
autoread =readMessage( &message,sizeof(message) );
assert( read ==sizeof(message),"message too short");
eos::print("Transfer ", message.amount," from ",eos::Name(message.from)," to ",eos::Name(message.to),"\n");
}
}
}// extern "C"
重新进行编译部署再次发送transfer消息,
命令:eoscpp -o hello.wast hello.cpp
命令:eosc set contract inita hello.wast hello.abi
发送交易消息:
命令:eosc push message inita transfer '{"from":"currency","to":"inita","amount":50}' --scope initc
如下图
eosd窗口打印出如下图的消息
本章节就到此结束,后期尽情期待:共同学习请加,微信:jmyang20
网友评论