0
pragma solidity ^0.8.0;

    contract Contract1 {
        struct User {
            bool isValid;
            uint value;
        }

        mapping(address => User) public party;  
    }

    contract Contract2 {
        Contract1 c1;
           constructor (address addr) {
           c1 = Contract1(addr);
    }

    modifier requireDeposit(address _eventAddress) {
        (bool isValid,) = c1.party(_eventAddress);
        require(isValid == true, "Not a valid user!");
        _;
    }

    function updateField(address _eventAddress) public {
        // I want to update the field value of _eventAddress.
        c1.party(_eventAddress).value = 35;
    }
    
}

I want updateField() function of Contract2 to update the value field of User struct from Contract1.

1 Answer 1

1

You can do it, using an Interface. Try this:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IContract {
        // Define the 'User' interface
        struct User {
            bool isValid;
            uint value;
        }

        // Define the methods to get/set value in 'User' interface
        function updateField(address _eventAddress, uint _value) external;  
        function getIsValid(address _eventAddress) external returns(bool);
    }

contract Contract1 is IContract {
    mapping(address => User) public party;  

    // Overriding method of interface 
    function updateField(address _eventAddress, uint _value) external override {
        party[_eventAddress].value = _value;
    }

    // Overriding method of interface
    function getIsValid(address _eventAddress) external view override returns(bool) {
        return party[_eventAddress].isValid;
    }
        
}

contract Contract2 {
    IContract iContract;

    constructor(address addr) {
        // Initialize interface object with Contract1 address
        iContract = Contract1(addr);
    }

    modifier requireDeposit(address _eventAddress) {
        // I changed this line calling 'getIsValid' function that I have declared on interface
        bool isValid = iContract.getIsValid(_eventAddress);
        require(isValid == true, "Not a valid user!");
        _;
    }

    // Call the method updateField define in Contract1 through 'IContract' interface
    function updateField(address _eventAddress) public {
        iContract.updateField(_eventAddress, 35);
    }
    
}

NOTE: I've had to change 'requireDeposit' modifier, using a new method that I have created.

2
  • Amazing! I just have one last question before I accept the answer. What is the rule of thumb when it comes to using interface? I mean what made you think that I need interface to do so...
    – Emrah
    Commented Mar 29, 2022 at 18:59
  • For the easy reason that if you want into contract2 declare a mapping with a User struct or you want to use the User struct, you must only implement IContract interface. Otherwise, you cannot access to User struct into Contract1 (like in your code) because the struct is internal access type. Commented Mar 29, 2022 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.