hello shaokun

code is law


  • 首页

  • 归档

eos dapp开发学习 第二课 续

发表于 2018-10-21

前言

到此我这里发现了多个问题,这里列出来,希望帮到遇到同样问题的同学

  1. 目前eoscdt git已经更新到1.4版本了,其中的结构,语法更改了很多,我这边mac系统是10.12.6,弄了一周还是没办法升级到13,而新的cdt最低需求已经要13了,忧伤。。。
    而我从源码编译,总是clone不下来,试过各种方法均失败了。这里提醒一下,最好按照他的系统要求去安装,已经有打包好的二进制文件了
  2. 目前的官网的版本使用的eoscdt1.2,而经过上面的方式失败了,我再次尝试了这个,成功了
  3. 这里如果按照昨天的cpp文件使用eosio-cpp进行编译,是没有问题的。但是无法部署合约,这里需要将table name 由user_info 改为 userinfo 注意 不能改成userInfo,UserInfo等等,即所有的需要写入abi的action和table name必须 仅能包含
    .12345abcdefghijklmnopqrstuvwxyz
    这些字符
  4. 莫名的感觉忧伤而兴奋,忧伤是跟不上新版本的步伐,兴奋的是开发越来越规范,现在可以接着上一篇文章继续写作了
  5. 带着梯子办事,总会减少很多很多没有必要的问题

编译、部署合约

不同的版本有着不同的变化,这里仅以eoscdt1.2进行操作,如果后续使用eoscdt1.3或者使用之前的eosiocpp来编译出来的abi和wasm文件肯定是用不了的

  • 更改cardgame.hpp
    contract

    ///@abi action  => [[eosio::action]]
    ///@abi table => [[eosio::table]]
    user_info => userinfo
    
  • 再次生成abi和wasm文件,这里要切换到c++文件所在的目录

    eosio-cpp -o cardgame.wasm cardgame.cpp --abigen
    
  • 部署合约,这里在任何目录执行都可以,合约的目录输入绝对路径

    cleos -u http://jungle.cryptolions.io:18888 set contract shaokun11113 /Users/shaokun/Desktop/eoslearning/cardgame -p shaokun11113@active
    
  • 当部署遇到图中红色的提示时,请注意table,action,class,struct的名字所含字符
    contract
    由之前的结论可以看到,我们合约成功部署了

与前端共同交互合约

  • 这里使用了最新的eosjs,请更新 eosjs

    npm install eosjs@beta    
    
  • 更新后package.json ,请注意eosjs的版本

    {
      "dependencies": {
        "eosjs": "^20.0.0-beta2",
        "react": "^16.5.2",
        "react-dom": "^16.5.2",
        "react-redux": "^5.0.7",
        "react-scripts": "2.0.5",
        "redux": "^4.0.1",
        "redux-logger": "^3.0.6"
      },
    }
    
  • 新版的eosjs的引入有更改,请仔细对比

  • 由于此处的合约只要是合法的注册到jungle上的account 都可以登录,所以前端框的private key的输入框可以随意输入,这里请注意风险
  • 登录成功后,跳转界面!!!本篇文章的代码lesson2 code
    contract

文章允许转载,但请注明出处,谢谢

结尾

总算完成了之前的坑。^o^
中间有很多前端的知识,这不是这个课程讲解的重点,只能靠各位同学自己去补习了。这个系列使用react,redux也是一个很庞大的工程,所以可以简单一点,展示一下交互就好。
应该说到此,区块链与前端的交互已经完成,接下来就是充实智能合约的功能了。如果你做到了这一步,建议去eos c++ api这里了解一下api,这样对于后面的合约编写会有一个更深层次的掌握

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步

eos dapp开发学习 第二课

发表于 2018-10-20
学习目标

我们将学习如何在智能合约中存储玩家信息;使用登录操作。然后我们将开始构建Web前端,添加Login页面。 要使登录页面与智能合约交互,我们将使用eosjs连接到EOSIO区块链。我们使用eosjs库来调用智能合约中的登录操作。接下来,我们将React连接到Redux以存储应用程序状态。最后,我们将所有这些结合起来并添加一个游戏页面,以便我们有一个工作登录屏幕。 在本课程结束时,玩家应该能够登录游戏并进入游戏中的第一个屏幕。

step 1 定义表结构

对于元素战斗,我们需要存储每个玩家的游戏进度的详细信息或状态。为此,我们将使用多索引表,这是EOSIO的一个功能。您可以将多索引表视为内存数据库。要使用多索引表,我们需要告诉EOSIO我们要在其中存储哪些数据。 对于游戏,我们需要存储玩家信息,所以让我们在之前创建的cardgame.hpp中创建一个名为user_info的结构。我们要存储:

  • the player’s name
  • win count (default to 0)
  • lost count (default to 0)

  • cardgame.hpp(这里传图片得了,看得仔细一点)
    lessons

step 2 写入数据到多索引表_user中

现在我们可以使用我们的多索引表了。所以让我们存储我们的合同状态。为此,我们将创建第一个操作,即登录操作。

lessons

step 3 前端页面组件布局

这里还是使用Jungle test net来做,account shaokun11113。
我这里出现了一个问题,就是之前我把eos升级了,但是我的电脑没有升级升级到eoscdt。导致现在能够生成abi和wasm文件,但是部署不到链上去,出现的是如下错误,哪位同学知道可以告诉我,感谢。
lessons

这里卡住我太久了,那部署合约这一步就先跳过,这一篇文章我们先根据官方的步骤先把前端页面展示出来吧!
lessons
主要是精简了官方的图片和ui,这一部分先把功能实现,有心思的同学如果觉得我的这个丑就按照官方的来吧,这里用到了几个react的库,建议你们先了解一下

 "eosjs": "^16.0.9",   
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-redux": "^5.0.7",
"react-scripts": "2.0.5",
"redux": "^4.0.1",
"redux-logger": "^3.0.6"

