EOS 智能合约最佳安全开发指南

原文:https://github.com/slowmist/eos-smart-contract-security-best-practices

这篇文档旨在为 EOS 智能合约开发人员提供一些智能合约的安全准则已知漏洞分析。我们邀请社区对该文档提出修改或完善建议,欢迎各种合并请求(Pull Request)。若有相关的文章或博客的发表,也请将其加入到参考文献中。

目录

安全准则

EOS 处于早期阶段并且有很强的实验性质。因此,随着新的 bug 和安全漏洞被发现,新的功能不断被开发出来,其面临的安全威胁也是不断变化的。这篇文章对于开发人员编写安全的智能合约来说只是个开始。

开发智能合约需要一个全新的工程思维,它不同于我们以往项目的开发。因为它犯错的代价是巨大的,很难像中心化类型的软件那样,打上补丁就可以弥补损失。就像直接给硬件编程或金融服务类软件开发,相比于 Web 开发和移动开发都有更大的挑战。因此,仅仅防范已知的漏洞是不够的,还需要学习新的开发理念:

  • 对可能的错误有所准备。任何有意义的智能合约或多或少都存在错误,因此你的代码必须能够正确的处理出现的 bug 和漏洞。需始终保证以下规则:
    • 当智能合约出现错误时,停止合约
    • 管理账户的资金风险,如限制(转账)速率、最大(转账)额度
    • 有效的途径来进行 bug 修复和功能提升
  • 谨慎发布智能合约。 尽量在正式发布智能合约之前发现并修复可能的 bug。
    • 对智能合约进行彻底的测试,并在任何新的攻击手法被发现后及时的测试(包括已经发布的合约)
    • 从 alpha 版本在麒麟测试网(CryptoKylin-Testnet)上发布开始便邀请专业安全审计机构进行审计,并提供漏洞赏金计划(Bug Bounty)
    • 阶段性发布,每个阶段都提供足够的测试
  • 保持智能合约的简洁。复杂会增加出错的风险。
    • 确保智能合约逻辑简洁
    • 确保合约和函数模块化
    • 使用已经被广泛使用的合约或工具(比如,不要自己写一个随机数生成器)
    • 条件允许的话,清晰明了比性能更重要
    • 只在你系统的去中心化部分使用区块链
  • 保持更新。通过公开资源来确保获取到最新的安全进展。
    • 在任何新的漏洞被发现时检查你的智能合约
    • 尽可能快的将使用到的库或者工具更新到最新
    • 使用最新的安全技术
  • 清楚区块链的特性。尽管你先前所拥有的编程经验同样适用于智能合约开发,但这里仍然有些陷阱你需要留意:
    • require_recipient(account_name name) 可触发通知,调用name合约中的同名函数,官方文档

已知漏洞

数值溢出

在进行算术运算时,未进行边界检查可能导致数值上下溢,引起智能合约用户资产受损。

漏洞示例

存在缺陷的代码:batchTransfer 批量转账

typedef struct acnts {
    account_name name0;
    account_name name1;
    account_name name2;
    account_name name3;
} account_names;

void transfer(symbol_name symbol, account_name from, account_names to, uint64_t balance)
{
    require_auth(from);
    account fromaccount;

    require_recipient(from);
    require_recipient(to.name0);
    require_recipient(to.name1);
    require_recipient(to.name2);
    require_recipient(to.name3);

    eosio_assert(is_balance_within_range(balance), "invalid balance");
    eosio_assert(balance > 0, "must transfer positive balance");

    uint64_t amount = balance * 4; //乘法溢出

    int itr = db_find_i64(_self, symbol, N(table), from);
    eosio_assert(itr >= 0, "Sub-- wrong name");
    db_get_i64(itr, &fromaccount, (account));
    eosio_assert(fromaccount.balance >= amount, "overdrawn balance");

    sub_balance(symbol, from, amount);

    add_balance(symbol, to.name0, balance);
    add_balance(symbol, to.name1, balance);
    add_balance(symbol, to.name2, balance);
    add_balance(symbol, to.name3, balance);
}

