'Getting the address of a contract by another one after inheritance
I am new to Solidity and I've come up with this issue.
I want to develop a contract called senderContract {} that can receive ether from any address and then automatically transfer these funds to another contract called receiverContract {}. In this second contract, you will find two functions, the first one (manualTransfer()) is working correctly and allows to introduce manually the contract contract address to send the ether. But the second one (autoTransfer()) is not working.
I've discovered that the constructor() in the first contract changes the value of the variable recipient once the second contract es deployed. How is it possible that a variable in a constructor changes from its initialized value? Is the contructor not supposed to be executed just once?
Is there any reason for this action not being possible or am I just not writing the correct code? I leave the code here:
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);
}
}
Thank you in advance!
Solution 1:[1]
constructor () {
recipient = address(this);
}
Constructor is in fact executed just once - during the contract deployment. However, the value of address(this) (the address of this contract) is different each time you deploy the contract. Which results in the value of recipient also being different each time.
The address of newly deployed contract is, by default, determined from the deployer address and nonce of the deploying transaction. First transaction has nonce 0, second transaction has nonce 1, etc. So when you send a first transaction deploying a contract from the deployer address, it results in the contract address 0x123. But a second transaction deploying a contract (any contract, even the same one) from the deployer address results in the contract address 0x456.
If you want the deployed contract address to be always the same (mind that you need to destruct the previously deployed contract before redeploying it), you can use the create2 opcode (the non-default option). See this answer for more info.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Petr Hejda |
