EOSIO合约开发库

通过简单的源码分析,可以很清楚的看到EOSIO合约开发库在目录libraries下,各个库的功能如下:
注意:由于篇幅问题,只介绍最主要的,常用的

CDT: 总目录|----libraries: 合约开发库总目录|----boost: 经过裁剪的boost库|----eosiolib: 链提供的合约API接口|----capi: 访问链的宿主函数API接口|----contracts: 宿主函数API的部分封装|----action.hpp: 对action分装,调用内联action,使用此类|----contract.hpp: 合约基类|----multi_index.hpp: 合约中最重要的表结构的实现|----permission.hpp: 权限封装,合约中权限的判断,详细参考多签名合约 |----singleton.hpp: 单例实现,借助multi_index实现,里面只有一条记录|----transaction.hpp: 在EOSIO中可以通过合约给链发送指定于行的交易,该类实现了合约中交易基本的打包与发送|----core: 合约开发基本类型|----asset.hpp: 代币类型,代币符号类型|----check.hpp: 对于合约断言的分装|----crypto.hpp: 加密解密|----datastream.hpp: 结构打包程序,对结构体pack与unpack|----name.hpp: name基本类型封装|----print.hpp: 日志打印封装|----time.hpp: 实现对microseconds,time_point,block_timestamp封装|----libc: c库源码|----libc++: c++库源码

EOSIO合约中表的结构

讨论以multi_index结构来展开,singleton表也是依赖multi_index来实现的

定义

// 以token合约账号表为例,每个账户都独立建立一张代币余额表
struct [[eosio::table]] account {asset    balance; //账户余额uint64_t primary_key()const { return balance.symbol.code().raw(); }  // 以代币符号ID作为主键
};
typedef eosio::multi_index< "accounts"_n, account > accounts;

代码展开如下:
在此句代码中,代码依次展开如下:

// “”_n运算符重载,在name.hpp中实现
template <typename T, T... Str>
inline constexpr eosio::name operator""_n() {constexpr auto x = eosio::name{std::string_view{eosio::detail::to_const_char_arr<Str...>::value, sizeof...(Str)}};return x;
}
/**由于multi_index是模版类,在这里先对该模版进行了特化,特化参数指明了存储的对象类型与表名,表名必须是name类型注意在这里,特化参数必须能隐式转化成int类型才可以,所以这里实现了对""_n重载,看过name类的实现,uint64与name是可以进行互转的
*/
template<name::raw TableName, typename T, typename... Indices>
class multi_index
{...
}

使用与访问

// 获取实例
/*** get_self()   :合约账号 * owner.value  :代币账户
*/
accounts to_acnts( get_self(), owner.value );

上句代码中,直接调用multi_index构造函数,完成multi_index对象to_acnts的实例化

multi_index( name code, uint64_t scope )
:_code(code),_scope(scope),_next_primary_key(unset_next_primary_key)
{}

至此,整个账户表被完成的确认出来

  • 合约账号(code) :确定表属于那个合约,跨合约是不能修改表数据的,但是可以访问读取
  • 表名(table) :确定表名
  • 小分类(scope) :确定记录的小分类,在此例中scope为账户名,故token相当于为每个账户都单独建立一张余额表
  • 主键(primary_key) :确定记录主键,和scope一起合作能确定表中一条唯一的记录
// 查询,添加,修改,删除
auto to = to_acnts.find( value.symbol.code().raw() );
if( to == to_acnts.end() ) {to_acnts.emplace( ram_payer, [&]( auto& a ){a.balance = value;});
} else {to_acnts.modify( to, same_payer, [&]( auto& a ) {a.balance += value;});
}if (to != to_acnts.end()){to_acnts.erase( to );
}

上述代码中,通过multi_inex类依次展开有点长,主要核心代码如下

// 向表中添加数据,具体步骤如下
/**
1 将对象obj,pack进入buffer,统计计算出数据包大小
2 计算获取主键,凑足确定一条记录的三个要素,payer.value是付费账号,eosio是资源消耗型付费
3 调用宿主函数db_store_i64将数据插入表
*/
template<typename Lambda>
const_iterator emplace( name payer, Lambda&& constructor ) {...datastream<char*> ds( (char*)buffer, size );ds << obj;auto pk = obj.primary_key();i.__primary_itr = internal_use_do_not_use::db_store_i64( _scope, static_cast<uint64_t>(TableName), payer.value, pk, buffer, size );...
}

同理参考emplace函数,实现对modify,erase,find函数的分析可知,三个函数最终都调用了对应的宿主函数

  • modify:调用 db_update_i64 函数
  • erase:调用 db_remove_i64 函数
  • find:调用 db_find_i64 函数
// 遍历, 类似stl中list等的遍历,在multi_index中,实现了表的迭代器,这里可以参考stl的源码进行解读
for ( auto itr = to_acnts.begin(); itr != to_acnts.end(); itr++ ) {// do somethings
}

总结

