2

I'm a big fan of TDD/BDD so I figured hardhat and chai/waffle are a good start to learning smart contract development.

I've run into an issue though where I'm wondering what best practice would be to expect the state of a mapped, nested struct?

Minimal example:

contract MyContract {
    struct Inner{uint foo;}
    struct Outer{Inner bar;}

    uint idx;
    mapping (uint => Outer) mapped;

    function doSomething(uint _val) public {
        mapped[idx] = Outer(Inner(_val));
    }
}

How would I go about testing that Inner.foo has the correct value after the call to doSomething(123) ?

The only solution I've found so far is creating a function getOuter(uint _idx) public view returns (Outer memory) and use that to retrieve the value to expect in the test.
This however would mean adding a function to the contract that is only needed for testing as well as using pragma experimental ABIEncoderV2; which - well, sounds kinda experimental.

What's the correct way to solve this?

1 Answer 1

1

With solc v0.8 ABIEncoderV2 is the default setting and the pragma line isn't needed anymore.

See the list of breaking changes in 0.8.


For testing you can inherit from the contract and implements getters there. A change required by using inheritance is declaring variables in the base contract as internal, otherwise if they are private they can't be used in the inherited contract.

contract MyContractForTest is MyContract {
    function getOuter(uint _idx) public view returns (Outer memory) {
        return mapped[_idx];
    }
}
4
  • Ah, ok thanks! But including a getter function just for testing still feels wrong, doesn't it?
    – TommyF
    Commented Mar 27, 2021 at 17:31
  • 1
    @TommyF For security reasons data is inaccessible on-chain without a getter. For testing you can use a mock contract that implements the getters.
    – Ismael
    Commented Mar 27, 2021 at 17:51
  • That makes sense, thank you. Is this common practice or is it more of a sign that my data structure is probably sub-optimal?
    – TommyF
    Commented Mar 28, 2021 at 5:48
  • @TommyF The reality is that there's a lack advanced of tools. The easy solution here doesn't scale well for dozen of contracts, doesn't add much security and it is impractical in many other cases. Modifying the EVM to extract data without creating the mock contract sound interesting but doing so is beyond the scope for most projects.
    – Ismael
    Commented Mar 28, 2021 at 16:36

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.