step 4 页面交互

由于合约没有部署上,所以没有办法上链进行演示,故此处仅仅是将整个前端的ui交互成功,如果你看过我之前的两篇文章,那么到这里你应该可以理解的。
lessons

结尾

这篇文章写的很不顺,没有完成最关键的上链一步给大家演示,真是抱歉了。那么只能够走思路了。附上本篇文章所用到的源码 elementel battels dev2

文章允许转载,但请注明出处,谢谢

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步

eos dapp开发学习 第一课

发表于 2018-10-20
前言

没想到block one就在10/19放出了一个官方的教程,教程内容很详细,比我上周的详细很多呢,包括语法,逻辑,代码的封装。那么接下来当然也要跟着一步一步的来学一下。
elemental battles 我这边貌似不用梯子也能进入的哈。

这里请注意一点,之前的两篇文章使用的是是使用的当前官网的步骤,使用的eosio.cdt1.2进行wasm和abi的,而现在github是最新的1.3版本,语法变化很多,更加规范。
而目前的这个教程使用的最开始的方法,所以为了一致,也会使用最古老的方式进行学习,保持统一。综合来看,整体开发dapp的流程和思想是一致的,新版本的只是语法有变化。
即整篇采用eos1.2的这个文档 eosio1.2
elemental battles cover
elemental battles cover
为了我自己不糊涂,再啰嗦一遍。建议生产中使用新版本

  • eosio1.2包含了生成.wasm和abi的工具eosiocpp
  • eoscdt1.2是单独的一个插件,更加专业,专门用于生成上述两个文件,使用eosio-cpp
  • eoscdt1.3是1.2的升级版,规范了语法优化了很多
准备阶段

目录

需要自己注册一个账号哈

可以看到,总共九个大的章节,第0章节介绍了eosio,然后指导安装eosio。这个安装和之前的步骤一样,在此就不啰嗦了。

step 1

  1. 新建三个c++文件,注意命名规则

    cardgame.hpp  // 定义智能合约的C ++头文件
    cardgame.cpp  // 用于实现智能合约的操作的C++源文件。
    gameplay.cpp  // 包含智能合约中使用的内部帮助函数的C++源文件。
    

文件结构1

  • 账户名只能包含字符.abcdefghijklmnopqrstuvwxyz12345。 a-z(小写),1-5和. (英文句点),必须以字母开头必须为12个字符
  • 表名,结构,函数,类最多只能包含12个字母字符
  • 符号必须是A和Z之间的大写字母字符必须是7个字符或更少

step 2

使用create-react-app 创建web项目,并移除其中不需要的文件
文件结构2

结尾

额,第0课和第一课就到这里结束了,可以看到和我们之前的流程是类似的。同样需要你掌握web和c++的知识,这些知识点都可以通过网络找到,需要自己积累。
第0课主要讲解了eosio开发环境的搭建,自备梯子很重要
第1课主要讲解的整个项目的结构

文章允许转载,但请注明出处,谢谢

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

结合scatter学习eos dapp开发,看这篇就够了(下)

发表于 2018-10-14

eos智能合约开发 c++合约编写

这里需要说明的一下,这个例子和官网提供的hello没有多大的区别,仅仅是带你多了解一下如何编写。其中遇到有些概念难以理解,建议还是参考官网的hello 从头看起

#include <eosiolib/eosio.hpp>  
#include <eosiolib/print.hpp>
#include<string>

using namespace eosio;
using std::string;

class todolist : public contract {  //继承 contract

  public:
  using contract::contract;           

  todolist(account_name self):contract(self){}   //构造函数
    // account_name 是eoslib中定义的一种类型

  [[eosio::action]]   // 以前的版本使用的 ///abi action ,eoscdt使用这种方式标识,更加的优雅,也就是你要对外开放的方法都加上才会生成在abi中
  void create(account_name author, const uint32_t id, const std::string &description)
  {
  // 记住,这些action方法的返回值只能是void,不然会报错,只有实际做过的人才会知道 ,那你要问我如何读取区块链的内容呢? 这个问题也困扰了我蛮久,继续看下面
    todo_index todos(_self, _self);
    // 实例化多索引列表,第一个参数是这张表是谁的 code ,即谁有权限去读写它
    // 第二个参数scope,相当于缩小范围去找到这张表
    // _self 是构造函数中的self
    // todo_index 是Multi_index的一个具体的类型,在下面定义的

    todos.emplace(author, [&](auto &new_todo) {
        new_todo.id = id;
        new_todo.description = description;
        new_todo.completed = 0;
    });
    // 使用todos这个表的实例,去添加一条todo
    // 第一个参数表示为这条内容的写入付费的account,第二个参数是一个lambda方法,拿到的参数是这个表中的一行的实例,然后赋值对应的数据即可

    print("todo#", id, " created");
    // 这里,如果你使用命令行方式 执行,执行成功后会打印这个方法,但是如果是dapp开发,这是看不到的,又有一个疑问,那我们怎么知道执行成功了呢?
  }

  [[eosio::action]]
  void complete(account_name author,const uint32_t id)
  {  
  // 更改todo的状态为完成
  todo_index todos(_self, _self);

      auto todo_look = todos.find(id);
      // 是否用find()方法,去查找这条方法对应的实例
      eosio_assert(todo_look != todos.end(), "todo does not exit");
    // 这里 如果找不到,todos.end() 会返回 null
      todos.modify(todo_look,author,[&](auto &t) {
          t.completed = 1;
      });

      print("todo #" ,id ,"marked as complted");
  }

