EOS Asia

本教程原文作者为EOS Asia,亚洲最具技术实力和最国际化的EOS超级节点竞选者。EOS Asia 同时也是EOS Gems和Traffic Exchange Token这两个项目背后的开发者。

本文由 DappReview 获得 EOS Asia 授权进行翻译并发表。

本篇是EOS智能合约系列第二弹,该系列教程旨在帮助开发者从0到1快速上手如何在EOS生态下开发DApp。如果有任何希望深入讨论的主题,欢迎留言给我们!如果你还不知道怎么在EOS下部署智能合约,请先阅读系列第一弹《[技术教程]EOS智能合约开发:第一节——准备发车》

在大部分的应用场景中,开发者都需要通过智能合约与区块链上“永久保存”的数据进行交互。本次教程中,我们会一起通过 To-do List(待办事项)这个实例,来教会你如何实现与数据交互的标准操作(CRUD - Create, Retrieve, Update, Delete)

深入了解 Boost.MultiIndex

由于EOS的智能合约基于C++,我们需要利用Boost.MultiIndex Containers这个库。下面是该库的说明:

Boost多索引容器库提供了名为multi_index_container 的类模板,可以用于建造拥有一个或多个索引(indices) 的容器,不同的索引具有不同的排序和访问语义。这些索引都提供了类似于STL容器的接口,因此使用起来也非常相似。在一组元素之上维护多个索引的想法来自 于关系数据库,并且考虑到简单的set和map无法满足多索引表中的复杂数据结构的规范。

让我们把上述的一些概念拆分讲解一下,并与开发者所熟知的传统数据库概念做类比:

容器(Containers)

  • 包含很多元素的类(table/表)

元素(Elements)

  • 数据对象(rows in a table/表中的行)

接口(Interface)

  • 容器读取元素的方法(query/查询)

在EOS智能合约中,可以使用 eosio::multi_index 来定义多索引容器。如果我们读一读使用了这个特性的一些合约例子,比如这个“骰子合约”:

https://github.com/EOSIO/eos/blob/master/contracts/dice/dice.cpp

你会发现很难真正搞明白到底是哪一部分是在处理区块链上的数据。不过别担心,我们会带你理解它,很快你就能自己实现一个有存储功能的智能合约。

我们将通过开发一个To-do List (待办事项表)小DApp来理解上述的内容。从功能上,要能勾掉已经完成的事情,添加新事项,以及删除不需要的事项。在这个例子中,我们将用 todos 作为容器名,todo 作为元素结构。

从初始化第一个容器为开始,首先,我们向 eosio::multi_index 传入两个模板参数。第一个参数是我们的容器名,第二个参数是定义元素的数据结构。来给我们的todo模型创建一个小例子,如下:

struct todo {uint64_t id;uint64_t primary_key() const { return id; }EOSLIB_SERIALIZE(todo, (id))
};typedef eosio::multi_index<N(todos), todo> todo_table;
todo_table todos;

简单有效!我们简单地定义了一个64位无符号整型的ID,并通过primary_key来访问它。把多索引定义成typedef,暂时还不需要把它实例化。目前为止,这个todo模型里面还没有什么东西,下面来添加一些参数:

struct todo {uint64_t id;std::string description;uint64_t completed;EOSLIB_SERIALIZE(todo, (id)(description)(completed))
};typedef eosio::multi_index<N(todos), todo> todo_table;
todo_table todos;

现在我们更近了一步,加入了待办事项的描述参数- description (比如 “完成小说撰写”)和状态参数- completed(用来记录一个事项在当前是否完成了)。

为了方便自动生成我们的ABI(Application Binary Interface),我们在容器定义前面加一行注释来帮助生成器:@abi table profiles i64

那么在注释里的 i64 是什么意思呢,它是我们的查询索引。默认情况下,我们需要一种在容器里查询元素的方法,而我们的前64位(64位类型下,基本上是first key)就可以用来干这件事。一般情况下都用uint64_t id ;对于first key,也可以用 account_name 类型,因为在底层其实 account_name 类型也是一个 uint64_t 类型。参考如下:

https://github.com/EOSIO/eos/blob/2f2c8c7e3811caca178a7553192c8fe59a22576d/contracts/eosiolib/types.h#L22

此时我们应该有了一个功能简单的容器, 代码看起来是这样的:

// @abi table todos i64
struct todo {uint64_t id;std::string description;uint64_t completed;uint64_t primary_key() const { return id; }EOSLIB_SERIALIZE(todo, (id)(description)(completed))
};typedef eosio::multi_index<N(todos), todo> todo_table;
todo_table todos;

使用你的新容器

现在已经有了一个定义好的容器,我们可以使用它里面的元素。在智能合约里,将通过不同的函数与这些元素进行交互。

对于链上的永久性储存有四种基本函数:创建(Create),检索 (Retrieve),更新 (Update),删除 (Delete)。 在这个例子里,我们不需要考虑检索,因为检索是由前端读取合约来处理的而不用函数。对其他的三个,我们将分别创建函数。

创建(Create)- 创建事项

添加一个待办事项进入列表

可以用 emplace 完成

// @abi action
void create(account_name author, const uint32_t id, const std::string& description) {todos.emplace(author, [&](auto& new_todo) {new_todo.id  = id;new_todo.description = description;new_todo.completed = 0;});eosio::print("todo#", id, " created");
}

一个重要细节是我们把author作为一个参数也传入了。在 emplace 方法中第一个参量是必须的。

更新(Update)- 完成事项

创建一个完成事项的函数可以通过更新参数completed 的状态来实现:

// @abi action
void complete(account_name author, const uint32_t id) {auto todo_lookup = todos.find(id);eosio_assert(todo_lookup != todos.end(), "Todo does not exist");todos.modify(todo_lookup, author, [&](auto& modifiable_todo) {modifiable_todo.completed = 1;});eosio::print("todo#", id, " marked as complete");
}

删除(Delete)- 删除事项

这是一个内部调用的智能合约,不用太担心安全性和权限问题。 我们专心搞清楚删除函数如何最简化地实行就可以了:

// @abi action
void destroy(account_name author, const uint32_t id) {auto todo_lookup = todos.find(id);todos.erase(todo_lookup);eosio::print("todo#", id, " destroyed");
}

部署,测试,与前端打通

在上一篇教程中,我们用一个简单的ping/pong实例讲述了如何将一个EOS的智能合约与网页前端连接起来。现在我们有了几个与区块链上的永久性数据交互的函数,下面可以为这个待办事项制作一个前端了。

部署

部署合约的过程比较直观,就下面这几步:

1. 建立合约ABI和WASM:eosiocpp -o hello.wast hello.cpp && eosiocpp -g hello.abi hello.cpp

2. 建立账户/钱包:

cleos create account eosio todo.user EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
cleos set contract todo.user ../todo -p todo.user

3. 测试合约也很简单:

$ cleos push action todo create '["todo", 1, "hello world"]' -p todo.user
executed transaction: bc5bfbd1e07f6e3361d894c26d4822edcdc2e42420bdd38b46a4fe55538affcf  248 bytes  107520 cycles
#          todo <= todo::create                 {"author":"todo","id":1,"description":"hello world"}
>> todo created

4. 获取数据:

$ cleos get table todo todo todos

在前端测试

在这里我们就节省读者的时间,不在文章中深究React.js的代码了,不过我强烈推荐大家去看下这个例子的代码仓库,里面有前端部分的全部代码:

https://github.com/eosasia/eos-todo

如果你希望我们去更深入地探讨一些关于浏览器前端和EOS智能合约交互的内容,不论是用React、Vue、Angular还是原生Javascript,欢迎留言或者在电报群里告诉我们。

电报群:https://t.me/EOSAsia

DAppReview往期精选

[深度干货]浅谈你们根本不懂的区块链游戏

V神看好的Plasma使用指南第一卷:游戏落地

[技术教程]EOS智能合约开发:第一节——准备发车

爆发前夜的区块链游戏——最大的特洛伊木马已经进城

[独家专访]1周13W交易的EtherGoo开发者James & 你所不知道的数据

区块链游戏生态抢滩登陆战,谁能拔得头筹?

