EOS开发(1.3-1.4)以上版本 智能合约DAPP全栈使用指南

前言

时间 2018-10-26
EOS 1.4.1 github链接
EOS-CDT 1.3.2 github链接
注:
1 本文针对 对EOS稍微有一点基础的以及从ETH转EOS开发的开发者,会在测试网络jungle中进行调试,从创建账号开始一直介绍到部署合约以及合约中转账和权限等问题,本文会同步更新。因为eos项目更新较为频繁,并且eos智能合约的c++语法库最近有变化,因此使用最新的版本来开始做示例。
2 任何疑问可以添加文末的微信以及知识星球,我们是专业的开发讨论组

一、使用工具和前序教程介绍 (部分基础步骤省略)

1 git clone EOS官方库 并按提示编译项目得到 $ cleos 等命令 (该命令用来做参与查询以及部署合约上链的操作)
2 强烈建议 参考官方的【getting start】 因为网上的教程基本都是搬运的这里。
3 git clone EOSCDT-合约工具库 编译项目得到$ eosio-cpp命令 用来编译合约成abi等文件。
4 如果已经有了eos旧版本的合约编写经验,可以参考 新旧版本区别
5 EOS前序教程及笔记

二、创建账号(创建jungle测试节点账号以及如何使用scatter插件)

A 创建一个eos账号

1 进入 JUNGLE测试节点官网地址 (jungle 类似以太坊中的kovan等测试节点)

image.png

2 用cleos 创建秘钥对 (公钥和私钥)

注:eos的账号一般是12个字符(a-z,1-5)组成,可以加小数点. 组成,每一个账号需要两个秘钥对来支持: 一个作为active,一个作为owner,可以理解为一个账号有两个子账号,权限不同而已,当然两个子账号可以使用同样的秘钥对,这样简单但是会有一点风险。每一笔交易都需要指定一个子账号作为发起者 一般用active权限的就够了。我们下面所有的操作都使用以下这一个秘钥对来做介绍。

$ cleos create key --to-console
Private key: 5K9fLKJ6K9ivadLASiXG8oS5qYsUdb2JP8ZNwK7phEi93hFLRTU
Public key: EOS5hSo21o6VXdZ4SM7UXv7u3uiVZ6oeVU7wxfWsxoQ5DFzVNAcRs

3 在jungle界面 选择 创建账号。


image.png

4 输入一个符合要求的账户名(注意 这个以后就是你的eos转账地址了,类似以太坊的钱包地址)
【本文以【abcdefg12345】为例】

5 输入公钥 publickey(两个输入框都填入public key! 私钥后面会用到 仅仅用来导入钱包!) 点击创建账号

6 如无意外 账号已经创建成功,可以点击 account info 查看是否创建成功

7 点击faucet 输入账号 能够获取测试用的100eos。

B 导入scatter

1 scatter下载

使用chrome浏览器,下载scatter插件。初次进入需要输入密码等操作,进入之后可以在设置中将语言调整为中文。


image.png

2 将jungle网络加入scatter

设置-> 网络 -> 新建
在需要填写的空白处填入以下内容 然后保存
域名: jungle.eosio.cr
端口: 443
chainid: 038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca


image.png

3 导入秘钥对

点击 -> 秘钥对 -> 新建
随意输入一个名称jungletest 以及私钥(输入私钥后 公钥会自动出来)

4 导入身份

点击 -> 身份 -> 新建
选择刚刚导入的 jungle 网络 和 秘钥对jungletest
点击导入 会等待几秒后 出现 两个账户名(xxx@active 和 xxx@owner)
选择一个账户之后 保存。
身份已经导入成功。

三、合约编编写 (C++语法以及合约基础架构不知道请事先了解或看前序教程笔记)

1 helloworld 示例
2 语法重点部分 (只介绍部分语法)。

(a). 新版的修改有很多 例如 account_name 类型 symbol类型的变化等等 可以看上面的新旧版本区别
(b). 程序入口 这是一个模板 ,类似路由 可以直接使用

extern "C"
{
    void apply(uint64_t receiver, uint64_t code, uint64_t action)
    {
        print(name{receiver}, name{code}, name{action});
        if (code == receiver)
        {
            switch (action)
            {
                EOSIO_DISPATCH_HELPER(examplecontractname, (func1)(func2))
            }
        }
        else if (code == "eosio.token"_n.value && action == "transfer"_n.value)
        {
            execute_action(name(receiver), name(code), &examplecontractname::transfer);
        }
    }
};

