EOS踩坑记

1、每个account只能更新自己的contract,即使两个account的秘钥相同,也不允许

  如下,使用alice的权限来更新james的contract。会返回 Missing required authority错误。

cleos set contract james /home/ubuntu/contracts/hello/jameshello -p alice@active

  应该改为:

cleos set contract james /home/ubuntu/contracts/hello/jameshello -p james@active

2、contract class 名可以与 account 名不一致。如,以下调用是OK的。

cleos set contract james /home/ubuntu/contracts/hello/xhello -p james@active

3、一个account只能有一个contract。

  例如,hello 账户有一个hi函数,set contract,此时abi 为:

    

  此时,有一个xhello contract,内含一个 hi2 函数,将xhello合约提交。

cleos set contract hello /home/ubuntu/contracts/hello/xhello -p hello@active

  则 hello 账户的 abi 会变为:

    

  可以看见,原有的hi action不见了。

4、contract class 名、目录名、文件名必须一致

  1)如下,文件名为hello,目录名为xhello,两者不一致。

  

cleos set contract james /home/ubuntu/contracts/hello/xhello -p james@active

  执行后,会返回找不到文件错误。

  

  2)如下,contract class名为 jameshello,而目录名为hello。

  

cleos set contract james /home/ubuntu/contracts/hello/hello -p james@active

  虽然可以成功发布合约,但合约的abi是空的,也就是实际等于没有发布成功。

  

5、任意account都有权调用他人的contract。如,下面用bob的权限调用james的hi action,是合法的,不论两者的公钥是否相同。

cleos push action james hi '["bob"]' -p bob@active

6、require_auth(name n)

  Verifies that @ref name exists in the set of provided auths on a action. Fails if not found.

  检测name是否在通过-p提供的名单里。

  可以用于限制每个account在调用action时,只能修改自身相关信息。例如:

[[eosio::action]]
void hi( name user )
{
require_auth(user);
print("Hello, ", user);
}

7、contract 类中的 get_self()方法、_self。

  1)_self 是 contract 类的一个 protected member,其类型为 name,可以知道,它存的是一个账号。

  

  2)_self的赋值来源于 receiver,所以_self就是receiver。

  

  3)get_self() 返回的就是 _self,也就是receiver,也就是一个account。

  

  

8、symbol_code

  symbol_code 是一个 class.

    

  只含有一个 uint64_t value 成员变量。

    

  symbol_code 将长度为7以内(包括7)的字符串 encode 为 uint64_t value。(注意 uint64_t可以存储8个byte)

9、symbol

  symbol 是一个class

    

  只包括一个成员变量

    

  通过构造函数可以看到 symbol可以存储8个Byte,上文的symbol_code使用了7个Byte,所以symbol可以将symbol_code存储在自身,并且额外加了一个precision字段。

    

  symbol_code 指的是 TOKEN Name,如DICE、EOS。

   precision 指的是一个TOKEN的精度,比如 100000000.0000,上限是1亿,precision是4。

10、asset

  下面的命令可以调用 eosio.token 的action,创建一个新的TOKEN.

cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active

  而 asset 代表的就是 "1000000000.0000 SYS"。

  asset 是一个class。他只有2个成员变量,amount对应上述命令的 1000000000.0000, 而symbol则代码SYS,以及精度4。

    

11、multi_index

  multi_index 是一个class,意为可以包含多个索引的table。eosio.cdt源码中有一个完整的示例:

 *  #include <eosiolib/eosio.hpp>