c++ eos智能合约开发_[EOS智能合约]第二节:用EOS开发一个To-do List小应用相关推荐

  1. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二节:Cocos引擎开发环境搭建与项目创建!

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第二节:Cocos引擎开发环境搭建与项目创建! 视频地址:http://edu.csdn.net/course/detail/1330 ...

  2. AOSP>设计>测试(第二节)测试开发工作流

    AOSP>设计>测试 第二节 测试开发工作流 一.概览 测试类型 测试用例准则 二.简单配置 示例 设置 三.复杂配置 目标准备器 测试类 四.插桩测试 概览 主要概念 步骤总结 自插桩测 ...

  3. 【C语言从零到入门】第二节 C语言开发工具的安装

    工欲善其事,必先利其器. 要想学习C语言,第一步当然是安装C语言的开发工具,我们在这里选择Dev-C++作为开发工具 为什么选择Dev-C++ ? 小巧,Dev-C++的安装包仅48MB,且对电脑的配 ...

  4. 法庭智能语音系统_法庭智能语音识别系统_法庭智能语音系统解决方案_深圳市亚讯威视数字技术有限公司...

    法庭智能语音系统 现状与需求 庭审过程中,需要形成文字版庭审记录,便于事后追溯或跟踪.现有的人工听写方式受限于记录员的业务熟练程度和打字速度,导致记录效率较低.浪费人力.采用信息化手段改善记录工作,提 ...

  5. 智能镜子制作_更智能的镜子及其制作方法

    智能镜子制作 A while ago I made a smart mirror for my bathroom. Maybe you've seen it. It started with a pa ...

  6. 小度智能音箱维修点_小度智能音箱APP下载

    小度智能音箱app是一款生活家居软件,小度智能音箱app基于音频娱乐.儿童教育.新闻资讯.FM电台等内容娱乐体验,是专门为小度智能音箱用户推出的音频娱乐互动的软件. 软件亮点 帮助用户更全面了解智能音 ...

  7. 小度智能音箱维修点_小度智能音箱无法唤醒怎么办

    小度智能音箱之百度旗下最近非常热门的新款人工智能音箱,刚上线发布就被抢购一空,这不仅仅体现在百度的宣传广告上,还有小度自身的魅力,无论是功能还是外观,都让人眼前一亮,简约大气的设计和音质也是魅力十足. ...

  8. 彼聆智能语音机器人_南昌智能语音机器人作用

    南昌智能语音机器人作用dfv39g 人工智能+电话销售把人类从重复的脑力劳动中解放出来这个任务沉重却赋予了咱们奋斗的动力,咱们把解放话务员的重复脑力劳动作为完结任务的个里程碑心态是一个大门槛. 南昌智 ...

  9. 小度智能音箱维修点_小度智能音箱——联通智慧生活语音服务入口

    恭贺新春 2019年伊始,中国联通联合白度推出小度智能音箱(行业版),定位于服务行业渠道的终端用户.搭载DuerOS语音交互系统,说出"小度小度"唤醒音箱进行语音互动,可以听歌曲. ...

  10. 巴巴腾小腾智能对话机器人_我的“心”始终陪伴着你——巴巴腾陪护机器人“小腾”...

    原标题:我的"心"始终陪伴着你--巴巴腾陪护机器人"小腾" 在这个科技发展快速的时代,陪伴孩子成为了每个埋头苦干的人的愿望,都希望孩子有个愉快的童年却抽不出时间 ...

最新文章

  1. FFMPEG转码常用命令研究
  2. 渔民之友:Google X 新项目,用计算机视觉养鱼
  3. 推荐7款好用的cmd命令行终端工具
  4. win_redis【win下安装使用redis】
  5. UI5 setModel 的核心逻辑
  6. Zookeeper 使用
  7. C和C++混合编程(__cplusplus使用)
  8. 2020中国直播电商生态白皮书
  9. 【安全-相关】kerberos hadoop Login failure for hadoop/localhost@YOUNG.COM from keytab
  10. Linux安装Oracle,卡在60%处的解决方法
  11. 推荐两个有意思的自定义View小项目
  12. html百度地图导航起点默认定位位置,百度地图API的自动定位路线查询
  13. 大气压力换算公式_压力公式换算
  14. excle表格导出到本地
  15. C语言----整钱换零钱问题。把1元兑换成1分,2分,5分的硬币,共有多少种不同的兑换方法?(同理n元硬币的兑换方法呢?n元由用户输入)
  16. 英特尔神经计算棒二代(NCS2)安装、配置及使用
  17. HTML小案例-使用CSS3实现网页加载loding动画
  18. vue element-ui Radio单选框默认值选不中的原因:混用字符和数字
  19. 如何对文本框进行功能测试
  20. php固定登录账号,PHP实现会员单一账号登录

热门文章

  1. ASP.NET Core WebListener 服务器
  2. .NET Core全新的配置管理[共9篇]
  3. Android之android8.1打开热点提示UID 10140 does not have Location permission和Location mode is enabled.
  4. java之DocumentBuilderFactory解析xml
  5. LeetCode之字符串(C++)的切割简单实现
  6. Android之Gradle Plugin Samples 之Gradle Library Projects
  7. 中科大镜像源_JETPACK4.4安装软件和备份镜像的方法介绍
  8. google浏览器插件 开发 获取页面指定数据_程序员必备的4款Chrome插件,编程神器...
  9. vscode搜索文件_VS Code 新图标来临 —— 侧边栏、文件管理器、搜索、调试等区域的图标迎来全新设计...
  10. java list 初始化_Java新特性:数据类型可以扔掉了?