通过对EOSIO合约开发库和合约实例的分析,我们解读出一些新的知识点,对EOSIO合约的开发有了更加深刻的认识

  • 整个合约的代码格式,符合C++语法规范,结构清晰
  • 可以使用C++基本的苦函数,如strcmp,strlen等,也能使用boost一些常用开发库,如vector,list等
  • 合约最终都是通过导入进来宿主函数实现对链,数据库的访问的,对于什么是宿主函数,我们后面在讨论
  • 此文中我们只分析了合约开发中最常用的操作,其他的更加的丰富的操作需要读者自己去做分析

EOSIO源码分析 - EOSIO合约开发库相关推荐

  1. 从源码分析Android的Glide库的图片加载流程及特点

    转载:http://m.aspku.com/view-141093.html 这篇文章主要介绍了从源码分析Android的Glide库的图片加载流程及特点,Glide库是Android下一款人气很高的 ...

  2. EOSIO源码分析 - 给CDT增加eosio的fc开发库

    为什么选择FC库 fc库是eosio中实现的C++反射机制的代码,通过这套机制,您可以极大的提高您的开发效率,他有如下优点: 跨平台,支持linux和windows,可以轻松加入到您的开发工程 代码简 ...

  3. 数据库中间件 MyCAT源码分析:【单库单表】插入【推荐阅读】

    ???关注微信公众号:[芋艿的后端小屋]有福利: RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表 RocketMQ / MyCAT / Sharding-JDB ...

  4. FreeRTOS源码分析与应用开发01:中断配置与临界段

    目录 1. 异常与中断的基本概念 1.1 异常分类 1.2 中断概述 1.2.1 中断处理宜短暂 1.2.2 临界段影响中断实时性 1.3 中断硬件基础 1.3.1 外设 1.3.2 中断控制器 1. ...

  5. FreeRTOS源码分析与应用开发02:任务管理

    目录 1. 任务概述 1.1 任务表示 1.2 任务状态 1.2.1 运行态 1.2.2 就绪态 1.2.3 阻塞态 1.2.4 挂起态 1.3 任务优先级 1.3.1 FreeRTOS优先级配置 1 ...

  6. FreeRTOS源码分析与应用开发07:事件标志组

    目录 1. 概述 2. 事件标志组类型 3. 创建事件标志组 4. 删除事件标志组 5. 设置事件标志位 5.1 任务级设置 5.2 中断级设置 6. 清除事件标志位 6.1 任务级清除 6.2 中断 ...

  7. FreeRTOS源码分析与应用开发04:消息队列

    目录 1. 队列结构 2. 创建队列 2.1 动态创建队列 2.1.1 xQueueCreate函数 2.1.2 xQueueGenericCreate函数 2.1.3 xQueueGenericRe ...

  8. FreeRTOS源码分析与应用开发11(完):编译、链接与部署

    目录 1. 存储设备布局 2. 链接器脚本 2.1 链接器脚本生成 2.2 链接器脚本分析 2.2.1 分散加载文件 2.2.2 加载区 & 运行区 2.2.3 ER_IROM1运行区分析 2 ...

  9. FreeRTOS源码分析与应用开发10:内存管理

    目录 1. 概述 1.1 RTOS中内存分配特点 1.2 内存堆(heap space)来源 1.2.1 ucHeap数组 1.2.2 链接器设置的堆 1.2.3 多个非连续内存堆 1.3 关于字节对 ...

最新文章

  1. 用Python进行诗歌接龙
  2. 9、ctemplate文档,简记(2)
  3. 移动端为何不使用click而模拟tap事件及解决方案
  4. Mysql5.X重点难点速记
  5. kettle 内存设置_【转】kettle 的内存设置及输出日志的时间类型
  6. LeetCode 810. 黑板异或游戏(博弈推理)
  7. python编码问题无法复现_python中烦人的编码问题
  8. Mac查看Python安装路径和版本
  9. python编程语言继承_Python 面向对象编程——继承和多态
  10. 北斗卫星定位系统原理
  11. PS计算机字体Q,PS q萌字体教程
  12. java程序设计概念对象先行_《Java程序设计概念:对象先行》【摘要 书评 在线阅读】-苏宁易购图书...
  13. angular8.x + ngx-translate实现国际化
  14. Kylin启动报错 ERROR: Check hive‘s usability failed, please check the status of your cluster
  15. idear配置工具上传Jar包到服务器并运行
  16. 小程序获取微信运动步数
  17. (16)万能查询还是万恶查询?
  18. 评测5款国内外免费远控,谁是最好用第一名?
  19. 用3DS MAX和PHOTOSHOP制作机器人----作者: Egbert Tjong 来源: 火星时代
  20. idea 安装教程图解

热门文章

  1. 微信小程序格式化日期的几种方式
  2. linux中查看网卡mac地址
  3. python 爬取_Python爬取电影天堂
  4. GAN笔记_李弘毅教程(一)Introduction
  5. 记:《洛克菲勒留给儿子的38封信》-- 29
  6. Lambda之Supplier
  7. vue3+ts eslint报错版本不符合的问题
  8. 1834 单线程 CPU
  9. 【Python CUDA版】河北工业大学计算机图像处理实验五:图像分割
  10. 不拉扯了 不拉扯了 碎碎念 下