Dapp开发区块链研习社

EOS currency智能合约的那些坑

2018-03-12  本文已影响467人  钟晓宏

本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击《区块链研习社》

今天照着eos提供的currency智能合约,动手写自己的currency智能合约。
不动手的时候,觉得代码很简单,动手后,才知道有很多坑。

下面我带大家来踩坑:

坑1:使用eoscpp -g生成abi文件,生成的abi文件没有内容。

{
  "types": [],
  "structs": [],
  "actions": [],
  "tables": []
}

经过各种人眼和比较工具比较,仍然不知道两个头文件实质内容有啥区别。
最后,无奈,把注释添加上去,神奇的事情就发生了。

{
  "types": [],
  "structs": [{
      "name": "currency_tokens",
      "base": "",
      "fields": {
        "quantity": "uint64"
      }
    },{
      "name": "transfer",
      "base": "",
      "fields": {
        "from": "account_name",
        "to": "account_name",
        "quantity": "currency_tokens"
      }
    },{
      "name": "account",
      "base": "",
      "fields": {
        "key": "uint64",
        "balance": "currency_tokens"
      }
    }
  ],
  "actions": [{
      "action_name": "transfer",
      "type": "transfer"
    }
  ],
  "tables": [{
      "table_name": "account",
      "index_type": "i64",
      "key_names": [
        "key"
      ],
      "key_types": [
        "uint64"
      ],
      "type": "account"
    }
  ]
}

我的理解是这样的,EOS有意强制开发人员写注释。

坑2:abi文件和hpp文件对不上

EOS提供的currency智能合约中,abi文件和hpp文件是对不上的,这种不同主要体现在transfer结构体中quantity的类型。
先看一下abi文件:

{
      "name": "transfer",
      "base": "",
      "fields": {
        "from": "account_name",
        "to": "account_name",
        "quantity": "uint64"
      }

再看一下hpp文件:

   struct transfer {
      /**
      * account to transfer from
      */
      account_name       from;
      /**
      * account to transfer to
      */
      account_name       to;
      /**
      *  quantity to transfer
      */
      currency_tokens    quantity;
   };

我猜EOS的开发人员先通过eoscpp -g生成abi文件,再修改abi文件中quantity的类型。
为什么要这样修改呢?我猜是为了让命令直观易懂,改了之后,就可以用以下命令转账:

$ eosc push message currency transfer '{"from":"currency","to":"inita","quantity":50}' --scope currency,inita --permission currency@active

而我因为是自己写的智能合约,需要自己生成abi文件,结果就生成了上面展示的abi文件,在这种情况下,使用上面的命令行转账是会报错的:

Invalid cast from type 'uint64_type' to Object

之所以会报错,是因为我把一个数字(uint64_t类型)传入到一个currency_tokens类型的变量。
如果不手动修改abi文件,稍微修改可以上面的命令,就可以使用:

$ eosc push message currency transfer '{"from":"currency","to":"inita","quantity":{"quantity":50}}' --scope currency,inita --permission currency@active

也就是说,我有两种解决办法:
1、修改abi文件
2、修改命令行
之所以可以这么修改,或者说需要这么修改,是因为头文件中transfer结构体中quantity是一个currency_tokens类型的变量

   /**
   * Defines a currency token
   */
   typedef eosio::token<uint64_t,N(currency)> currency_tokens;

而eosio::token来源于eoslib/token.hpp,我们从eoslib/token.hpp可以看到quantity成员:

    /**
    * Quantity of tokens available
    * @brief Quantity of tokens available
    */
    NumberType quantity = 0;

此时,NumberType 就是uint64_t,这是自定义currency_tokens类型时传入的。
由于token结构体中的quantity成员也是uint64_t类型的,所以可以将abi文件中quantity的类型手动修改为uint64_t,这对应第一种解决办法。
我们也可以把transfer结构体中quantity成员当成一个自定义类型的成员,通过quantity.quantity来引用,这对应第二种解决办法。

下面是不脸打赏地址:

ERC20代币地址:0xdeF092bca8d9E093EAD79c967b11D5cA7b0f7a4A

image

EOS currency智能合约的那些坑

QYB(屈原币)地址:

QPA9RhmH5NVRFXARWex9hkyoZMVypLqqYR

image
上一篇 下一篇

猜你喜欢

热点阅读