2

Is it possible to return a variable with the data location type of storage from a function?

Consider the smart contract below, which DOES NOT compile:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;

library MappingDataTypes {
    struct UintMappingValue {
        uint256 value;
        bool isSet;
    }
}

contract Storage {
    mapping(address => MappingDataTypes.UintMappingValue) uintStorage;

    // ISSUE HERE: TypeError: Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
    function getUnitStorage(address ownerAddr) public returns (MappingDataTypes.UintMappingValue storage) {
        return uintStorage[ownerAddr];
    }


    function storeValue(uint256 value) public {
        // if return value of getUintStorage() function is set to (MappingDataTypes.UintMappingValue memory), the compilation fails with the following error:
        // TypeError: Type struct MappingDataTypes.UintMappingValue memory is not implicitly convertible to expected type struct MappingDataTypes.UintMappingValue storage pointer
        MappingDataTypes.UintMappingValue storage storedValue = getUnitStorage(msg.sender);
        storedValue.isSet = true;
        storedValue.value = value;
    }


}

The goal is to return a struct from the uintStorage mapping and then modify it in the storeValue() function. The changes should persist in the contract's storage and reflected in the uintStorage mapping value.

The contract above does not compile with the following error: TypeError: Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.. If the if return value of getUintStorage() function is set to (MappingDataTypes.UintMappingValue memory), another error occurs due to not being able to cast from a memory variable into a storage variable: TypeError: Type struct MappingDataTypes.UintMappingValue memory is not implicitly convertible to expected type struct MappingDataTypes.UintMappingValue storage pointer.

How can the goal of returning a storage struct from a function, or equivalent, be achieved?

Thank you.

1 Answer 1

5

It works if you declare it as internal.

function getUnitStorage(address ownerAddr) internal returns (MappingDataTypes.UintMappingValue storage) {
    return uintStorage[ownerAddr];
}

Public and external functions cannot return storage references.

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.