  [[eosio::action]]
  void destroy(account_name author, const uint32_t id)
  {    
        require_auth(author);
        // 权限验证,只能够删除自己的todo

        todo_index todos(_self, author);
      auto todo_look = todos.find(id);
      todos.erase(todo_look);
      print("todo#", id, " destroyed");
  }
  private:
    // 在eoscdt中 注意加上[[eosio::table]] ,否则abi中不会生成这个table
  struct [[eosio::table]] todo {
      uint64_t id;
      string description;
      uint64_t completed;

      uint64_t primary_key() const {
      // 这个方法是必须存在的,上面方法能够查找就是因为这个方法的存在,  
      // 所以说查找只用传入 id即可,  
      // 如果要使用其他的查找方式,得多定义几个查找的方法,最多可以定义16个  
      // 如何定义看官网,这里不演示了  
          return id;
      }

      EOSLIB_SERIALIZE(todo,(id)(description)(completed));
  };

  typedef eosio::multi_index<N(todo),todo> todo_index;
  // 这里定义了多索引列表的具体实现,N(todo)是将你的account 转换为 uint64_t 类型,第二个参数传入表名字, 定义的具体的类型是todo_index

};

EOSIO_ABI(todolist, (create)(complete)(destroy))

eos智能合约开发 编译智能合约

经过以上的步骤,我们编写好了智能合约,这个合约是一个todolist,可以增加todo,可以将todo变为完成的状态,还可以删除todo,只能删除自己的todo

这里编译智能合约,需要下载好eoscdt,如果没有下载好,建议完整安装好eoscdt再继续往下走了

  1. contract
    新建一个todolist文件夹,将上面写好的todolist.cpp放进去
  2. contract
    打开终端,进入文件夹,输入

    eosio-cpp -o todolist.wasm todolist.cpp --abigen
    
  1. contract
    成功后会在当前文件夹目录下生成 todolist.wasm 和 todolist.abi

eos智能合约开发 部署智能合约

这里部署智能合约我暂时只找到使用 命令行的方式部署,如果哪位同学知道其他的方式部署,请告诉我,谢谢

合约的部署又得创建钱包导入账户,和我们在scatter的方式一样,只不过这次是在命令行上操作了,那接下来继续走

  • contract

    //显示当前的钱包,如果是按照教程来,应该如图显示
    cleos wallet list 
    
  • contract

    // 创建钱包,记住将返回的钱包密匙保存起来
    cleos wallet create —-to-console 
    // 显示钱包
    cleos wallet list 
    
  • contract

    // 导入我们之前的导入scatter的密匙对的私钥
    // 执行后粘贴 私钥就好
    cleos wallet import
    
  • contract

    // 导入我们之前的导入scatter的密匙对的私钥
    // 执行后粘贴 私钥就好
    cleos wallet import
    
  • contract

    // 部署合约 eee,注意看提示内容,RAM不够了,怎么办?去买
    // 参数解释
    // -u 指定部署合约的网络
    // set contract  部署合约的命令
    // shaokun11113  部署到哪个账户上,注意 这里这个账户的私钥必须被导入钱包且已在 -u指定网络上进行注册
    // /Users/shaokun/Documents/todolist  abi 和 wasm的 绝对路径 ,建议不要使用相对路径
    //-p 指定权限
    cleos -u http://jungle.cryptolions.io:18888 set contract shaokun11113 /Users/shaokun/Documents/todolist -p shaokun11113@active
    
  • contract

    // 购买RAM
    // -u 去哪里买
    // system buyram  购买ram的命令
    // shaokun11113  谁去买,谁付钱
    // shaokun11113  谁受益 买来的ram 给谁
    // -k 买多少 kbytes 
    cleos -u http://jungle.cryptolions.io:18888 system buyram shaokun11113 shaokun11113 -k 1024
    
  • contract
    有时候你也许会遇到这种情况 ,那就需要之前创建钱包时的密匙进行解锁钱包

  • contract

    // 解锁默认钱包,输入钱包秘钥就好, 可以使用-n 指定解锁的钱包名字
    cleos unlock wallet
    
  • contract

    // 再次部署合约,可以看到结果eosio::setcode eosio::sebabi说明部署成功
    cleos -u http://jungle.cryptolions.io:18888 set contract shaokun11113 /Users/shaokun/Documents/todolist -p shaokun11113@active
    

eos智能合约开发 使用scatter.js进行交互

这里使用 create-react-app 脚手架创建项目,删除无用的文件,启动项目。这里有疑问的请百度

  • contract contract

创建react项目,打开项目,删除无用的文件

  • contract

启动项目,保证项目的正确性

  • contract

    // 安装scatter sdk
    // 这里使用的是eosjs1,尝试了多种方式,未找到eosjs2的使用方式,如有知道的同学,还请告知
    npm i -S scatterjs-core  scatterjs-plugin-eosjs
    
  • contract

改造项目的布局

render() {
    return (
        <div>

            <div>
                <button onClick={() => this.createTodo()}>create todo</button>
                <button onClick={() => this.deleteTodo()}>delete todo</button>
                <input type="text" onChange={e => {
                    this.setState({
                        deleteId: Number.parseInt(e.target.value)
                    })
                }}/>

                <button onClick={() => this.completeTodo()}>complete todo</button>
                <input type="text" onChange={e => {
                    this.setState({
                        competedId: Number.parseInt(e.target.value)
                    })
                }}/>
                <button onClick={() => this.showTodo()}>show todo</button>
            </div>
            <div>
                <p>below is data</p>
                <ul>
                    {
                        this.state.rows.map((todo, index) => {
                            return <li key={index}>
                                <p>id : {todo.id}</p>
                                <p>description : {todo.description}</p>
                                <p>completed : {todo.completed}</p>
                            </li>
                        })
                    }
                </ul>
            </div>
        </div>
    );
}
  • 引入scatter sdk

    import React, {Component} from 'react';
    import ScatterJS from 'scatterjs-core';
    import ScatterEOS from 'scatterjs-plugin-eosjs';
    import Eos from 'eosjs';
    
    ScatterJS.plugins(new ScatterEOS());
    
    const network = {
    blockchain: 'eos',
    protocol: 'http',
    host: 'jungle.cryptolions.io',
    port: 18888,
    chainId:         '038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca'
    }
    
  • 初始化