防御方法

尽可能使用 asset 结构体进行运算,而不是把 balance 提取出来进行运算。

真实案例

权限校验

在进行相关操作时,应严格判断函数入参和实际调用者是否一致,使用require_auth进行校验。

漏洞示例

存在缺陷的代码:transfer 转账

void token::transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );

    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

    auto payer = has_auth( to ) ? to : from;

    sub_balance( from, quantity );
    add_balance( to, quantity, payer );
}

防御方法

使用require_auth( from )校验资产转出账户与调用账户是否一致。

真实案例

暂无

apply 校验

在处理合约调用时,应确保每个 action 与 code 均满足关联要求。

漏洞示例

存在缺陷的代码:

// extend from EOSIO_ABI
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
      auto self = receiver; \
      if( action == N(onerror)) { \
         /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \
         eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \
      } \
      if( code == self || code == N(eosio.token) || action == N(onerror) ) { \
         TYPE thiscontract( self ); \
         switch( action ) { \
            EOSIO_API( TYPE, MEMBERS ) \
         } \
         /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
      } \
   } \
}

EOSIO_ABI_EX(eosio::charity, (hi)(transfer))

防御方法

使用

if( ((code == self  && action != N(transfer) ) || (code == N(eosio.token) && action == N(transfer)) || action == N(onerror)) ) { }

绑定每个关键 action 与 code 是否满足要求,避免异常调用。

真实案例

参考文献

致谢

  • 麒麟工作组
  • eosiofans
  • 荆凯(EOS42)
  • 星魂
  • 岛娘
  • 赵余(EOSLaoMao)
  • 字符

在麦子钱包发布了一个叫【EOS子弹消息】的DAPP

WechatIMG6301

花了1小时基于麦子钱包的 API 做的一个 DAPP

DAPP介绍

把一段内容写在备注里面,通过一次转账发送给多个好友,每条消息通过给好友转 0.0001 EOS 完成。

为什么做这个DAPP?

之前看到不少机构在通过这种方式做推广,普通用户还没有比较好用的工具,所以就在麦子上做了一个。
另外这种方式挺“区块链”的,第一、相比短信推广它的费用更低;第二、它的收益方是接受消息的用户而非中间商。

对接麦子钱包的心得体会

简单研究了一下麦子钱包的API,发现可以基于现成开源的【小协议】代码做修改,前端都没自己写,还是很方便的。

主要用到 EOS 支持一个 transaction 可以包含多个 action 的特点,具体代码已开源,有兴趣的可以访问 https://github.com/MediShares/mds-eosjs/tree/master/eos/sample06

WechatIMG2471

如何进行自动的延迟EOS转账

transaction 里面有一个 delay_sec 的参数,默认是0,可以通过自定义实现延迟EOS转账。

具体代码可以查看 contracts/eosiolib/transaction.hpp

我们通过写一个新的合约,实现延时转账的 send 功能


void send(account_name from, account_name to, asset amount, string memo, uint64_t delay) {
eosio::transaction t{};
t.actions.emplace_back(
eosio::permission_level(from, N(active)), // with `from@active` permission
N(eosio.token), // You're sending this to `eosio.token`
N(transfer),   // to their `transfer` action
std::make_tuple(from, to, amount, memo));  // with the appropriate args
t.delay_sec = delay; // Set the delay
t.send(eosio::string_to_name(memo.c_str()), from); // Send the transaction with some ID derived from the memo
}
};

最后需要记得对发送者账户进行权限设置,让该合约有权限进行转账操作。

$ cleos set account permission <sender-account> active '{"threshold": 1,"keys": [{"key": "<sender-pubkey>","weight": 1}],"accounts": [{"permission":{"actor":"<contract-account>","permission":"eosio.code"},"weight":1}]}' owner -p <sender-account>

参考:https://eosio.stackexchange.com/questions/1900/how-to-transfer-eos-after-a-particular-delay

EOS合约权限(二)- 如何检查 EOS 合约的安全性

开源,并能够验证开源代码与链上部署代码一致

