本文是整理好的CIP-71中文介绍,供大家交流讨论。
CIP-71详情链接:https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-71.md
简介
CIP-71 开发网络完全关闭合约的抗重入(anti-reentrancy)机制。
摘要
当前,Conflux 智能合约虚拟机拥有抗重入机制。当单个合约在调用栈内出现两次时,Conflux 将禁止在后续执行诸如 SSTORE
、LOG0
至 LOG4
以及余额非零的 CALL
等写入操作。此 CIP 旨在令此功能可配置。我们将引入一个新的内部合约,此合约将允许合约自身或其管理者开启或关闭抗重入功能。
动机
Conflux 引入抗重入机制来避免某些来自 DEFI 应用的攻击。然而此机制也会禁用一些合法操作。举例来说,如果某借方合约调用了一个闪电贷合约,然后此闪电贷合约又调用了借方合约的“callback”函数,那么借方合约就会在调用栈内出现两次,接下来的所有写入操作都将被禁止。尽管开发人员可以通过改变合约间的交互逻辑来避免出现这类问题,但是这会给合约迁移带来额外的任务量。
规格参数
Internal contract
Conflux将引入一个新的内部合约。
pragma solidity >=0.4.15;
contract AntiReentrancy {
/**
* @dev the contract turns on/off the anti-reentrancy.
* @param allow A boolean variable to indicate if the reentrancy is allowed in this contract.
*/
function allowReentrancy(bool allow) external {}
/**
* @dev a contract admin turns on/off the anti-reentrancy for the contract.
* @param contractAddr The address of the contract.
* @param allow A boolean variable to indicate if the reentrancy is allowed in this contract.
*/
function allowReentrancyByAdmin(address contractAddr, bool allow) external {}
/**
* @dev get whether the reentrancy is allowed for a contract. vote power staking balance at given blockNumber
* @param contractAddr The address of the contract.
*/
function isReentrancyAllowed(address contractAddr) external returns (bool) {
Change for the anti-reentrancy mechanism
只有在一个不允许重入(抗重入功能开启)的合约地址在调用栈内出现两次时,Conflux才会禁止写入操作(触发抗重入机制)。
Activation plan
参数: BLOCK_NUMBER_CIP71A
,BLOCK_NUMBER_CIP71B
。
a. 启用新的内部合约,对于Conflux上允许重入的合约,关闭其抗重入功能。此内部合约将从block_numer >= BLOCK_NUMBER_CIP71A
开始激活。
b. 对于当前抗重入机制的实现,将从block_number >= BLOCK_NUMBER_CIP71B
开始修复其错误行为。
安全方面的考虑因素
目前,一些经过充分审计的合约模版允许开发人员在 Solidity 代码中检测合约是否发生重入,并禁止恶意利用重入的操作,所以没有必要在虚拟机层面保留抗重入机制。然而,已经部署在Conflux的合约可能将继续依赖此机制,所以我们将抗重入机制改为可配置的,而非将其删除。