【问题标题】:Getting the address of a contract by another one after inheritance继承后获取另一个合约的地址
【发布时间】:2022-06-13 04:43:21
【问题描述】:

我是 Solidity 的新手,我提出了这个问题。 我想开发一个名为senderContract {} 的合约,它可以从任何地址接收以太币,然后自动将这些资金转移到另一个名为receiverContract {} 的合约中。在第二个合约中,你会发现两个函数,第一个函数 (manualTransfer()) 工作正常,允许手动引入合约合约地址来发送以太币。但是第二个 (autoTransfer()) 不起作用。

我发现一旦部署第二个合约,第一个合约中的constructor() 会更改变量recipient 的值。构造函数中的变量如何从其初始化值更改?构造函数不应该只执行一次吗?

是否有任何原因导致无法执行此操作,或者我只是没有编写正确的代码?我把代码留在这里:

pragma solidity >= 0.7.0 < 0.9.0;


 contract receiverContract {

    event Log(uint);
    address public recipient;

    constructor () {
        recipient = address(this);
    } 

    fallback () external payable {
        emit Log(gasleft());
    } 

    receive () external payable {}

    function getThisAddress() public view returns(address) {
        return address(this);
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }

}



contract senderContract is receiverContract {

    function manualTransfer (address payable _to) public payable {
        _to.transfer(msg.value);
    }

    function autoTransfer () public payable {
        payable(recipient).transfer(msg.value);
    }

}

提前谢谢你!

【问题讨论】:

    标签: inheritance ethereum solidity smartcontracts


    【解决方案1】:
    constructor () {
        recipient = address(this);
    }
    

    构造函数实际上只执行一次 - 在合约部署期间。但是,每次部署合约时,address(this)(此合约的地址) 的值都不同。这导致recipient 的值每次也不同。

    新部署的合约地址默认由部署者地址和部署交易的nonce确定。第一个交易的随机数为 0,第二个交易的随机数为 1,依此类推。因此,当您从部署者地址发送部署合约的第一笔交易时,它会生成合约地址 0x123。但是从部署者地址部署合约(任何合约,甚至是同一个合约)的第二次交易会导致合约地址0x456


    如果您希望部署的合约地址始终相同(请注意,您需要在重新部署之前销毁之前部署的合约),您可以使用create2 操作码(非默认选项)。请参阅this answer 了解更多信息。

    【讨论】:

    • 感谢彼得的回答。我想我已经理解了这个问题的概念部分,但我不确定如何实现它。能否分享一个小例子,说明如何使用 nonce 获取此地址?
    • @RodrigoR 随机数是在在后台检索的,你没有在代码中明确使用它。所以如果你想从另一个合约部署一个合约(工厂模式),您可以在 Solidity 中使用 new 关键字:new MyContract(constructorParams); 并将 MyContract 的新实例部署到新地址(地址由后台的 nonce 确定)。
    【解决方案2】:

    这似乎运作良好,使用super 功能(查看第二个合约的第一行);在混音时,recipent_recipient 是相同的。

    pragma solidity >= 0.7.0 < 0.9.0;
    
    contract receiverContract {
    
        event Log(uint);
        address public recipient;
    
        constructor () {
            recipient = address(this);
        } 
    
        fallback () external payable {
            emit Log(gasleft());
        } 
    
        receive () external payable {}
    
        function getThisAddress() public view returns(address) {
            return address(this);
        }
    
        function getBalance() public view returns (uint) {
            return address(this).balance;
        }
    
    }
    
    
    
    contract senderContract is receiverContract {
    
        address _recipient=super.getThisAddress();
    
        function manualTransfer (address payable _to) public payable {
            _to.transfer(msg.value);
        }
    
        function autoTransfer () public payable {
            payable(_recipient).transfer(msg.value);
        }
    
    }
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2017-07-03
    • 2022-12-03
    • 1970-01-01
    • 2020-03-28
    • 2018-02-04
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多