比如 EOS.win 的代码就能够在 EOSpark 上查到,并已被 EOSpark 验证与链上部署代码一致
https://eospark.com/MainNet/contract/eosluckygame

慢雾科技也推出 EOS 合约验证平台,也可以做相应的查询和确认
https://eos.slowmist.io

代码安全性

EOS 代码安全性审计需要比较专业的背景知识,在合约层面一般的问题包括数值溢出漏洞、代码逻辑错误等。

权限

合约账户的权限能够控制对账户内金额转账,以及对合约进行升级,是非常重要的安全环节。目前主要有三种方法对权限进行限制。

方法一(低安全):多重签名账户

通过EOS账户体系的Weight和Threshold控制账户权限,实现由多人共同管理一个账户。假设该账户owner权限由5个不同的公钥控制,每个公钥的Weight为1,Threshold为3,表示需要这5个人中的3人进行签名,才能转账或修改合约代码,从而提升账户安全性。

参看 eosio.prods 的权限设置,就是使用这种方式 https://eospark.com/MainNet/account/eosio.prods
当然 eosio.prods 的参与者是所有当选的超级节点,公信力更高。

方法二(高安全):移交智能合约权限

修改合约权限为 eosio.prods 账户,意味着将修改合约的权限交给21个超级节点,如果需要转移资金或修改合约,需要申请节点仲裁。
使用 updateauth 命令可以进行权限的修改:

$ cleos push action eosio updateauth '{"account": "eosio", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@owner
$ cleos push action eosio updateauth '{"account": "eosio", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@active

参看 eosio 的权限设置,就是使用这种方式 https://eospark.com/MainNet/account/eosio

方法三(高安全):设置账户权限到一个黑洞公钥

将owner和active权限设置为一个没有人知道私钥的公钥地址(黑洞),即可保证没有人可以获得账户的实际控制权。比如 EOS1111111111111111111111111111111114T1Anm,它的公钥是0值加检验数据生成,任何人都不知道它的私钥。

以下一些最近的热门游戏合约,供大家学习研究用:

狼人
https://eosflare.io/account/eosfoiowolfs

ITE
https://eosflare.io/account/itedeathstar

EOS Bet
https://eostracker.io/accounts/eosbetdice11

EOS核心仲裁庭收费标准

请注意: 本文由EMAC(EOS 华语治理社区)仲裁候选人Achilles原创翻译,保留该声明即可转载。

原文来源:https://steemit.com/ecaf/@ecaf/ecaf-s-fee-schedule

EOS核心仲裁庭费用表

本费用表适用于在EOS核心仲裁庭(ECAF)的争议解决机制(RDR)之下进行的仲裁,详情请参见此处https://eoscorearbitration.io/home/governance/

本费用表将会不定期的修订。ECAF的费用将以EOS的形式收取。如果需要从法币转换为EOS,操作过程在本备忘录末尾的货币转换部分做了详细说明。

该收费制度分为两部分,如下:

1.不可退还的诉讼费:在提交案件时支付。

2.仲裁费用:在案件结案时支付,用于补偿仲裁员、案件管理员、仲裁庭工作人员、外部专家等在案件上花费的时间成本。

注:费用与仲裁员针对潜在的判决可能要求当事人作为担保缴纳的任何保证金是分开的。

诉讼费:

当提交仲裁申请时,申请人应支付不可退还的诉讼费,该费用取决于索赔金额,具体如下:

ecaf001

仲裁费用

根据RDR第5.9节https://eoscorearbitration.io/home/governance/ :当仲裁程序开始,仲裁员将在切实可行的范围内尽快的提交一份仲裁费用的估算。

该仲裁费用将固定使用在仲裁上并且将被支付到本法庭账户。

这样的花费可能包括:

1、仲裁员的报酬;

2、仲裁员的花费;

3、专家和翻译的成本;

4、其它与本法庭审理该案件相关的报酬和花费;

5、当事人引发的合理的法律费用和其它花费;

6、由于消极的行动或行为被仲裁员征收的罚金;

7、任何与临时或者紧急救济通知有关的费用;

