防止意外的RAM消耗

in #cn6 years ago

 一些用户和基于EOSIO的智能合约,其RAM资源在无意中被恶意的第三方用在了已创建的特殊智能合约中。发生这种情况的原因是对功能的误解,发生这种情况的原因是对使合约能够通知其他事件合约的功能的误解,例如收入转账。恶意合约使用此通知功能在未经知情着同意的情况下,用随机数据填充其他人的RAM,然后这部分RAM将无法释放。
梗概1、没有通证被盗;2、正确部署的合约不容易受到攻击;3、治理流程可以修复同各方意图相悖的代码所产生的行为;4、节点对于保护的措施只有缓解的选项是可行的;5、及时升级可以使默认操作更安全。
没有通证被盗恶意合约利用了智能合约开发者和用户对开发智能合约的最佳实践的误解。这种攻击类似于故意破坏而不是盗窃,一旦EOS治理流程可以审查和纠正这种情况,就不会对相关各方造成长期损害。
正确部署的合约不容易受到攻击期望每个用户都能够审查在他们之间进行交互的合约,或让受信任的第三方代表来进行审查。这意味着审查者应谨慎地同使用通知功能的智能合约进行交互。例如将通证发送给他们不信任的CPU和RAM资源所在的智能合约。 若要以编程方式将通证发送到不受信任的第三方指定帐户,开发人员应通过没有可用RAM资源的帐户中继传输。这既适用于处理中心化交易所中用户的提现操作,也适用于通过智能合约执行此操作的去中心化交易所。有几个可信任的中继合约可用。 当某项操作可能会消耗RAM时,许多钱包提供方已为用户设置了提醒功能。
通过治理流程释放消耗的RAM我觉得应该强制执行能被用户和开发人员理解其意图的代码。如果恶意合约明显地利用了用户意图同代码实际效果之间不匹配的情况,那么在恶意合约编写者和与之产生交集的人之间进行仲裁时,节点能够将恶意合约列入黑名单。 如果仲裁发现代码的行为违背了同代码交互的各方的意图,那么当选的节点可以自由地更新代码,使得结果同各方的初始意图相匹配。在这种情况下,代码将被更新以释放意外消耗的RAM,并且之后不会再消耗RAM。
为什么这是EOSIO的一个特性?对于RAM被滥用的情况,有许多现成的案例。最常见的案例是想要用户进行充值的游戏合约。交易所部署代码以处理来自代币合约的转账通知,然后将余额记入交易发起人的账户。在这种情况下,在这种情况下,交易所和存款用户可以合理地授权交易合约消费用户的 RAM 来存储他们的余额。交易所不一定要将用户的余额存储在他们自己的RAM中,因为这可能导致另外的攻击,比如许多帐户向交易所发送极小余额请求的攻击。 EOSIO有一个叫内联操作的功能,它允许当前合约调用另一个合约的代码作为当前交易的一部分。与操作通知功能不同,内联操作仅限于分配生成内联操作的合约的资源。基于原始操作的资源分配权限的操作许可。
防止意外行为继续发生虽然现有设计有许多合法用途,但目前我们认为代码的默认行为与用户和开发人员的直觉相反。为了简化不太常见的案例,必须采取更加复杂的步骤防止正常的案例被滥用。 展望未来,我们建议通知处理程序只有使用接收通知的合约RAM的权限。这样可以安全地将通证发送到任何合约,而不必担心它会以意想不到的方式消耗RAM。交易所能够安全地处理提币请求,而无需在处理提款请求之前审查部署到用户帐户的合约。 根据此提议的变化,现有合约必须获得直接授权以消耗一些用户可用的RAM。在接受用户的存款之前,交易所合约将要求用户“开立账户以预留存储其余额的空间”。然后,传入的存款通知将很容易增加预先分配的RAM,而不是分配新的RAM。
提议的升级路线我们正在准备一个仅限节点的升级,它将改变默认行为,以防止操作通知的接收者(例如通证转移通知)意外消耗交易发起者的RAM。如果所有节点都采用此升级,那么RAM滥用的缓解策略将不再必要。不幸的是,这种缓解可能会破坏有效合约,直到它们可以更新为在操作通知处理程序期间不再依赖于用户帐户上分配的RAM为止。 幸运的是,升级合约以采用新的最佳实践的过程应该相对简单。 作为下一次公投的一部分,所有节点都将采用仅限节点的升级。
总结EOSIO的设计符合设计要求,并且在正确使用时是安全的。我们相信,对于大多数案例,我们可以更轻松地使用EOSIO对其进行满足,并能同EOS社区合作开发出最强大的整体解决方案。