首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

EOS智能合约开发系列(七):多索引table

本文介绍eosio提供的一个可持久化状态的类:多索引table。可以理解为这是一组操作数据库的方法所组成的类。在写智能合约的时候,势必要持久化数据,要持久化数据就势必用到多索引table。

多索引table就是我们上一篇中遇到的这个类了:

它提供了一组持久化数据的操作。它提供的功能类似于DB的功能,所以有人把它也称之为。 不过,因为这个类更相当于db中的一个table(每次写入的数据都相当于的table中的一条record),所以我有时候会把这个类称之为了。

为什么需要持久化存储

EOSIO合约是通过action来触发执行的。action在每次执行的时候都会有一个自己的上下文环境。 每个上下文会在每次action触发前,为其开辟一块干净的内存。所以在内存中的数据状态是无法在action之间传递的,也就是说,如果你在一个action中设置了某个变量,在另一个action中是无法获取到你对应的值的。在action之间传递状态的唯一方法,是将其持久化并从EOSIO数据库中检索它。

你可能会说,我修改类的字段应该是可以在action之间传递的吧?总不能全局变量也不行吧?是的,都不行。验证也很简单,比如我们修改一下我们之前写的hello合约的,像下面这样:

部署完之后,我们多次触发 hi和say,你会发现,每次输出的和的结果都是一样的。

也就是说,持久化是在action之间传递状态的唯一方式。而table是我们目前持久化的唯一方法。

Multi-Index table 的特点

它可以可以支持多索引。除了一个主索引外,还可以支持16个二级索引。每个索引的排序方式都是可以自定义的。

支持迭代器,并且符合常规的C++迭代器模式。每个迭代器都有const版本,而且支持反向迭代。

如何创建table

给你要持久化的对象定义一个或者,一个table只能存储一种类型的对象

在该中,定义一个primary_key方法,它返回一个uint64_t类型的值作为该table的主索引键

确定二级索引,最多可以达到16个,二级索引支持以下类型:

如何使用

可以使用 方法来插入记录,方法来修改记录,方法来删除记录。

可以使用和方法,以及iterator查找记录。

举例说明

创建一个结构(要存储的数据结构类型)

上面代码中,我们把想要存储的数据类型定义出来,并定义一些方法获取我们想要生成的索引的值。记住,我们必须要有一个方法,它返回我们表的主键。另外还可以定义最多16个其他的索引,每个所有都有一个方法对应,比如上面的,就是一个的。

还有两点需要注意:

//@abi table 这个注释的作用是公开数据库中的数据。在有这个注释的情况下,任何人都可以获取此table的数据。如果没有该注释,除了代码可以访问该table外,任何人都无法通过命令行来获取table数据。我个人认为,这是EOS对table设计的一个缺憾,对于table中的数据获取权限没有一个灵活的权限设置。理应在有相应许可的情况下,允许某些许可通过命令行来获取table数据。

上面这个类的名字必须小于12个字符,并且都是小写。

table的索引

这个是C++的语法,一个新的类型,这样之后就可以用声明变量,不需要这么长了。第一个模板参数代表table的名字,N的作用是可以把字符串转化为一个uint64_t类型的整数。第二个参数代表要存储的记录的类型。

如何指定二级索引呢?可以用模板参数,像下面这样:

其中

的意思是:

索引的字段名被转化为一个整数,

代表提取哪个索引。这里的代表要对哪个table进行排序,代表依照哪种类型进行排序,代表提取排序索引的方法。这里的的类型应该与的返回类型保持一致。

如果有更多的索引,可以像下面的代码这样:

注意:

这个记录类型必须与table的名字保持一致。也就是第一个模板参数必须是这种形式的;如果记录类型是,那么第一个模板参数必须是,按此类推。

如果你想让你的table对于外界是可见的,也就是可以通过获取,那么table的名字必须小于12个字符,并且都是小写的;而且在记录类型声明的时候,一定要加上//@abi table字样。

一个完整的例子

虽然table的内部实现很复杂,不过用起来还是蛮简单的。这个例子只用到了emplace这个方法,其他方法也都是类似的,我就不一一举例展示了。后面需要用到这些方法的时候,我再强调一下。

我们在后面的智能合约的学习中,会经常用table类。

欢迎加入知识星球讨论学习。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180928G0H6ZH00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券