8、任何与请求合并仲裁有关的费用;

仲裁费用应参照仲裁庭成员的工作量计算。费率将取决于案件的具体情况,包括其复杂性和仲裁员可能具有的任何特殊资质。

费用将按小时收取,如下文(数字以美元报价,但以EOS收取,见后文关于货币兑换的部分)。适用的费率将取决于经验水平和本人对问题的专业程度。

ecaf002

保证金

仲裁员可指示当事人按其认为适当的比例和时间提交两种类型的保证金:

1.仲裁费用的预付款。根据ECAF规则,此类由当事人预付的保证金可以由ECAF用来支付任何此类仲裁费用(包括ECAF自己的费用和开支)。

2.占争议总金额一定百分比的保证金,作为对潜在判决的担保。

如果一方当事人未能或者拒绝支付任何款项到仲裁员指示的仲裁费用的账号,仲裁员可指示另一方或多方代为支付以允许仲裁继续进行(基于任何针对仲裁费用的仲裁令或裁定)。在这种情况下,代为付款的一方可以要求仲裁员给出一个命令或裁决,以便将该金额作为违约方的一笔立即到期债务和应付账款,来进行收回。

一方当事人申请紧急救济时,除了支付不可退还的诉讼费之外,还应支付相当于750美元的EOS的保证金(见后文关于货币兑换的说明)作为紧急救济程序的预付费用。如果没有同时支付诉讼费和保证金,ECAF将不会以紧急救济程序进行处理。

临时付款

随着仲裁程序的进行,由ECAF和仲裁员批准,部分保证金可能会不时地被释放,以覆盖仲裁费用的任何部分。

如果在需要临时付款时没有或欠缺资金,付款通知可以被提交给当事人直接进行付款。

支付方式

ECAF只会要求您将资金转入以下两个账户之一:

ecafeewallet
ecafescrowww

警告:不要将资金转移到任何其他帐户!任何向其他EOS帐户或交易所帐户付款的请求都是欺诈性请求! ECAF不会对转入其它账户的资金承担责任。

诉讼费的收取

申请人将通过ECAF官方网址的诉讼提交页面提起一个诉讼:https://eoscorearbitration.io/file-a-claim/

ECAF的案例经理随后将审核该诉讼。一旦案件经理确信不需要其他补充信息,他们将联系申请人提交诉讼费并附上适当的备注到以下地址:

Ecafeewallet

一旦成功收到诉讼费,该案件将被标记为已被仲裁庭接受,并等待分配给具体的一个仲裁员。

保证金的收取

当仲裁员被分配到一个案件时,他们将对仲裁费用进行初步估计。 (该估计将在结案时最终确定。)

仲裁员可以随后指示案件管理员将本案件的这些费用通知当事人。仲裁员还将确定是否需要要求一笔保证金来覆盖部分仲裁费用以及作为争议金额的保证金。

保证金将由案件经理负责征收,并将存入ECAF的托管账户,同时附有将提供给当事人的备注。保证金必须只能发送到以下这个账户:

Ecafescrowww

货币兑换

金额必须以EOS的形式支付。

如果任何到期金额没有以EOS为单位报价,则应按保证金和/或裁定的付款通知发出之日前一天的兑换率进行兑换。
EOS转换为美元使用的利率引用自CoinMarketCap https://coinmarketcap.com/currencies/eos/historical-data/ 在指定日期的收盘价。

如果该金额以美元以外的法定货币表示,则该金额应首先使用引用自OandA https://www.oanda.com/lang/cns/currency/converter/ 的在指定日期的平均卖出价,来转换为美元。然后再将其转换为如上所述的EOS单位。

全文完。

EOS 错误码整理

EOS 目前大约有180种错误类型,虽然有错误码,但是还是很笼统的,具体的报错信息还得看detail里面的内容
一、常见的错误码以及issue上对应的错误记录

3010001 Invalid name
账户名格式1-12位(a-z,1-5,“.” ) 且”.”不能在首尾
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3010001

