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 为:

    EOS踩坑记

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

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

  则 hello 账户的 abi 会变为:

  EOS踩坑记  

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

 

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

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

  EOS踩坑记

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

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

  EOS踩坑记

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

  EOS踩坑记

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

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

  EOS踩坑记

 

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,可以知道,它存的是一个账号。

  EOS踩坑记

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

  EOS踩坑记

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

  EOS踩坑记

  

8、symbol_code

  symbol_code 是一个 class.

    EOS踩坑记

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

    EOS踩坑记

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

 

9、symbol

  symbol 是一个class

    EOS踩坑记

  只包括一个成员变量

    EOS踩坑记

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

    EOS踩坑记

   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。

    EOS踩坑记

 

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) )
View Code

相关文章: