从另一个合约调用合约函数时出现以太坊交易错误

Ethereum Transaction Error while calling a contract function from another contract

以下智能合约在 Remix 和 Ganache 中运行良好。但是不适用于 Kaleido 或 Azure 等私有以太坊区块链。我错过了什么。当我调用 setA 时,它消耗了所有气体然后失败了。

pragma solidity ^0.4.24;

contract TestA {
    uint public someValue;

    function setValue(uint a) public returns (bool){
        someValue = a;
        return true;
    }
}

contract TestB {
    address public recentA;

    function createA() public returns (address) {
        recentA = new TestA();
        return recentA;
    }

    function setA() public returns (bool) {
        TestA(recentA).setValue(6);
        return true;
    }
}

您正在达到每个区块允许花费的气体限制。每个区块中都包含有关 gas limit 的信息,因此您可以在您的区块链中查看此值的当前值。目前在以太坊主网上,GasLimit(每个区块)约为 800 万(参见此处https://etherscan.io/blocks

要解决此问题,您可以使用修改后的创世文件启动您的区块链。尝试增加创世文件中 gasLimit 参数的值,该参数指定每个块处理的最大气体量。尝试 "gasLimit": "8000000"

我在 Kaleido 中尝试了你的合同,发现即使用非常大的号码调用 eth_estimateGas 也会导致 "out of gas"。

我更改了 setValue 跨合约调用以设置 gas 值,然后我能够调用 setA,并且估计 setA 的 gas 仅显示 31663。

recentA.setValue.gas(10000)(6);

我怀疑此 EVM 行为与 gasprice 为零的许可链有关。但是,这是猜测,因为我还没有调查内部结构。

我还在 kaleido-go 中添加了 eth_estimateGas,并支持 Solidity 文件中的多个合约,以防有帮助: https://github.com/kaleido-io/kaleido-go

Another possibility for others encountering "out of gas" calling across contracts - In Geth if a require call fails in a called contract, the error is reported as "out of gas" (rather than "execution reverted", or a detailed reason for the require failing).

尝试丢弃合约TestAsetValue方法的return语句。

pragma solidity ^0.4.24;

contract TestA {
    uint public someValue;

    function setValue(uint a) public {
        someValue = a;
    }
}