【问题标题】:Solidity - Calling parent payable not possible?Solidity - 不可能打电话给父母?
【发布时间】:2019-01-05 09:13:39
【问题描述】:

我正在尝试继承和覆盖父母的应付函数(并添加一些修饰符和逻辑),但到目前为止似乎无法这样做。

我的第一次直观尝试是这样的:

contract foo {
    function test() public payable returns (uint256) {
        return msg.value;
    }
}

contract bar is foo {
    function test() public payable returns (uint256) {
        return super.test.value(msg.value / 2)();
    }
}

并收到编译错误:

TypeError: Member "value" not found or not visible after argument-dependent lookup in function () - did you forget the "payable" modifier?
super.test.value(msg.value)();

给函数一个不同的名字也不起作用,所以这不是一个压倒一切的问题。

contract foo {
    function test() public payable returns (uint256) {
        return msg.value;
    }
}

contract bar is foo {
    function anotherTest() public payable returns (uint256) {
        return super.test.value(msg.value / 2)();
    }
}

我通过使用强制转换来欺骗编译器稍微走得更远,但这显然不好,因为会在运行时导致无限循环:

contract foo {
    function test() public payable returns (uint256) {
        return msg.value;
    }
}

contract bar is foo {
    function test() public payable returns (uint256) {
        return foo(address(this)).test.value(msg.value / 2)();
    }
}

有效的方法是将两者结合起来,即给它一个不同的名称和铸造:

contract foo {
    function test() public payable returns (uint256) {
        return msg.value;
    }
}

contract bar is foo {
    function anotherTest() public payable returns (uint256) {
        return foo(address(this)).test.value(msg.value / 2)();
    }
}

现在用 6 wei 调用 bar.test() 返回 6,调用 bar.anotherTest() 返回 3。但这并不是我想要的,因为它仍然通过 bar 公开 test()。

那么我做错了什么,或者这是设计使然?真的很想了解为什么 Solidity 会以这种方式运行,以及是否有解决方法来实现我想要的。谢谢!

【问题讨论】:

    标签: inheritance parent ethereum solidity


    【解决方案1】:

    您可以修改最后一个示例,并在父合约中将test 标记为internal。从它继承的合约仍然可以调用它,但不能从外部调用执行。

    contract foo {
        function test() internal payable returns (uint256) {
            return msg.value;
        }
    }
    
    contract bar is foo {
        function anotherTest() public payable returns (uint256) {
            return foo(address(this)).test.value(msg.value / 2)();
        }
    }
    

    【讨论】:

    • 感谢 Raghav 的建议。但我相信payable 不能是internal 并且通过将bar 转换为foo 我会尝试直接在foo 上调用test,或者像你所说的那样从外部调用。
    • 啊,对。另一种选择是您可以使用修饰符使 foo.test() 只能由 bar 访问。
    【解决方案2】:

    在您的所有示例中,您都试图以内部调用的方式发送以太币,这不是以太坊的工作方式,也没有理由这样做。这样做意味着你可能对 Solidity 的一个基本部分感到困惑。如果你向合约发送以太币,你只需要支付最外层的函数,内部函数和被覆盖的函数不需要支付。我认为您正在尝试做的事情的一种方法是:

    pragma solidity 0.4.24;
    
    contract foo {
        function test(uint value) internal pure returns (uint256) {
            return value;
        }
    }
    
    contract bar is foo {
        function test() public payable returns (uint256) {
            return super.test(msg.value/2);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 2016-01-18
      • 1970-01-01
      • 2015-01-16
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多