componentDidMount() {
    setTimeout(() => {
        this.init()
    }, 2000)
}

init() {
ScatterJS.scatter.connect('eos').then(connected => {
    if (!connected) return false;
    const scatter = ScatterJS.scatter;

    this.setState({
        scatter
    });
    alert("scatter load success")
});
}    
  • contract

    增加 曾 删 改 查的功能

    createTodo() {
    this.state.scatter.getIdentity(requiredFields).then(() => {
        const account = this.state.scatter.identity.accounts.find(x => x.blockchain === 'eos');
        const eos = this.state.scatter.eos(network, Eos);
        const transactionPermission = {authorization: [`${account.name}@${account.authority}`]};
        const num = Math.floor(Math.random() * 100000);
        eos.contract(account.name).then(ins => {
            ins.create(account.name, num, "this is " + num, transactionPermission).then(res => {
                console.log(res)
            })
        })
    
    }).catch(error => {
        console.error(error);
    });
    }
    
  • contract

启动项目,看看演示效果。可以看见与eos网络的交互还是很流畅,速度也很快。到此,基于eos网络开发dapp的流程应该算结束了,谢谢你的阅读。

eos智能合约开发 总结

本打算下周更新此篇文章,恰好今天原来的计划取消了,那就不拖了,下周有下周的事情呢
这里有几点需要大家注意:

  • 一定要有梯子,不然根本无从谈起
  • eos要求硬件比较高,这个需要自己准备了
  • 一定要先理解eos中的相关概念,和以太坊还是有很大的区别的
  • 一定要先跟着官网的hello走一遍
  • 如果哪一步遇到问题了,可以反复翻看这两篇文章,你一定能够成功的

eos智能合约开发 源码

