eosio.cdt:EOS智能合约工具集
目前EOS已经迎来了1.5.x时代,很多内容都有了较大的改变。其中智能合约的工作流程发生了改变,EOSIO为智能合约提供了独立且功能完整的工具集eosio.cdt。该工具集基于WASM平台,可解耦于eos系统,更便携地完成智能合约的开发编译。此外eosio.cdt在底层优化上已经超脱于eos系统,使用了更新的对LLVM有了更佳地支持,未来在性能方面会有较大提升。本章讲重点介绍eosio.cdt工具集,在该工具集的基础上,分析研究eos现有的官方智能合约例子。
关键字:eos,eosio.cdt,hello,bbt脚本,李嘉图合约,合约更新,合约调试
hello
首先,在本机安装eosio.cdt。官方推荐的安装方式有很多,笔者推荐采用源码安装的方式。
$ git clone --recursive https://github.com/eosio/eosio.cdt
$ cd eosio.cdt
$ ./build.sh
$ sudo ./install.sh
编译
hello合约的源文件内容:
#include "hello.hpp"
using namespace eosio;
ACTION hello::hi( name user ) {
print_f( "Hello % from hello", user );
}
EOSIO_DISPATCH( hello, (hi) )
下面开始编译example/hello合约。执行eosio.cdt刚刚安装的命令eosio-cpp编译合约,传入hello.cpp文件。执行命令:
eosio-cpp -abigen hello.cpp -o hello.wasm
将会生成两个文件:
- abi文件,是合约的描述文件,是可读的json结构,其中包含了合约的备注、版本、结构、接口或动作以及状态库的table,这些内容是由编译工具eosio-cpp通过合约源文件生成的。
- wasm文件,内容不可读,用于将合约部署运行在wasm平台上。
部署
合约成功编译以后,可以在链上部署运行。使用前文介绍的bbt脚本快速构建一个多节点EOS网络环境,然后执行:
cleos set contract useraaaaaaaa examples/hello/ hello.wasm hello.abi
这时会报错:
Error 3080001: Account using more than allotted RAM usage
说明useraaaaaaaa账户的内存容量不够,需要再购买一些。执行命令购买内存:
cleos system buyram useraaaaaaaa useraaaaaaaa "10 SYS"
然后再次执行前面的合约部署命令,内存充足以后,hello合约被成功部署。
执行
下面尝试执行hello合约。使用命令:
cleos push action useraaaaaaaa hi '["evsward"]' -p useraaaaaaaa
同步跟踪EOS节点的日志输出,会发现有hello合约的信息打印出来。
debug 2018-12-20T12:13:20.233 thread-0 apply_context.cpp:28 print_debug ]
[(useraaaaaaaa,hi)->useraaaaaaaa]: CONSOLE OUTPUT BEGIN =====================
Hello evsward from hello
[(useraaaaaaaa,hi)->useraaaaaaaa]: CONSOLE OUTPUT END =====================
要注意开启节点的合约调试选项:--contracts-console
合约编写
下面来研究如何利用eosio.cdt完成合约的编写。首先尝试修改hello.cpp。前面的测试中,执行hello合约时是不限制输入参数的内容的,可以增加检验将输入参数改为有效用户。
#include "hello.hpp"
using namespace eosio;
ACTION hello::hi( name user ) {
require_auth(user);
print_f( "Hello % from lwb", user );
}
EOSIO_DISPATCH( hello, (hi) )
加入了一行代码require_auth(user);用来校验用户的权限,如果输入参数不是有效用户名或者传入的权限与输入用户不一致则会报错,下面来演示如何更新hello合约以及执行最新代码。仍然是编译、部署、执行三步:
- eosio-cpp -abigen hello.cpp -o hello.wasm
- set contract useraaaaaaaa ../hello/ hello.wasm hello.abi
- push action useraaaaaaaa hi '["evsward"]' -p useraaaaaaaa
此时第三步的运行命令将会执行失败,因为不存在名为"evsward"的有效账户,因此修改命令:
push action useraaaaaaaa hi '["useraaaaaaaa"]' -p useraaaaaaaa
即可执行成功,这行命令末尾的-p参数不可省略,因为hello合约修改后增加了对账户权限的校验。目前这个参数是hello合约的部署者,如果传入其他有效账户并附属其权限,也是可以执行成功的。
push action useraaaaaaaa hi '["useraaaaaaab"]' -p useraaaaaaab
传入的参数改为了b结尾的账户,同时附属了其权限,该action也会成功执行。输出日志为:
Hello useraaaaaaab from lwb
李嘉图合约
通过以上对权限hello的测试,似乎能够察觉出某种深意,即有效账户useraaaaaaaa的动作是由自身签名(通过-p参数)的,useraaaaaaab账户的hi动作也是其自身签名。这种该执行其合法绑定者来关联该合约的每一个action的合约,被成为李嘉图等价的合约,简称李嘉图合约。
合约更新的结论
上面更新一个合约时,是使用相同的部署者重新部署修改后的合约。在EOS中,合约一旦被部署者部署,该合约的所有动作均通过部署者来发起。此外,一个部署者可以多次部署同一个合约,同时也可以部署不同的多个合约,以最后一次部署为准。这部分可以通过部署者code来检查:
cleos get code useraaaaaaaa
输出该账户的code,code就是对应部署的合约的hash。
code hash: ddf06bb75dadfb0b598df0047f5e469891dafce125e0224f869dc8d8e2f5d770
当部署者部署新的合约时,该code会被更新。
合约调试
由于智能合约的运行平台的特殊性,目前暂无法去到WASM平台通过断点的方式调试合约的字节码,因此官方给出的调试方法是通过日志,正如上面所展示的内容那样,官方称之为Caveman debugging,也自嘲了智能合约的原始调试手段。
eosio.cdt:EOS智能合约工具集的更多相关文章
- 【精解】EOS智能合约演练
EOS,智能合约,abi,wasm,cleos,eosiocpp,开发调试,钱包,账户,签名权限 热身 本文旨在针对EOS智能合约进行一个完整的实操演练,过程中深入熟悉掌握整个EOS智能合约的流程,过 ...
- 【精】EOS智能合约:system系统合约源码分析
系统合约在链启动阶段就会被部署,是因为系统合约赋予了EOS链资源.命名拍卖.基础数据准备.生产者信息.投票等能力.本篇文章将会从源码角度详细研究system合约. 关键字:EOS,eosio.syst ...
- EOS智能合约授权限制和数据存储
EOS智能合约授权限制和数据存储 在EOS合约中,调用合约需要来自账户的授权,同时还要指定需要调用的动作.当然,有的合约并不是所有账户都可以调用的,这就需要用到授权限制.接下来我们就来看看如何限制合约 ...
- EOS智能合约开发(四):智能合约部署及调试(附编程示例)
EOS智能合约开发(一):EOS环境搭建和创建节点 EOS智能合约开发(二):EOS创建和管理钱包 EOS智能合约开发(三):EOS创建和管理账号 部署智能合约的示例代码如下: $ cleos set ...
- EOS智能合约开发(三):EOS创建和管理账号
没有看前面文章的小伙伴可以看一下 EOS智能合约开发(一):EOS环境搭建和启动节点 EOS智能合约开发(二):EOS创建和管理钱包 创建好钱包.密钥之后,接下来你就可以创建账号了,账号是什么?账号保 ...
- EOS 智能合约编写(一)
本文编写了一个简单的EOS智能合约,实现用户管理和资产管理,包括存钱,取钱,转帐的功能,旨在学习如何编写自己的EOS合约功能. 系统:Ubuntu EOS版本:v1.1.1 一.智能合约代码 ...
- eos智能合约执行流程
eos智能合约执行 1. 执行流程 controller::push_transaction() // 事务 -> transaction_context::exec() // 事务 -&g ...
- eos 智能合约开发体验
eos编译安装 eos 特性 数据存储 eos投票智能合约开发 eos投票智能合约部署测试 注意避坑 eos编译安装 ERROR: Could not find a package configura ...
- EOS智能合约存储实例讲解
EOS智能合约存储实例 智能合约中的基础功能之一是token在某种规则下转移.以EOS提供的token.cpp为例,定义了eos token的数据结构:typedef eos::token<ui ...
随机推荐
- Error while executing: am start -n
单纯clean project是不行的,选择File-Invalidate Caches/Restart,清除缓存,重启AS Android NDK 是在SDK前面又加上了"原生" ...
- ECMAscript,DOM,BOM哪个比较重要
ECMA > DOM > BOM ECMA是JS的核心,语法.变量.对象.各种对象的API.作用域.原型链.闭包.This指向.构造函数等等必须要熟练,有了这些基础你才能去熟练的操作DOM ...
- docker日志设置定期清理
1.新建/etc/docker/daemon.json,若有就不用新建了 2.添加log-dirver和log-opts参数,样例如下 "log-driver":"jso ...
- Django 载入静态文件地址
1,Django框架中有专门存放静态文件的目录. 项目中的CSS.图片.js都是静态文件 配置静态文件 在settings 文件中定义静态内容 2,这些静态文件,他们统一存放在项目目录,templat ...
- modal 移除遮盖层
弹框关闭时 移除遮盖层 $("#modal").bind('hide.bs.modal',function(){ $(".modal-backdrop").re ...
- hdu-1878(欧拉回路)
题目链接:传送门 思路:就是判断无向图的欧拉回路的两个条件:(1)连通性(2)点的度数是偶数 注意:两个条件一同时满足才行. #include<iostream> #include< ...
- Linux下强制杀死进程的方法
常规篇: 首先,用ps查看进程,方法如下: $ ps -ef …… smx 1822 1 0 11:38 ? 00:00:49 gnome-terminal smx 1823 1822 0 11:38 ...
- Day03(黑客成长日记)
#猜数游戏 != 是不等于 # import random # secret = random.randint(,) # gwea = # tries = # : # guess = int(inpu ...
- Codeforces Round #486 (Div. 3) E. Divisibility by 25
Codeforces Round #486 (Div. 3) E. Divisibility by 25 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- 1131 Subway Map DFS解法 BFS回溯!
In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...