Is it possible to read constants from external contracts in Solidity

constantsoliditysolidity-0.8.x

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)

Best Answer

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; 
    }
}