(c) Multi Index table 结构

struct [[eosio::table]] bet
    {
        uint64_t key;
        uint64_t level;
        name player;
        int result;
        uint64_t primary_key() const { return key; }
        uint64_t by_level() const { return level; }
        EOSLIB_SERIALIZE( bet, (key)(level)(player)(result) )
    };

typedef eosio::multi_index<name("bet"), bet, indexed_by<name("level"), const_mem_fun<cbet, uint64_t, &cbet::by_level>>> betting;
betting _bets;

(d) transfer方法rewrite (这一段是手写, 基本用法应该都在里面)

ACTION transfer(name from, name to, asset quantity, string memo)
    {
        require_auth(from);
        eosio_assert(quantity.is_valid(), "Invalid token transfer...");
        eosio_assert(quantity.symbol == EOS_SYMBOL, "only EOS token is allowed");
        eosio_assert(quantity.amount > 0, "must buy a positive amount");

        print("\n ontransfer from:", from, " to:", to, " quantity:", quantity, " memo:", memo);
        if (to != _self)
            return;

        // 查询 根据第二索引
        auto level_index = _currentbets.get_index<name("level")>();
        uint32_t findindex = quantity.amount;
        auto itr = level_index.find(findindex);
        if (itr != level_index.end())
        {
               // 保存
                _bets.emplace(get_self(), [&](auto &p) {
                    p.key = _bets.available_primary_key();
                    p.level = itr->level;
                    p.player = itr->player;
                    p.result = res;
                });

                // 修改
               level_index.modify(itr, get_self(), [&](auto &p) {
                    p.player1 = iname;
                    p.player2 = iname;
                    p.invest = 0;
          });
         
          // 转账 
          asset reward(amount, quantity.symbol);
          action(
                    permission_level{get_self(), "active"_n},
                    "eosio.token"_n,
                    "transfer"_n,
                    std::make_tuple(get_self(), to, reward, std::string("reward")))
                    .send();
        }
    };
3 当你写好你的逻辑之后 使用编译命令可以得到 abi文件 example.abi
$ eosio-cpp -I include -o example.wasm example.cpp --abigen

四 部署合约 及相关命令

1 先要 为账户购买RAM 以及cpu 和net (命令使用-u 来远程连接jungle节点)

#抵押EOS追加网络和CPU资源
$ cleos system delegatebw <本人账户名> <代币发行账户名>  '0.1 EOS'  '1 EOS'
$ cleos -u http://jungle.cryptolions.io:18888 system delegatebw abcdefg12345 abcdefg12345  '0.1 EOS'  '1 EOS'

#购买内存资源
$ cleos system buyram <本人账户名> <代币发行账户名>  '1 EOS'
$ cleos -u http://jungle.cryptolions.io:18888 system buyram abcdefg12345 abcdefg12345 '1 EOS'

2 部署合约

$ cleos -u http://jungle.cryptolions.io:18888 set contract example /work/dapp/eosproject/example -p abcdefg12345@active

3 发起转账action

注:dapp应用或游戏 很多靠转账的接口transfer 这个接口可以看成是合约固定的接口,可以把逻辑写在transfer接口中,当玩家转账给该合约账户,则会执行相应的游戏逻辑。

# bob是另一个测试账号,用bob这个玩家来对合约进行转账 2 eos (小数点需要写4位)
$ cleos -u http://jungle.cryptolions.io:18888 push action eosio.token transfer '[ "bob", "abcdefg12345", "2.0000 EOS", "备注" ]' -p bob@active;

4 当合约内部写了类似 从合约发送eos奖励给玩家 的逻辑时 需要赋予合约 转账的权限

cleos set account permission abcdefg12345 active '{"threshold": 1,"keys": [{"key":"EOS5hSo21o6VXdZ4SM7UXv7u3uiVZ6oeVU7wxfWsxoQ5DFzVNAcRs", "weight":1}],"accounts": [{"permission":{"actor":"abcdefg12345","permission":"eosio.code"},"weight":1}]}' owner -p abcdefg12345

5 查询账户余额

$ cleos -u http://jungle.cryptolions.io:18888 get currency balance eosio.token abcdefg12345 EOS

6 查询合约内部定义的struct table

$ cleos -u http://jungle.cryptolions.io:18888 get table abcdefg12345 abcdefg12345 table

未完待续... 下篇会讲到如何使用EOS.js 来调用合约

对了 欢迎加入我们分享开发经验

如果qr过期可以留言
知识星球【新】:


知识星球

微信2群:


微信2群
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348