1

I have a mapping in contractA marked as public. I know a default getter function is created that will allow me to get the value from contractB, but can I set the value from contractB too? The compile error I'm getting isn't clear "TypeError: Expression has to be an lvalue." so I'm just wondering if I have the syntax wrong or if it's simply not possible even though it's marked as public.

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.7.0 <0.9.0;

contract contractAInterface {
    mapping(string => uint256) public testMapping;
}

contract contractB {

    address contractAddress = 0xd9145CCE52D386f254917e481eB44e9943F39138;
    contractAInterface contractA = contractAInterface(contractAddress);

    function setValueOfMapping(string memory _key, uint256 _value) public {
        contractA.testMapping(_key) = _value;
    }
}

1 Answer 1

0

It's not possible to modify any state variable of a smart contract from another contract directly at all. That would defeat the purpose of the smart contract if anybody could update anything from another smart contract directly.

But, if you inherit from that contract, then you could update its internal and public properties directly since when you inherit from a contract your contract is basically the other contract too, mixed together.

Take a look at the refactor:

contract contractAInterface {
    mapping(string => uint256) public testMapping;
}

contract contractB is contractAInterface{

    address contractAddress = 0xd9145CCE52D386f254917e481eB44e9943F39138;
    contractAInterface contractA = contractAInterface(contractAddress);

    function setValueOfMapping(string memory _key, uint256 _value) public {
        testMapping[_key] = _value;
    }
}

If you own the other contract you could add functions to mutate state variables:

contract contractAInterface {
    mapping(string => uint256) public testMapping;
    function mutateTestMapping(string memory key, uint256 value) external {
        testMapping[key] = value;
    }
}

contract contractB {

    address contractAddress = 0xd9145CCE52D386f254917e481eB44e9943F39138;
    contractAInterface contractA = contractAInterface(contractAddress);

    function setValueOfMapping(string memory _key, uint256 _value) public {
        contractA.mutateTestMapping(_key, _value);
    }
}
1
  • 1
    Great thanks for confirming that, I just wasn't sure if by deliberately making it public then the intention of contract ownerA was to allow it, but all good that's perfect thanks! Aug 26, 2022 at 23:23

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.