EOS智能合约安全终极指南

EOS,世界上最大的ICO,EOS于2018年6月推出时,加密社区变得持怀疑态度,并且由于软件错误而被冻结了2天。但快进4个月,EOS今天占了以太网今天所做交易的两倍以上。通过免费和更快速交易的承诺,EOS最顶级的Dapp拥有大约13,000个每日活跃用户,而以太网的最顶级Dapp只有2,000个。

一些常见的智能合约漏洞几乎适用于所有平台。与以太坊一样,在EOS上编写的智能合约需要在主网上上线之前进行审核,合同中的致命错误可以在合同没有经过足够的战斗时被利用。

在阅读之前,了解有关EOS开发的一些先决条件信息非常重要,这些信息在您阅读本指南时会很方便。了解C ++是必须的。开始智能合约开发的最佳位置是EOSIO。

处理ABI调度员

上图是修改后的ABI调度程序的示例代码。如下所示的更简单的ABI调度程序用于简化合同的操作处理。

ABI调度员/转发器允许合同收听传入的eosio.token转移事件,以及与智能合约的正常交互。为了避免异常和非法调用,绑定每个键操作和代码以满足要求是很重要的。

一个例子是由于他们的ABI转发源代码中的错误而发生在dApp EOSBet Casino上的黑客攻击。

上面检查ABI转发源代码的apply 动作处理程序允许攻击者完全绕过eosio.token :: transfer()函数,并在放置之前直接调用contract :: transfer()函数而不将EOS转移到合同中。打赌,对于损失,他没有得到任何报酬,但一无所获。然而,对于胜利,他从合同中支付了真正的EOS。

他们通过在传入的操作请求合同之前添加eosio.token合同转移操作检查来修复上述错误。

使用语句require_auth(account)非常重要; 进入只需要授权帐户才能执行的操作。require_auth(_self); 用于仅授权合同的所有者签署交易。

行动中的授权

上面的示例代码允许任何人调用该操作。要解决它,请使用require_auth(from); 声明授权付款人致电该行动。

避免修改eosio.token合同

一位白帽黑客因其eosio.token合同中的方法调用不佳而设法获得了10亿美元的dapp 令牌。Dapp Se7ens(现在处于非活动状态)在eosio.token合同中声明了一种新方法,用于将其令牌空投到用户帐户中。

合同没出现问题或transfe 的eosio.token合约以反映更改,因此奇迹般地出现在用户的账户资金- [R行动。其次,他们忘记在转移之前验证方法中的金额,这允许黑客在此过程中索取10亿个令牌。

除了更改最大供应和令牌符号之外,建议避免为自定义函数修改它,因为eosio.token合同中的错误可能是致命的。为了便于安全地进行空投,将空投代币转移到一个单独的帐户并从那里分发。

修改多索引表属性

EOS当前将数据存储在共享内存数据库中,以便跨操作共享。

上面的示例代码创建了一个名为people 的multi_index表,该表基于使用struct person 的该表的单行的数据结构。部署后,EOS目前不允许修改表属性。

eosio_assert_message 断言失败将是将被抛出的错误。

因此,在部署表之前需要完全考虑属性。否则,需要创建具有不同名称的新表,并且在从旧表迁移到新表时需要特别小心。如果不这样做可能会导致数据丢失。

数值溢流检查

在进行算术运算时,如果没有足够负责地检查边界条件,则值可能会溢出,从而导致用户资产丢失。

在上面的示例代码中,使用uint64_t 表示用户余额可能会在值乘以时导致溢出。因此,尽量避免使用uint64_t 来表示余额并对其执行算术运算。使用eosiolib中定义的资产结构进行操作,而不是处理溢出条件的精确平衡。

照顾合同中的假设

在执行合同时会有假设需要断言。如果断言失败,使用eosio_assert 将事先处理条件并停止执行特定操作。举个例子:

上面的断言语句假设roll_under整数大于2且小于96.但如果不是,则抛出上述消息并停止执行。没有发现像上面这样的角落案件可能会成为制定规则的房子的灾难。

生成真随机数

如果没有准确完成,在EOS区块链上生成真正的随机数仍然存在风险。如果没有正确地做到这一点,将导致对手预测结果,在整个过程中对整个系统进行游戏。像Oracalize.it这样的服务可以提供来自外部源的随机数,但它们很昂贵,而且单点故障。

人们过去曾使用Blockchain的上下文变量(块编号,块戳等)来生成以太坊智能合约中的随机数,但它之前已被游戏过。为了正确地进行生成,程序必须提供一种单独的一方无法单独控制的组合随机性。目前最好的方法之一是Dan Larimar自己在双方之间生成随机数时建议的方法。

上面的示例代码给出了1到100之间的优化随机数生成.seed1是house种子,seed2是上面的用户种子。作为参考,DappubEOSBetCasino开放了他们的完整合同,随机数发生器实现了玩家和房子(开发商)之间的公平骰子游戏

EOSBet最近再次遭到65,000 EOS的攻击,当一个对手欺骗他们的eosio.token合同时,只要他在自己的钱包之间进行交易,就将EOS送到他的钱包。

eosio.token合同代码通知EOS令牌的发送者和接收者有传入令牌。为了模仿行为并促进黑客行为,对手创建了两个帐户,让我们假设A&B .A与智能合约的动作有声明require_recipient(N(eosbetdice11))。

当A通过动作调用促进了从A到B的交易时,它通知了转移功能在合同中,好像电话来自eosio.token合同。由于EOS没有真正转移到合同中,每当黑客输掉赌注时,他什么都没有丢失,但是在赢得赌注时他获得了奖励。因此,仅检查合同名称和操作名称是不够的。

检查合同中的通知

为了缓解这个问题,该函数应检查合同是否确实是令牌的接收者。

在EOS上制定智能合约时应遵循的最佳做法是什么?

错误是任何软件不可避免的一部分。它的后果在分散的环境中被放大,特别是如果它涉及价值交易。除了上面讨论的EOS特定保护措施之外,以下是新智能合约开发人员应该记住的一些一般预防措施和最佳实践。

始终审核发布在mainnet之前独立第三方智能合同审计公司的合同。在发布到testnet之前,进行必要的Caveman调试(当前调试合同的唯一方法)。EOSIO文档有一个很好的指南

设置提款限额转移率,避免主网启动初期出现过多损失。有白帽黑客负责任披露的bug赏金计划。当检测到错误时,有一个killswitch来冻结合同。

为了实现它,我们在multi_index表中保留一个标志。我们使用只能由合同所有者调用的操作来设置标志。然后我们检查每个公共行动是否将标志设置为冻结。下面给出了该函数的示例实现。

随时了解库中的安全性增强或平台上的漏洞披露。必要时立即更新库。至少开源合同代码,以便在游戏中保持公平性,独立开发者可以更快地发现错误。

EOS智能合约安全:结论

自EOS推出仅仅5个月,它已经超出了预期。它所取得的权衡 - DPOS,可变智能合约,21个采矿节点等,当然受到权力下放极端主义者的严厉批评。然而,考虑到平台今天提供的可扩展性,它并没有阻止基于以太坊的dApp转向EOS。

无论是EOS还是以太坊赢得战争还有待确定,但EOS肯定赢得了这场战斗。它将保持不变,直到以太坊设法达到运行“世界计算机”所需的世界所需的可扩展性。

本文由来源 Investinblockchain,由 sylvia 整理编辑,其版权均为 Investinblockchain 所有,文章内容系作者个人观点,不代表 链码笔记 对观点赞同或支持。如需转载,请注明文章来源。

发表评论