Solidity合约间调用原子性操作实验

BCOS评论765阅读模式

实验说明

为了测试在合约内调用另一个合约时,若在某一方法内,先调用另一个合约方法导致其数据更改成功,而执行后面的语句时由于某些原因导致交易失败,那么已经被调用的合约数据已然更改还是未被更改?针对这个问题,专门进行了以下测试。准备两个合约一个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];
    }
}

 

BCOS最后更新:2021-10-28
以太坊之数据存储详解 以太坊

以太坊之数据存储详解

本文整理分析以太坊网络中的区块、交易以及合约数据是如何存储的。 区块结构 区块由两部分组成,分别是区块头(header)和区块体(body)两部分,详细结构图如下。 区块头(header) 区块头存储...
Solidity开发bug汇总 BCOS

Solidity开发bug汇总

编译器与代码版本不一致问题 (代码版本pragma solidity ^0.4.25),产生如下报错: { "component": "general", "formattedMessage": "S...