3010004 Invalid authority
检查 authorization”: [{
“actor”: “accountname1”,
“permission”: “active”
}] 参数是否填写正确
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3010004

3010008 Invalid block ID
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3010008

3010010 Invalid packed transaction
一般报这个错误就是打包交易的参数传的不正确
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3010010

3010011 Invalid asset
检查资产格式是否正确
如”stake_net_quantity”:”0.0001 EOS” 1.确保正确的精度 空格加Symbol
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3010011

3030000 Block exception
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3030000

3030001 Unlinkable block
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3030001

3030002 Transaction outputs in block do not match transaction outputs from applying block
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3030002

3030003 Block does not guarantee concurrent execution without conflicts
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3030003

3030008 Block is not signed with expected key
检查是否对块信息签名
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3030008

3040000 Transaction exception
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3040000

3040002 Transaction should have at least one normal action
查看action是否添加,是否正确
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3040002

3040005 Expired Transaction
交易过期,过期时间可以设置长一点
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3040005

3040006 Transaction Expiration Too Far
过期时间设置太长

3040007 Invalid Reference Block
引用块无效或不匹配,节点间不同有关
https://github.com/EOSIO/eos/issues/4659

3050000 Action validate exception
检查Action是否正确
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3050000

3050001 Account name already exists
账户名已存在

3050002 Invalid Action Arguments
检查Action参数
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3050002

3050003 eosio_assert_message assertion failure
账户不存在,资产金额不正确等

3060003 Contract Table Query Exception
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3060003

3060004 Contract Query Exception
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3060004

3070002 Runtime Error Processing WASM
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3070002

3080001 Account using more than allotted RAM usage
内存不足,买些内存

3080002 Transaction exceeded the current network usage limit imposed on the transaction
网络资源不足,抵押一些资源

3080004 Transaction exceeded the current CPU usage limit imposed on the transaction
CPU不足,抵押一些CPU

3080006 Transaction took too long
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3080006+

3081001 Transaction reached the deadline set due to leeway on account CPU limits
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3081001

3090003 Provided keys, permissions, and delays do not satisfy declared authorizations
检查权限,签名等是否正确
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3090003

3090004 Missing required authority
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3090004

3110001 Missing Chain API Plugin
https://github.com/EOSIO/eos/issues?utf8=%E2%9C%93&q=3110001

二、EOS 错误码大全

