实验说明
为了测试在合约内调用另一个合约时,若在某一方法内,先调用另一个合约方法导致其数据更改成功,而执行后面的语句时由于某些原因导致交易失败,那么已经被调用的合约数据已然更改还是未被更改?针对这个问题,专门进行了以下测试。准备两个合约一个Call.sol主动调用合约,BeCalled.sol是被动调用合约,在Call的方法里调用操作BeCalled的数据。
测试过程
调用testCallOtherContract(100)
该笔交易执行错误
然后分别查数据,Call中调用getMap(100)返回为false
BeCalled中调用getStoreMap(100)返回为false
说明
在调用出方法中出现require等,且未通过安全性检查时,整个交易会被回退,即使已成功调用了其他合约的方法,被调用的合约依然会回退到调用前的状态。
实验代码
Call.sol
pragma solidity ^0.4.25; import "./BeCalled.sol"; contract Call { BeCalled private beCalled; mapping(uint => bool) isExecuteSuccess; constructor(address beCalledAddr){ beCalled = BeCalled(beCalledAddr); } function getMap(uint key) public returns(bool) { return isExecuteSuccess[key]; } function testCallOtherContract(uint account) public returns(uint) { uint retState = beCalled.setStoreMap(account, true); require(retState == 0); // 此处交易会显示出错 isExecuteSuccess[account] = true; return 1; } }
BeCalled.sol
pragma solidity ^0.4.25; contract BeCalled { mapping(uint => bool) storeMap; function setStoreMap(uint key, bool value) public returns(uint) { storeMap[key] = value; return 1; } function getStoreMap(uint key) public returns(bool) { return storeMap[key]; } }