1

Say you have a contract defined like this:

pragam solidity >=0.8.0;

contract Foo {
    uint256 public constant MY_CONSTANT = 6174;
}

If I just import Foo in another contract, without inheriting from it, can I read MY_CONSTANT?

I tried doing it like this, but it didn't work.

pragam solidity >=0.8.0;

import { Foo } from "/path/to/Foo.sol";

contract Bar {
    function myFunction() external {
        uint256 myConstant = Foo.MY_CONSTANT; 
    }
}

I got the following error:

TypeError: Member "MY_CONSTANT" not found or not visible after argument-dependent lookup in type(contract SablierV2Pro)

2 Answers 2

3

If I just import Foo in another contract, without inheriting from it, can I read MY_CONSTANT ?

Without forcing a call, no. constant variables are hardcoded into the bytecode, they are not variables, don't take any storage, and don't make it to the ABI unless if you specify it as public but issuing a call to read a constant variable through the auto generated getter just doesn't make any sense...

If both Foo and Bar need that constant, but inheritance doesn't make sense for some reasons, I'd argue that the constant definition doesn't belong in Foo to begin with. In that case, it has the characteristics of a global / application-wide constant.

Solidity leaves the possibility of declaring constant at a file level for those cases (this issue might also be of interest). Assuming that the following code is placed in a file called constants.sol which holds various global constants for your application, including MY_CONSTANT :

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

uint256 constant MY_CONSTANT = 6174;
// other global constants...

You can then import it and use it in both Foo and Bar :

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

import "./constants.sol";

contract Foo {
    // Doesn't need to declare MY_CONSTANT as this is done
    // at the file level in constants.sol

    // Use the imported definition from ./constants.sol
    function myFunction() external pure returns (uint256) {
        return MY_CONSTANT; 
    }
}

contract Bar {

    // Use the imported definition from ./constants.sol
    function myFunction() external pure returns (uint256) {
        return MY_CONSTANT; 
    }
}
1

An alternative for old solc version is to create a base contract with the constants and inherit it contracts in the contracts that need them.

pragma solidity >=0.4.0;

contract Constants {
    uint256 public constant MY_CONSTANT = 6174;
}

contract Foo is Constants {
    function foo() pure public returns (uint256) {
        return MY_CONSTANT;
    }
}

contract Bar is Constants {
    function bar() pure public returns (uint256) {
        return MY_CONSTANT;
    }
}

It won't work for libraries, so having global constants is the better solution.

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.