3000000 blockchain exception
3010001 Invalid name
3010002 Invalid public key
3010003 Invalid private key
3010004 Invalid authority
3010005 Invalid action
3010006 Invalid transaction
3010007 Invalid ABI
3010008 Invalid block ID
3010009 Invalid transaction ID
3010010 Invalid packed transaction
3010011 Invalid asset
3010012 Invalid chain ID
3010013 Invalid fixed key
3010014 Invalid symbol
3020000 Fork database exception
3020001 Block can not be found
3030000 Block exception
3030001 Unlinkable block
3030002 Transaction outputs in block do not match transaction outputs from applying block 交易不匹配
3030003 Block does not guarantee concurrent execution without conflicts
3030004 Shard locks in block are incorrect or mal-formed
3030005 Block exhausted allowed resources
3030006 Block is too old to push
3030007 Block is from the future
3030008 Block is not signed with expected key
3030009 Block is not signed by expected producer
3040000 Transaction exception
3040001 Error decompressing transaction
3040002 Transaction should have at least one normal action
3040003 Transaction should have at least one required authority
3040004 Context-free action should have no required authority
3040005 Expired Transaction
3040006 Transaction Expiration Too Far
3040007 Invalid Reference Block
3040008 Duplicate transaction
3040009 Duplicate deferred transaction
3040010 Context free action is not allowed inside generated Transaction
3040011 The transaction can not be found
3040012 Pushing too many transactions at once
3040013 Transaction is too big
3040014 Unknown transaction compression
3050000 Action validate exception
3050001 Account name already exists
3050002 Invalid Action Arguments
3050003 eosio_assert_message assertion failure
3050004 eosio_assert_code assertion failure
3050005 Action can not be found
3050006 Mismatch between action data and its struct
3050007 Attempt to use unaccessible API
3050008 Abort Called
3050009 Inline Action exceeds maximum size limit
3060000 Database exception
3060001 Permission Query Exception
3060002 Account Query Exception
3060003 Contract Table Query Exception
3060004 Contract Query Exception
3060100 Database exception
3060101 Database usage is at unsafe levels
3060102 Reversible block log usage is at unsafe levels
3070000 WASM Exception
3070001 Error in WASM page memory
3070002 Runtime Error Processing WASM
3070003 Serialization Error Processing WASM
3070004 memcpy with overlapping memory
3070005 binaryen exception
3080000 Resource exhausted exception
3080001 Account using more than allotted RAM usage
3080002 Transaction exceeded the current network usage limit imposed on the transaction
3080003 Transaction network usage is too much for the remaining allowable usage of the current block
3080004 Transaction exceeded the current CPU usage limit imposed on the transaction
3080005 Transaction CPU usage is too much for the remaining allowable usage of the current block
3080006 Transaction took too long
3080007 Transaction exceeded the current greylisted account network usage limit
3081001 Transaction reached the deadline set due to leeway on account CPU limits
3090000 Authorization exception
3090001 Duplicate signature included
3090002 Irrelevant signature included
3090003 Provided keys, permissions, and delays do not satisfy declared authorizations
3090004 Missing required authority
3090005 Irrelevant authority included
3090006 Insufficient delay
3090007 Invalid Permission
3090008 The action is not allowed to be linked with minimum permission
3090009 The parent permission is invalid
3100000 Miscellaneous exception
3100001 Internal state is no longer consistent
3100002 Unknown bloc
3100003 Unknown transaction
3100004 Corrupted reversible block database was fixed
3100005 Extracted genesis state from blocks.log
3100006 Subjective exception thrown during block production
3100007 Multiple voter info detected
3100008 Feature is currently unsupported
3100009 Node management operation successfully executed
3110000 Plugin exception
3110001 Missing Chain API Plugin
3110002 Missing Wallet API Plugin
3110003 Missing History API Plugin
3110004 Missing Net API Plugin
3110005 Missing Chain Plugin
3110006 Incorrect plugin configuration
3120000 Wallet exception
3120001 Wallet already exists
3120002 Nonexistent wallet
3120003 Locked wallet
3120004 Missing public key
3120005 Invalid wallet password
3120006 No available wallet
3120007 Already unlocked
3120008 Key already exists
3120009 Nonexistent key
3120010 Unsupported key type
3120011 Wallet lock timeout is invalid
3120012 Secure Enclave Exception
3130000 Actor or contract whitelist/blacklist exception
3130001 Authorizing actor of transaction is not on the whitelist
3130002 Authorizing actor of transaction is on the blacklist
3130003 Contract to execute is not on the whitelist
3130004 Contract to execute is on the blacklist
3130005 Action to execute is on the blacklist
3130006 Public key in authority is on the blacklist
3140000 Exceptions that are allowed to bubble out of emit calls in controller
3140001 Block does not match checkpoint
3150000 ABI exception
3150001 No ABI found
3150002 Invalid Ricardian Clause
3150003 Invalid Ricardian Action
3150004 The type defined in the ABI is invalid
3150005 Duplicate type definition in the ABI
3150006 Duplicate struct definition in the ABI
3150007 Duplicate action definition in the ABI
3150008 uplicate table definition in the ABI
3150009 Duplicate error message definition in the ABI
3150010 ABI serialization time has exceeded the deadline
3150011 ABI recursive definition has exceeded the max recursion depth
3150012 Circular definition is detected in the ABI
3150013 Unpack data exception
3150014 Pack data exception
3160000 Contract exception
3160001 The payer of the table data is invalid
3160002 Table access violation
3160003 Invalid table iterator
3160004 Table can not be found inside the cache
3160005 The table operation is not allowed
3160006 Invalid contract vm type
3160007 Invalid contract vm version
3160008 Contract is already running this version of code
3160009 No wast file found
3160010 No abi file found
3170000 Producer exception
3170001 Producer private key is not available
3170002 Pending block state is missing
3170003 Producer is double confirming known rang
3170004 Producer schedule exception
3170006 The producer is not part of current schedule
3180000 Reversible Blocks exception
3180001 Invalid reversible blocks directory
3180002 Backup directory for reversible blocks already existg
3180003 Gap in the reversible blocks database
3190000 Block log exception
3190001 unsupported version of block log
3190002 fail to append block to the block log
3190003 block log can not be found
3190004 block log backup dir already exists
3200000 http exception
3200001 invalid http client root certificate
3200002 invalid http response
3200003 service resolved to multiple ports
3200004 fail to resolve host
3200005 http request fail
3200006 invalid http request
3210000 Resource limit exception
3220000 Mongo DB exception
3220001 Fail to insert new data to Mongo DB
3220002 Fail to update existing data in Mongo DB
3230000 Contract API exception
3230001 Crypto API Exception
3230002 Database API Exception
3230003 Arithmetic Exception