* using namespace eosio;
* class mycontract: contract {
* struct record {
* uint64_t primary;
* uint64_t secondary_1;
* uint128_t secondary_2;
* uint256_t secondary_3;
* double secondary_4;
* long double secondary_5;
* uint64_t primary_key() const { return primary; }
* uint64_t get_secondary_1() const { return secondary_1; }
* uint128_t get_secondary_2() const { return secondary_2; }
* uint256_t get_secondary_3() const { return secondary_3; }
* double get_secondary_4() const { return secondary_4; }
* long double get_secondary_5() const { return secondary_5; }
* };
* public:
* mycontract(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds){}
* void myaction() {
* auto code = _self;
* auto scope = _self;
* multi_index<"mytable"_n, record,
* indexed_by< "bysecondary1"_n, const_mem_fun<record, uint64_t, &record::get_secondary_1> >,
* indexed_by< "bysecondary2"_n, const_mem_fun<record, uint128_t, &record::get_secondary_2> >,
* indexed_by< "bysecondary3"_n, const_mem_fun<record, uint256_t, &record::get_secondary_3> >,
* indexed_by< "bysecondary4"_n, const_mem_fun<record, double, &record::get_secondary_4> >,
* indexed_by< "bysecondary5"_n, const_mem_fun<record, long double, &record::get_secondary_5> >
* > table( code, scope);
* }
* }
* EOSIO_DISPATCH( mycontract, (myaction) )

   第一个参数是拥有这张表的account,第二个参数是 scope。

    

  find参数可以用来根据主键查找。

    

  下面是 eosio.token 中的使用代码:

     stats statstable( _self, sym.code().raw() );
auto existing = statstable.find( sym.code().raw() );
eosio_assert( existing == statstable.end(), "token with symbol already exists" ); statstable.emplace( _self, [&]( auto& s ) {
s.supply.symbol = maximum_supply.symbol;
s.max_supply = maximum_supply;
s.issuer = issuer;
});

12、SEND_INLINE_ACTION

  SEND_INLINE_ACTION 是eosio.cdt的action.hpp中定义的一个宏.

    

  在 eosio.token 中的使用如下:
    

  第一个参数是 account(也即 contract),第二个参数是 action name,第三个参数是权限。之后的参数全部传递给 action。

  可以看一下 transfer 函数的原型。

    

13、require_recipient

  这个方法用于通知 notify_account,当前调用方法以某些参数被调用。

    

  例如,在transfer(from,to,quantity,memo)中调用了

    require_recipient(from)

    require_recipient(to)

  则from、to分别会拥有一条执行了transfer() action的记录:

    

  这只是一条记录,并不说明 transfer被多执行了两次。

    

14、multi_index 中的 scope

  multi_index 类似于数据库中的Table,struct 定义了Row的结构。

  为了提升多线程读写性能,eos加入了 scope概念,scope是一个 uint64_t。一个scope下包含多个row。所以形成了 Table-Scope-Row 的结构。

    

  在 eosio.token 示例中,分别使用 symbol.code().raw() 作为 scope,以及使用 owner.value 账户名作为 scope。

  从第2个索引起,the name is less important as you will pass the getter name into the typedef.

15、code 是发布合约的account. 详情参考[3]

16、permission_level  

  permission_level 是一个 struct,只包含 name actor; name permission; 两个字段。

   

17、eosio.code

  面临的问题:

    比如alice调用智能合约contract1.test,一开始alice看过contract1.test的逻辑,发现它只是一个打印函数,并不会调用其他合约。所以alice以自己active的权限alice@active去执行contract1.test。

    但是contract1的拥有者某一天可能偷偷更改了test的实现,在test函数中调用eosio.token的transfer函数以alice@active权限就可以取走alice的EOS.

  解决方案:

    为了解决权限乱用问题,EOS新增了eosio.code这个特殊权限。采用eosio.code后,contract1.test要以alice@active去调用eosio.token,必须得到alice的授权,即必须在alice@active里添加contrac1@eosio.code授权.

$cleos set account permission alice active '{"threshold": 1,"keys": [{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":1}],"accounts": [{"permission":{"actor":"contract1","permission":"eosio.code"},"weight":1}]}' owner -p alice@owner

  account_1:alive : 1 account_2@eosio.code 的含意为:当account_1调用account_2的合约代码时,account_2可以以account_1.alive 权限去调用外部 contract action.

  更详细资料可见[参考4].