2018-11-15 22:18:58更新
[源码送上…]
(https://shaokun11.github.io/2018/11/15/%E5%9F%BA%E4%BA%8Eeos%E8%BF%9E%E6%8E%A5scatter%E5%BC%80%E5%8F%91dapp(%E4%B8%8B)%20%E7%BB%AD)

接下来的计划

  • 继续分享智能合约的知识,主要是基于eos,tron,eth三个平台,希望能够帮助到大家
  • 分享一些编程语言知识,eth 和 tron 是用solidity写合约,eos是用c++写,前端展示页面是用react写的

文章允许转载,但请注明出处,谢谢

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

结合scatter学习eos dapp开发,看这篇就够了(上)--补充

发表于 2018-10-13

eos智能合约开发 在jungle上创建account 续

之前由于网络的原因,导致中断了,那我们继续接着来。自带梯子最重要

jungle
打开网站,输入之前的信息如图所示,点击左下角create
jungle
创建成功后,会返回这样的信息,看见最下面有绿色的应该就是成功了吧
接下来我们查看一下我们创建的account的信息,回到主页,选择account info,输入刚才创建的account ,我这里输入shaokun11113 ,点击 get
jungle
jungle
可以看到返回了我们创建账号的信息:

  • balance 什么都没有
  • activity key 和 owner key为我们刚才创建账户的时候输入的key
  • RAM 目前账号的RAM情况,这里可以看到刚创建账号就已经消耗了一部分的RAM,为什么呢? 因为你的账号信息要占用内存啊,所以说,创建账号得找到一个有eos的账号的用户帮你创建,他要为你支付这部分费用
  • net Bandwidth 存了100个eos,目前没有使用
  • cpu Bandwidth 存了100个eos,目前没有使用

由于作为dapp开发者,那么我们得准备点eos,那么接下来我们再去获取一点eos吧
回到主页,选择 faucet,输入 你的账号,如图所示,通过验证,选择send coins 就好
jungle
返回的结果如上所示,有兴趣的同学可以仔细看看这些内容。
那么我们如何知道我们是否收到了eos呢?
还是回到主页,进入 account info查询就好

jungle

这里注意一下 balance 那一项就好,可以看到已经有100个eos和100个jungle token了

eos智能合约开发 导入Account到scatter中

经过上一步骤,我们已经创建好了账户,接下来就讲账户导入到scatter中吧。在scatter中,这里叫做identity(身份)

jungle
进入scatter,选择身份。点击左下角的编辑的icon
如果你关闭过浏览器,请输入最开始的密码进入就好,如果忘记了,请输入助记词找回,如果丢了,就从头来一遍就好.
jungle
这里我们注意一下 账户选项中的内容就好
jungle
这里都是选择题,账户的第一项勾选我们创建网络时输入的名字,第二项勾选我们生成密匙对的名字就好,点击导入
jungle
如果你看到了这个结果,不好意思,我也不知道你哪一步有问题。你可以从头开始再来一遍就好
jungle
当然,我希望的是你看到的这个界面,通常我们选择active账号,然后点击右上角保存按钮
jungle
回到这个界面,可以看到我们刚才创建的账户已经导入成功了,这里多一步的设置,把此账户设置为scatter的默认账户,这样以后调用scatter的时候就会默认选择此账户进行智能合约的调用了 勾选左下角的那个小圆圈的icon
jungle
我们就可以看到我们账户的信息啦

文章允许转载,但请注明出处,谢谢

这样一点点的敲下来,内容还是蛮多的。本打算一次写完,结果遇到网络的问题,暂停了一会,这篇文章算是对第一篇的补充吧。到目前为止,我们只是创建好了账户,还没有涉及到dapp的开发,接下来的具体怎么开发dapp估计要等到下周了吧。

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

结合scatter 学习eos dapp开发, 看这篇就够了(上)

发表于 2018-10-13

eos安装 方式1

eos安装1
这是eos官网推荐的安装方式。

官网推荐docker,可以减少不必要的麻烦 ,而且步骤超级详细,超级详细,要是安装不成功的话,请确认是否使用mac电脑或者官网推荐的其他操作系统,千万不要使用Windows系统来玩eos,因为官方说过不支持的哈。

eos安装 方式2

eos 安装2

git clone https://github.com/EOSIO/eos --recursive
cd eos
./eosio_build.sh
./eosio_install.sh
// 从源码编译 准备好梯子很重要

eoscdt安装

eosio.cdt 安装1 这里遵循官网的步骤

git clone --recursive https://github.com/eosio/eosio.cdt --branch     v1.2.1 --single-branch
cd eosio.cdt 
./build.sh eos
sudo ./install.sh
//这是新的生成wasm 和 abi的工具,以后官方会维护的,之前方式会在后续被移除 

eosio.cdt 安装2 这里是最新的步骤

eos安装 方式总结

简单,超级简单。
但是,受限于我们得环境,自备梯子是成功的第一步,第二步就是要一个适合的硬件,两者缺一不可。

eos智能合约开发 开发体会

最好的学习资料就是官方提供的资料了,而且eos官方的资料具详细,在此送上
eos官网

安装不是我要说的重点,过程艰辛就不说了,有问题Google或者度娘吧,我这里主要想要与大家分享的是如何使用scatter连接eos的测试网或者主网进行dapp的开发。

上面的环境安装了可以启动本地的节点来进行测试,官网也是如此,而现在我能够搜索到的文章基本上也是基于本地节点使用命令行来进行开发,这样只能保证你学习开发eos的流程,但是具体怎样开发dapp你可能还是不清楚,因为你不知道如何连接scatter,如何与智能合约进行交互,所以这篇文章重点解决的问题是在这里。

这里再区分一下钱包开发和dapp的开发。钱包开发需要用户提供他的私钥给你,或者你创建好给用户。而我们此处所要使用的是官方的钱包scatter来进行开发dapp,不需要用户提供私钥给我们,他只需要接入官方提供的scatter就好,如果你有以太坊的经验,这就是metamask

eos智能合约开发 scatter安装

scatter,官方提供的eos钱包,这样用户才会放心把他们的密钥放进去,所以先安装它吧
scatter是chrome的插件,所以你先得安装它chrome浏览器下载
接下来把scatter 插件安装上 scatter Chrome插件

scatter
搜索scatter安装就好,我这里是安装好的界面

  • scatter
    点击插件的scatter图标弹出如图界面,输入你的钱包密码然后点击生成钱包就好
  • scatter
    助记词,抄写下来吧,以后恢复钱包用的
  • scatter
    这里我选择skip basic setup,后续再来设置也是可行的
  • scatter
    这个界面,点击右上角的⚙图标
  • scatter
    这个界面,选择language,设置语言
  • scatter
    设置好后,切换回来,成功了

    eos智能合约开发 使用scatter生成密匙对

  1. 经过以上的步骤,scatter已经安装好了,也就是我们创建了钱包,但是我们的钱包还没有内容的,为什么呢?这里我还是看看官网的这张图吧
    eos钱包关系
  2. 基于上张图的方式,我们得创建一对密匙,那就按照接下来的方式做吧
    • scatter
      点击密匙对,点击新建
    • scatter
      点击生成密匙对
    • scatter
      重点,记住这里的步骤不能省略
      重点,记住这里的步骤不能省略
      重点,记住这里的步骤不能省略
      点击 复制
    • scatter
      新开一个文本文档,点击粘贴,这样就把生成好的密匙对保存下来了,待会要用的
    • scatter
      为这个密匙对取个名字,随便写,随意几好
    • scatter
      完成了这些步骤,你应该能够看到上面的信息,如果没有,就再从头来一遍了。
      这样我们的密匙对就创建好了,但是只是在本地创建好了的啊,怎么连接到测试网络和主网络呢?

eos智能合约开发 设置scatter连接 jungle test net

  • scatter net setting
    回到这个界面,选择设置图标,选择
  • scatter net setting
    这个界面选择网络
  • scatter net setting
    这里可以看到已经有一个eos和eth的主网的网络节点,那么我们来把我们的测试网络的节点加入进去,点击右上角的新建
  • scatter net setting
    这个界面就是设置网络所需要的一些必要信息,我们一个一个来填
    1. 由于我们是连接eos网络,所以这里第一项默认不变,下拉框可以选择eth,以后还可以支持tron
    2. 名称: 随便写一个,你自己记得住就好
    3. 改成http,因为我们测试网络的endpoint就是用的这个协议,照改就好。
    4. 域名或ip地址:jungle.cryptolions.io
    5. 端口 :18888
    6. chaninId: 038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca
    7. 如果你对以上填入的这些信息想知道为什么,那么可以补一下rpc协议,不想了解直接填入就好,以后就懂了
  • scatter net setting
    按照上述的步骤填完后,信息如上,点击右上角保存
  • scatter net setting
    没有问题的话,会看到如上红框的显示内容,代表我们得测试网络已经设置好了

eos智能合约开发 在jungle测试网络上创建account

为什么要创建账户呢?这就是eos的一大特点。BM说,你创建了一个密匙对,谁记得住呢,所以就设计了一个这样的账户系统,这个账户 长12位,只能由a-z12345这些字符组成。简而言之,方便记忆。

  • jungle net account
    打开jungle测试网络地址
  • jungle net account
    来到jungle的主页,点击 Create Account
  • jungle net account
    1. Account name : 看清楚要求 小写字母 加上12345,总共12个字符
      这里我写作 shaokun11113
    2. owner public key : 将我们用scatter生成的那个密匙对的公钥填入这里
    3. active public key: 将我们用scatter生成的那个密匙对的公钥填入这里
    4. 我这里用一对就好,在主网申请账号的时候建议使用两对密匙对。想要知道为什么?可以看看eos第二版的白皮书
  • jungle net account
    这次我就这样填写,然后人机验证,通过后点击左下角的create,确保网络质量优良

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

带你以通俗易懂的小例子了解bancor

发表于 2018-10-02
bancor的简单概述

bancor是一种算法用于区块链的一种新的token的交易方式,目的是解决长尾的问题,增加ERC20的流通。长尾简单理解就是99%和1%的关系,即1%的token在大家的认知中有实际价值,而99%的token是没有的。那么通过bancor协议就是可以解决这99%的token,也可以给一个机会,让他们也有实际的价值。
具体可访问bancor github repo,这里有详细的介绍和白皮书

bancor名词展示

以下资料来自网络 start

Token的供应量【Smart Token’s Supply】,简称Supply;

Token的价格【Smart Token’s Price 】,简称Price;

Token的总市值【Smart Token’s Total Value】,简称TotalValue;

储备金余额【Connector Balance】,简称Balance;

储备金固定比率【Connector Weight】,简称CW。

计算公式如下:

CW = Balance / TotalValue;

TotalValue = Price * Supply;

Price = Balance /(Supply * CW)

举例:若当前AToken的发行量为1000,报价为0.5个ETH兑换1个AToken,那么AToken的总价值为500个ETH,但是储备金余额可能并没有500个ETH,比如为250个ETH,那么CW则为0.5(50%)

Token买入计算公式:

Token_Return = Supply *((1 + ETH_Amount / Balance)^ CW - 1)
//此公式的证明可以通过查看白皮书

例如 若当前AToken的发行量为1000,储备金余额为250个ETH,CW为0.5,那么当前的报价则为0.5个ETH兑换1个AToken;现在Bob想花750个ETH购买AToken,带入公式:Token_Return = 1000 *((1 + 750 / 250)^ 0.5 - 1)= 1000

即Bob花了750个ETH购买了1000个AToken,本次购买的平均价格为0.75个ETH兑换1个AToken。
Bob的购买行为推高了AToken的报价。若Bob接着购买同样数量的AToken,则需要付出更多的ETH代价,每一笔购买都会继续推高AToken的报价。

Token卖出计算公式:

ETH_Return = Balance *(1 - (1 - Token_Amount / Supply)^ (1 / CW))

在Bob的那笔交易完成后,AToken的发行总量为2000个,储备金余额为1000个ETH,CW维持不变、仍然为0.5,那么通过公式可以计算当前的报价为1个ETH兑换1个AToken;现在Alice想卖掉1000个AToken,带入公式:ETH_Return = 1000 *(1 - (1 - 1000 / 2000)^ (1 /0.5))= 750

即Alice 卖掉了1000个AToken,获得了750个ETH,本次购买的平均价格为0.75个ETH兑换1个AToken。因为Bob的购买行为推高了AToken的报价,而Alice是在Bob的购买行为之后卖掉了AToken,所以Alice卖到了相对较高的价位。假如没有Bob的购买行为,回到AToken的供应量为1000的那个时候,Alice卖掉全部的AToken,也只能获得250个ETH

智能代币(Smart Tokens)

智能代币是Bancor协议的核心。它们的运作类似于常规代币,在ETH区块链上使用的符合ERC20标准[5],但也要包含额外的逻辑,即允许用户通过它的智能合约直接购买和出售代币,价格通过程序自动调整以反映供求关系。实际上,智能代币拥有一种内置的流动性机制,确保它们可以持续地为兑换为其他代币。

智能代币连接器(Smart Token connectors)

智能代币连接器可以被视为分布式、自主、透明和可预测的做市商,而不是交易所。智能代币通过程序自动调整它们的价格,来管理它们的连接器准备金,以保持它们与智能代币的总市值之间的比率是恒定的。
锚定代币(connected token)
每个智能代币都配置了连接器模块,这些模块持有它连接的另一个代币作为准备金(例如,BNT智能代币有一个连接到ETH的连接器,它持有ETH作为准备金)。ETH此时就是连接器代币。

代币网络(token network)

智能代币可以实现自己和它们的连接代币之间进行即时兑换。这个功能足以使智能代币即时兑换为一定数量的以类似的方式连接到同一网络的任何其他代币。通过这种方式,智能代币可以连接到无限数量的代币,从而创建一个分布式的流动性网络,该网络可能由数百万个代币组成,这些代币都可以以不断计算的价格自动地相互兑换。

中继代币(Relay Token)

具有两个连接器的智能代币,其总CW恰好为100%,其功能类似于分布式代币兑换币对。中继代币允许用户在两个连接代币之间互相兑换,通过两步操作实现,即购买一种代币,立即出售另外一种代币。

流动性代币(Liquid Tokens)

具有组合连接器总权重低于100%(更典型的低于20%)的智能代币成为流动性代币。可能有一个或者多个连接器。例如,BTN具有单个权重为10%的ETH连接器。流动性代币可以使用连接器代币买卖(使用Bancor公式计算它相对于连接代币的价格),并且可以自适应调节供应量,在购买时增加,出售时减少。

代理代币(Proxy Token)

具有一个连接器占100%权重的智能代币。

组合代币(Array Token)

具有三个或者更多连接器权重为100%的智能代币。

糖果代币(Bounty Tokens)

具有单个尚未激活连接器的智能代币(当前连接器准备金为0),可以向早起持有者(例如社区支持者)发放将来会发行的代币。

网络代币(Network Tokens)

由多个(>2)智能代币持有作为连接代币的智能代币,BNT就是一个网络代币,也是一个流动性代币。

交易者

持有、兑换和支付智能代币的终端用户

智能代币发行者

发行智能代币,配置初始供应量、价格、连接器权重CW和管理智能代币初始发行的人员、公司、社区、组织或基金会。还包括将现有ERC20代币连接到Bancor网络的中继代币的创建者。

资产代币化者

将代理代币或者组合代币映射到实体资产或者其他区块链上代币的创建者。这允许智能代币连接到更广泛的资产,如比特币、法定货币、黄金或其他新兴的区块链代币。

套利者

监控Bancor流动性网络与外部交易所或者其他智能代币的价格,并且通过套利消除价差的交易者。套利者通过消除价差获得奖励,因此是Bancor生态系统的重要参与者。

end

我之理解
cw的理解可以参考很那张很经典的图
cw<50%:price与supply的变化可理解为指数函数y = x^N 的形式变化
cw=50%:price与supply的变化可理解为一次函数y = ax (a>0)的形式变化
cw>50%:price与supply的变化可理解为对数函数y = y=logN(x)的形式变化
cw=100%:price与supply的变化可理解为常数函数y = x的形式变化  
  1. 我发行一个smart token(暂且叫sk),总量1000个 ,即supply= 1000 sk
  2. 预估一下我这个项目的价值,暂且估计价值1000个eth ,即TotalValue = 1000 eth
  3. 而我只有100个eth,那作为储备金,剩余的向大家融资吧,即balance = 100 eth
  4. 设定cw = 10%,
  5. 根据算法,得到price = 1 sk/eth,
  6. 到此,可理解为我用100eth以单价为10买了1000 sk,
  7. 使用100 eth买入,根据买入公式,得到((1+(100/100))^0.1 - 1) 1000= 0.0718 1000 = 71.8个sk,
  8. 当执行上笔交易后,cw是不会变得,其余的会动态调整。那么此时的sk supply = 1071.8 sk,balance = 200 eth,price = 1.866 sk / eth
  9. 这里可以看到买入100个后,一个sk价值1.866个eth,价格上涨了呢。这里有兴趣的同学可以试试连续分批次买10次,每次10个eth,可以看到价格的变化,最终的结果也是一样的,这就是bancor算法保证的结果
  10. 再继续使用100eth买入,根据买入公式,得到((1+(100/200))^0.1 - 1) 1071.8= 0.0414 1071.8 = 44.37个sk,这样后来买的价格就比之前的高了,获得的sk就会少,也就是价格高了
  11. supply = 1116.7 sk,balance = 300 eth,price = 26.86 sk/eth 单价已经翻了20倍了
  12. 卖出50 sk,根据卖出公式 300 *(1 - 50/1116.7)^(1/0.1) = 189.7488 eth
  13. 额,初始值设定的不恰当,整个流程算出来的结果有点恐怖,有兴趣的同学可以按照流程调整一下初始值哈0.0
  14. 这里可能有同学会问了,我刚使用100eth获得44个sk,我马上又卖出50个sk可以得到189个eth,大赚了啊。理论上是成立的,但是你得保证你这两个操作中间没有其他人的卖出哈(买入你就赚得越多),其他人卖出之后,你再去卖价格就低了,所以得自己评估风险哦

小结:

  • 控制cw的变化,可以控制token的价格的走势
  • 买入,会提高smart token的价格,卖出会降低smart token的价格,具体变化由cw的决定
  • 缺点:这些数据都是采用智能合约编写的,无法改变。但是项目方可以更改cw的值,从而控制整个token的价格走势
  • 优点:你如果持有smart token是可以随时和储备金类型的token进行买卖的。这都是由智能合约自动执行,这点可以相对于传统的1co有着更好的安全,至少你持有的token有着更好的流通性,随时都可以流通,也可以换取其他的token或者储备金的token
关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

资料更新 2018-10-13 15:50:20

更新一下,这里补上bancor的经典cw图,便于大家理解。
cw
根据这张图中的曲线,那么你所持有的币的价值就是等于曲线上任意两点作x轴 所形成的面积。所以任何一点点的买入卖出都会影响整个智能代币的价格
另外附上bancor的白皮书
bancor 白皮书 英文版

全新的加密NTF表现形式---ERC998

发表于 2018-09-19
ERC998

在开始之前,你可能需要了解一下区块链,比特币,以太坊,ERC20和ERC721的相关知识,因为整篇文章也是在此基础上的一个应用的开始。

ERC998目前状态Draft,创建于2018/7/7
具体信息可访问ERC998。
特性:可组合(composable)。ERC20和ERC721仅仅是单一的物品的应用,而ERC998可以组合不同的ERC721和ERC20,使之产生更丰富的应用。可以类比主机(ERC721) + 显示器(ERC20)+ 外设(ERC721)= 电脑(ERC998);通过这样的组合我们就能够创建出更加复杂,高级的功能。

ERC998的两种实现

ComposableTopDown和ComposableBottonUp,本次结合我实际的应用只讲介绍前者,具体的不同可以参考官网,当然这里有一篇作者更详细的介绍:
Top-Down and Bottom-Up Composables, What’s the Difference and Which One Should You Use?

ERC998接口分析

原作者已经写得非常详细了,具体就不在具体分析了。这里结合avatar(ERC998的实现的虚拟形象)和clothes(ERC721的实现的衣服)简单的看看ComposableTopDown的实现吧。(ComposableBottonUp的原理也类似)

interface ERC998ERC721TopDown

event ReceivedChild(address indexed _from, uint256 indexed _tokenId, address indexed _childContract, uint256 _childTokenId)

当avatar接收到一件clothes会触发的一个事件
_from : clothes的原始owner address
_tokenId : 哪一个avatar来穿这件衣服,即avatar id
_childContract: clothes contract address
_childTokenId: 哪一件衣服,即clothes id

event TransferChild(uint256 indexed tokenId, address indexed _to, address indexed _childContract, uint256 _childTokenId);

当avatar脱下一件clothes时会发出的一个事件
tokenId : 将要脱下clothes的avatar id
_to : 接收clothes address,在项目中
_childContract: clothes 合约地址
_childTokenId: clothes id

function rootOwnerOf(uint256 _tokenId) external view returns (bytes32 rootOwner);

rootOwner:获得clothes的owner address,实际上是调用的下面的这个函数
返回的是加上ERC998的特殊值加上owner的address,可以通过address(_rootOwner)得到owner的address
_tokenId 需要查找的avatar id

function rootOwnerOfChild(address _childContract, uint256 _childTokenId) external view returns (bytes32 rootOwner);

rootOwner:cloth对应的owner address
这里注意一下,此处返回的 root owner有可能是contract address ,也有可能是user address。根据作者的设计总共有四种可能
_childContract : clothes contract address
_childTokenId : clothes id

function ownerOfChild(address _childContract, uint256 _childTokenId) external view returns (bytes32 parentTokenOwner, uint256 parentTokenId);  

parentTokenOwner: 返回的是加上ERC998的特殊值加上owner address
parentTokenId : avatar id
_childContract: clothes contract address
_childTokenId: clothes id

function onERC721Received(address _operator, address _from, uint256 _childTokenId, bytes _data) external returns (bytes4);

bytes4: 返回的一个bytes4的值 用于更新其他NTF到avatar时的一个回调方法,告诉avatar转入了这个数据,将此数据添加到avatar的数据中.
这里使用NTF代替其他ERC721 token
_operator: 执行这个操作的address
_from : 原始NTF 拥有者的 address
_childTokenId: NTF id
_data : 附加数据

function transferChild(uint256 _fromTokenId, address _to, address _childContract, uint256 _childTokenId) external;
function safeTransferChild(uint256 _fromTokenId, address _to, address _childContract, uint256 _childTokenId) external;
function safeTransferChild(uint256 _fromTokenId, address _to, address _childContract, uint256 _childTokenId, bytes _data) external

这是三个重载的方法,加上safe是为了确保转入的合约地址有类似于onERC721Received的方法进行回调,确保token不会丢失。如果转入的合约地址没有注册次方法,那么将不会转入成功,从而回退转移操作,保证NTF的安全。
如果转入的是user address,那么直接调用第一个方法即可。
这些方法均会触发TransferChild这个事件
_fromTokenId : avatar id
_to :接受clothes address
_childContract : clothes contract address
_childTokenId : 将要进行转出的clothes id

function transferChildToParent(uint256 _fromTokenId, address _toContract, uint256 _toTokenId, address _childContract, uint256 _childTokenId, bytes _data) external;

如果avatar含有ERC998 ComposableTopDown的token,可以通过这个方法进行转移

function getChild(address _from, uint256 _tokenId, address _childContract, uint256 _childTokenId) external;

用于用户user自己转入clothes到avatar中,注意与onERC721Received进行比较。
_from : clothes拥有者的address
_tokenId :转进给哪一个avatar,即avatar id
_childContract : clothes contract address
_childTokenId : clothes id

interface ERC998ERC721TopDownEnumerable

function totalChildContracts(uint256 _tokenId) external view returns (uint256);

获取avatar下面有多少种类的NFT,目前可以知道我们的项目只有clothes,所以返回1
_tokenId : avatar id

function childContractByIndex(uint256 _tokenId, uint256 _index) external view returns (address childContract);

获取NFT的contract address。目前我们的Bitizen中,仅有clothes,所以结果只有clothes的contract address
_tokenId : avatar id
_index : 从0开始的下标

function totalChildTokens(uint256 _tokenId, address _childContract) external view returns (uint256);

获取NTF的数量,即获取clothes的数量
_tokenId : avatar id
_childContract : NTF contract address,即clothes的合约地址

function childTokenByIndex(uint256 _tokenId, address _childContract, uint256 _index) external view returns (uint256 childTokenId);

根据totalChildTokens的返回值,获取具体的每一个NTF id
_tokenId : avatar id
_childContract : NTF contract address,即clothes的合约地址
_index : 从0 开始的索引,小于totalChildTokens的返回值

interface ERC998ERC20TopDownEnumerable {
function totalERC20Contracts(uint256 _tokenId) external view returns (uint256);
function erc20ContractByIndex(uint256 _tokenId, uint256 _index) external view returns (address);}
interface ERC20AndERC223 {
function transferFrom(address _from, address _to, uint _value) external returns (bool success);
function transfer(address to, uint value) external returns (bool success);
function transfer(address to, uint value, bytes data) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint256 remaining);}

ERC20集成到ERC998的interface,可按照ERC721的理解,就不一一讲解了

interface ERC998ERC721BottomUp {
function transferToParent(address _from, address _toContract, uint256 _toTokenId, uint256 _tokenId, bytes _data) external;}

声明ComposableBottonUp的接口,用于transferChildToParent
到此为止,ComposableTopDown的对外开放的接口已经分析完毕了。

ERC998实际运用

Bitizens在这里,你可以找到第一个基于ERC998创建的一款3D游戏,你可以免费创建一个只属于你自己的bitizen.

结尾

这篇文章仅仅分析了ERC998的标准接口,当然其中也涉及到ERC721和ERC20的一些知识,希望能够给将要进入dapp的开发者提供一点点帮助。

文章允许转载,但请注明出处,谢谢

关于我

区块链技术痴迷的程序猿一枚,如果你喜欢我的文章,可以加上微信共同学习,共同进步。

1…34

shaokun

点滴积累,聚少成多! 心中有善,不骄不躁

38 日志
© 2021 shaokun
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
访问人数 访问总量 次