EOS合约权限(一)- FOMO3D和其山寨的EOS版本

fomo3d

FOMO3D这游戏超魔性,虽然它是以太坊的。

既然我们是EOS博客,先说说 F3D 和 EOS 可能的关联。

Fomo3D的好处很明显:可以帮助锁仓、增加用户数、拉升链上交易活跃度。尤其是EOS有这么多中国玩家,配合国人搏一把心态,加上EOS网络速度,很难不爆发。
而且已经有人做了一个受F3D启发的EOS DAPP出来了,虽然玩法上还不够精致 https://eosbutton.io/

不过EOS合约有个毛病,可以随时改,不像eth合约无法被人控制,就算上了EOS智能合约还是可以卷款跑路。

(2018/07/27 更新:上面的说法不准确,社群里面也收到不少反馈,准确来说EOS的权限设置很灵活,合约可以修改也可以不能修改,如果把合约账户的owner和active设为空,或者没人知道私钥的密钥,或者由超级节点多签的账户,则可以理解为合约将无法修改。另外一点就是升级合约只能改动代码逻辑部分,合约中数据是不能改的,如果要改还需要专门写Action,这是一个很大的话题。)

官网
http://exitscam.me/

官方教程 – 英文
https://fomo3d.hostedwiki.co/

ETH 合约地址
https://etherscan.io/address/0xa62142888aba8370742be823c1782d17a0389da1#code

团队自己直接开发了一个去中心交易所,可以随时买卖P3D:
https://exchange.powh.io/purchase-tokens

中文攻略
https://bihu.com/article/972045
https://bihu.com/article/988957
https://bihu.com/article/1005669

用麦子钱包APP玩FOMO3D说明
https://mp.weixin.qq.com/s/vbWvwLmZZxVFTMc1y2u12w
http://mathwallet.org/

彩蛋:
https://mp.weixin.qq.com/s?__biz=MzU1OTQ3MTI3Ng==&mid=2247484008&idx=1&sn=017ae144c895b80fe0cc7aec641c839d
https://mp.weixin.qq.com/s/FrwzjoP-8vUytEyXlpANpQ
https://mp.weixin.qq.com/s?__biz=MzU0ODg3Mjk2Mw==&mid=2247483809&idx=1&sn=6259ecc668d3e37d398b1371ad00075e

名词解释:
Exitscam – 逃离骗局
Bad advice – 坏的建议
Fomo3D – FOMO – Fear of missing out 害怕踏空
Key – 打开大奖的钥匙
P3D – PoWH3D – Proof of Weak Hands 缺乏投资信念、心理素质极差、特别怂的那类投资者

2018/07/27 更新:

事件后续,果然有个团队做了一个叫做狼人的EOS版本出来(网址:https://eosfo.io/),然后出了本文刚开始说到问题,目前正在由EMAC仲裁,EOS作为一条治理型区块链,真是一个很有趣的社会实验
该狼人EOS游戏被黑事件经过:
https://bihu.com/article/1007040

先写第一篇,介绍大概背景,感觉这个可以写一个系列。

EOS内存投机和资源模型

在美国呆了一周,回来发现整个群风向都变了,RAM投机这事真是毒害不浅

从技术角度,个人觉得有三个方向其实可以研究:

1 BM设计的跨链通讯的理论基础–Merkle证明已经得到证实。BM在Dawn3.0和Dawn4.0之间大幅修改了原先的跨链设计,这里面有很多机会可以研究
https://steemit.com/eos/@dan/inter-blockchain-communication-via-merkle-proofs-with-eos-io

2 Evolution团队这两天也对内存资源模型提出了自己的设计,Evolution会做一条和主网并行但交叉的主网,对主网进行扩容
https://hackernoon.com/solving-ram-speculation-property-rights-in-eos-631ca10c1970

3 EOS原力团队,作为国内的EOS团队,重写了EOS资源模型,使用了与ETH类似的手续费模式,其尝试和探索个人觉得是值得鼓励的。
https://www.eosforce.io/?lang=Cn

EOS MongoDB支持

好消息!EOSIO开始有分支重新支持MongoDB了,兼容现有主网。链接:https://github.com/EOSIO/eos/pull/4304
操作步骤如下:
        git clone -b release/1.1 https://github.com/EOSIO/eos.git
        cd eos
        git fetch –all –tags –prune
        git merge -m “merge” –commit origin/gh#3030-enable-mongodb
        git submodule update –init –recursive
        ./eosio_build.sh
        cd build/
        make install
修改config.ini配置文件,添加如下两行:
        plugin = eosio::mongo_db_plugin
        mongodb-uri = mongodb://localhost:27017/eosmain
其中,eosmain是要写入的MongoDB数据库名。
好了,万事俱备,开始启动
进入~/opt/mongodb/bin目录,启动MongoDB服务。
        cd ~/opt/mongodb/bin
        ./mongod
这时MongoDB服务会默认监听27017端口,如下图所示。
        新开一个小窗,重启nodeos,需要加上–replay-blockchain,以使历史交易数据同步到MongoDB。
        如果没有意外的话,此时MongoDB应该开始写入相关记录了。
        执行mongo程序进入MongoDB控制台,查询相应数据库和记录,如下图。
        本文完。

EOS账户与公私钥的关系

        昨天晚上在创建EOS账户的时候发现之前遗漏掉没有关注的point,现在的EOS账户只能通过已有的账户帮忙创建新的账户,在通过某钱包微信群花了40大洋帮忙注册了之后(后来知道现在EOS账户的创建成本大概在二十几块),在办公室找同事场外买了两个EOS就开始尝试自己创建的账户(花钱创建的暂且称为账户A,新创建的账户称为账户B)。刚开始在网页上使用Chrome的插件Scatter和https://www.eostoolkit.io/create,但是总是提示失败,失败如图

        So,最后还是用回某P钱包,结果问题就来了,在创建钱包的时候,不小心把Active Key 填成了账户A的Public Key, Owner Key 仍然填写的账户B的Public Key。这就创建完成了,当时没在意,后面当我把账户A的EOS转入到账户B后,在想转出去的时候就完蛋了,提示“没有授权”,开始以为是RAM、CPU和NET不够,购买和抵押的时候仍然提示我“没有授权”,我当时的表情就是黑人问号脸,痛定思痛,后来鼓起勇气把Owner Key也改成了账户A的Public Key,结果钱包就提示我此账户已经没用了,要不要删除钱包,WTF?!当时我就慌了,身家性命都在这儿了,提示我删除?不管了,抱着试试的心态删掉了,重新导入账户A的Public Key,神奇的事情发生了,这个时候钱包其实我选择进入账户A还是账户B,果断进入账户B,币还在!真是柳暗花明又一村,轻舟已过万重山。

        至此,才想起来EOS的账户设计,首先,账户B虽然是通过账户A创建的,但其实账户A和账户是平行关系,而不是母子关系。其次,同一个公钥可以对应多个账户,并且账户A和账户B是平行关系,对于子账户没有限制。我想,这大概才是EOS好玩的地方吧,哈哈哈