18、The primary key of the object in the eosio::multi_index container must be a unique unsigned 64-bit integer. The objects in the eosio::multi_index container are sorted by the primary key index in ascending order of the unsigned 64-bit integer primary key.

  

  A key differentiator of the EOSIO persistence services over other blockchain infrastructures is its Multi-Index iterators. Unlike some other blockchains that only provide a key-value store, EOSIO Multi-Index tables allow a contract developer to keep a collection of objects sorted by a variety of different key types, which could be derived from the data within the object. This enables rich retrieval capabilities. Up to 16 secondary indices can be defined, each having its own way of ordering and retrieving table contents.

19、eosio.system

  eos区块链启动时,默认有一个eosio account,该账户默认会 set eosio.system contract.

  通过执行以下命令,可以看到 eosio是有 setcode、setabi 等 eosio.system中的action的。

cleos get abi eosio

  

20、eosio.bios

  In a public blockchain, this contract will manage the staking and unstaking of tokens to reserve bandwidth for CPU and network activity, and memory for contracts.

21、eosio::history_api_plugin

  nodeos 启动时只有加载了这个插件,才能执行 get accounts pub-key 命令.

cleos get accounts EOSXXXXXXXXXXXXXXXXXXXX

  详细见参考[6].

22、Future versions of this contract may allow other parties to buy symbol names automatically.

  EOS的SYMBOL未来将会采取体售卖的形式。

23、

参考:

1、https://developers.eos.io/eosio-home/docs/your-first-contract

2、https://developers.eos.io/eosio-home/docs/token-contract

3、https://developers.eos.io/eosio-home/docs/data-persistence

4、https://blog.csdn.net/itleaks/article/details/80557560

5、https://developers.eos.io/eosio-cpp/docs/db-api

6、https://developers.eos.io/eosio-cpp/docs/introduction-to-smart-contracts

EOS踩坑记的更多相关文章

  1. EOS踩坑记 2

    [EOS踩坑记 2] 1.--contracts-console 在开发模式下,需要将 nodeos 添加此选项. 2.Debug Method The main method used to deb ...

  2. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  3. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  4. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  5. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  6. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  7. djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记

    情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...

  8. HttpWebRequest 改为 HttpClient 踩坑记-请求头设置

    HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...

  9. vue踩坑记

    vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...

随机推荐

  1. nodeJS网络操作

    var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, ...

  2. 创建java类并实例化类对象

    创建java类并实例化类对象例一1.面向对象的编程关注于类的设计2.设计类实际上就是设计类的成员3.基本的类的成员,属性(成员变量)&方法 面向对象思想的落地法则一:1.设计类,并设计类的成员 ...

  3. MySQL8.0 关闭二进制日志

    Binary logging is enabled by default (the log_bin system variable is set to ON). The exception is if ...

  4. centos7以rpm方法装mysql5.7及大坑

    环境: CentOS Linux release 7.5.1804 (Core)   Mysql版本: MySQL-5.7.17-1.el6.x86_64.rpm-bundle.tar   下载地址( ...

  5. MongoDB的启动与停止(一)

    1:启动和停止Mongodb    1)从命令行启动      执行mongod,启动MongoDB服务器,mongod有很多可配置的启动选项,可以使用mongod --help查看所有选项   -- ...

  6. Guava 12:Guava EventBus源码剖析

    一.架构速读 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus不是通用型的发布-订 ...

  7. mongo数据的导入(mongoimport)和导出(mongoexport)

    1.导出数据可以使用命令: mongoexport -h dbhost -d dbname -c collectionName -o output 参数说明: -h 数据库地址 -d 指明使用的库 - ...

  8. Python递归解压缩多级.zip压缩包

    参考如下代码(from:https://stackoverflow.com/questions/36285502/how-to-extract-zip-file-recursively-in-pyth ...

  9. Linux系统挂载新磁盘

    执行df -h 查看已挂载磁盘 未能找到挂载磁盘 1)使用fdisk -l命令查看主机上的硬盘 红圈标志为后挂载的磁盘未能挂载 2)使用mkfs.ext4命令把硬盘格式化: mkfs.ext4 /de ...

  10. 【C++】vector内存机制和性能分析

    转自:https://blog.csdn.net/mfcing/article/details/8746256 一些好的公司校园招聘过程中(包括笔试.面试环节),经常会涉及到STL中vector的使用 ...