1)在(一)的安装成功之后,用eosiocpp编译新写的contract 总还是出现找不到头文件的现象,先要查一下自己的path 和 libarry 的设定:
>echo $PATH /usr/local/eosio/bin:/Users/username/Library/Python/3.6/bin/:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
>echo $LD_LIBRARY_PATH
/usr/local/eosio/lib:/Users/username/gitspace/engo/eos/contracts
要注意EOS代码下载之后,里面包含了tool那个目录,里面也有eosiocpp ,设定path的时候要注意,搞不清楚就用which eosiocpp 确认一下。
- 试开发一个小的dApp: Player
File 参考github:
Player 是一个基于EOS的一个小游戏,Player玩家拥有:玩家名,初始level, health_points, energy_points,每次transaction 模拟一次游戏,消耗health_points 和 energy_points 一些
Players.hpp:
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <string>
Player.cpp:
···
namespace Oasis{
using namespace eosio;
using std::string;
class Players : public contract{
using contract::contract;
public:
Players(account_name self):contract(self){}
//@abi action
void add(account_name account, string& username){
require_auth(account);
playerIndex players(_self, _self);
auto iterator = players.find(account);
eosio_assert(iterator==players.end(), "Address for account already exist ");
players.emplace(account, [&](auto& player){
player.account_name = account;
player.username = username;
player.level = 1;
player.health_points = 1000;
player.energy_points = 1000;
});
}
void update(account_name account, uint64_t level, int64_t health_points, int64_t energy_points){
require_auth(account);
playerIndex players(_self,_self);
auto iterator = players.find(account);
eosio_assert(iterator != players.end(),"Address for account not found.");
players.modify(iterator,account,[&](auto& player){
player.level = level;
if((player.health_points - health_points) < 0){
player.health_points = 0;
}else{
player.health_points -= health_points;
}
if((player.energy_points - energy_points) < 0){
player.energy_points = 0;
}else{
player.energy_points -= energy_points;
}
});
}
void getplayer(const account_name account) {
/* code */
playerIndex players(_self,_self);
auto iterator = players.find(account);
eosio_assert(iterator != players.end(),"Address for account not found.");
auto currentPlayer = players.get(account);
print("Username:", currentPlayer.username.c_str()," Level:", currentPlayer.level," HealthPoints:",currentPlayer.health_points," EnergyPoints:",currentPlayer.energy_points);
}
private:
struct player{
uint64_t account_name;
string username;
uint64_t level;
int64_t health_points = 1000;
int64_t energy_points = 1000;
uint64_t primary_key() const {return account_name;}
EOSLIB_SERIALIZE(player,(account_name)(username)(level)(health_points)(energy_points))
};
typedef multi_index<N(player), player> playerIndex;
};
EOSIO_ABI(Players,(add)(update)(getplayer))
}
···
以上的代码中:EOSLIB_SERIALIZE 和 EOSIO_ABI 是EOS的宏,
EOSLIB_SERIALIZE用序列法在合约和节点系统中来回传递(这里比较模糊,需要进一步弄清楚)。
EOSIO_ABI 用于调用合约,通过手柄监听action(add,update 等) 进行相应处理。
3)接下去是生成.wast 和.abi 文件
eosiocpp -o Players.wast Players.cpp
eosiocpp -g Players.abi Players.cpp

4)这步成功之后可以deploy 合约了,但在这之前要确保节点已经开始运行,如果没有开,要去开一下。(参考一)
然后是要保证钱包是Unlock的,一般钱包会自动关掉,需要手动打开一下(参考一)
cleos wallet unlock -n oasis --password PW5JzoNwNrnYdPt4cHB647gSGzr8AhqYURGbzAuczxHtP7qoZ754Q
然后:
-创建账户
cleos create account eosio anorak EOS5H5vjaW3Nv7v1qkKRgjuHrXyCaPjkFVVzQxaRjnekWwjjqprMW
-部署合约
cleos set contract anorak . Players.wast Players.abi
测试合约:add, update, getplayer (查询用户)等等
整个过程可以参考下图:

*1)我曾经愚蠢地试图想要把eosiocpp 这个编译工具集成到xcode, 发现根本不行,搞了一个礼拜(当然是零碎时间),放弃了,估计是太蠢的缘故,最后找到infinitex 的文章,才发现合成在VS 和CLion中有一些介绍。总之蛮麻烦的。(等有空了再试试)
目前我是用mac 下的Atom 编辑,然后在iterm里面直接编译生成abi,但总是感觉不爽。。。
*2)Cleos 的一些命令可以到这里查:https://eosfans.io/wiki/cleos-command-reference
3) 如果一开始搞不清楚,可以使用eos 的目录框架,.cpp, *.hpp 放到eos项目框架下的contracts 目录里面。(环境变量设置对的话不需要非要放到EOS的目录,但是未来可以借鉴其目录结构)
在EOS里面有写好的CMAKE 文件,目前的水平只能去重用一下,等研究透了再自己写。
总结:
这个测试用的DApp 主要可以体验一下合约如何与账户互动,未来如果要对账户做权限改动设置等还有很多事情要做要研究。另外对于EOS写好的CMAKE, BOOST也应该好好研究一下,才能彻底定制自己的链。
昨天看到有人发文说开发DAPP还是开发公链,DAPP好像就是在别人的菜园子里面种菜,不爽啊,最好自己买个院子然后自己想种什么种什么。