Search code examples
ethereumsoliditysmartcontractsbrownieevm

Does a contract instance created via interfaces have the same address as the original deployed contract?


I have been following Solidity, Blockchain, and Smart Contract Course – Beginner to Expert Python Tutorial (https://www.youtube.com/watch?v=M576WGiDBdQ&t=28658s). instead of copying a ton of code, I'm trying to generalize my question as follows:

consider the following code snippet:

weth=interface.IWeth(SomeAddress)
tx=weth.deposit({"from":account, "value": 0.01*10**18})

I understand that interface.IWeth(SomeAddress) tells Ethereum virtual machine to create an instance of the contract at SomeAddress ( which I will call SomeContract) with the functionalities of the interface.

I would like to confirm the following:

Does weth and SomeContract share the same address?

will the following state changes have the same outcome?

weth.deposit({"from":account, "value": 0.01*10**18})

and

SomeContract.deposit({"from":account, "value": 0.01*10**18})

Solution

  • Let's say you have contractB and contractA. Inside contractB you want to interact with contractA but you do not know the code of contractA. All you know is interface and address of the contractA. In this case, you interact with contractA inside contractB via the interface, and any change you make to contractA will be reflected inside contractA in blockchain.

    In your question when you call weth.deposit you are actually modifying the state of contract at given address.

    You could test this easily on Remix.

    Let's say you have contractA and interface of it:

        // SPDX-License-Identifier: MIT
        pragma solidity ^0.8.0;
        
        interface InterfaceA {
            function count() external view returns (uint256);
            function increment() external;
        }
        
        contract contractA {
            uint256 number = 0;
        
           function count() external view returns (uint256) {
              return number;
           }
        
           function increment() external {
              number++ ;
           }
        }
    

    You compile it and then deploy it. (Make sure when you deploy it, select the contractA not interfaceA). Get the address of deployment. Then create contractB:

        // SPDX-License-Identifier: MIT
        pragma solidity ^0.8.0;
        
        import './contractA.sol' ;
        
        contract contractB {    
            address addressA;   
            constructor (address _addressA) {
                  addressA = _addressA;
            }
        
            function getCount() external view returns (uint256) {
                 InterfaceA b = InterfaceA(addressA);
                 return b.count();
            }
        
            function addToIncrement() external {
                 InterfaceA b = InterfaceA(addressA);
                 b.increment();
            }
        }
    

    Now when you deploy this, since I wrote a constructor with an argument, you need to pass the address of cotractA. Then call addToIncrement() of contractB. This will call the increment function of contractA. Now go to contractA and call count and you will get updated value.