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