Skip to main content

Keccak Hash Not Treated as Constant

Description

In Solidity, constant keccak256 variables are treated as expressions and not as true constants. This means that using them in certain contexts, such as during contract initialization, can result in additional gas costs.

Example Code

Consider the following contract code:

pragma solidity 0.8.0;

contract KeccakExample {
bytes32 constant MY_HASH = keccak256(abi.encodePacked("my_string"));

function myHash() public pure returns (bytes32) {
return MY_HASH;
}
}

In this code, we define a constant MY_HASH using keccak256, which takes the keccak256 hash of the string my_string. However, because MY_HASH is treated as an expression, using it in the contract initialization phase will result in an additional gas cost.

Recommendation

To avoid additional gas costs when using keccak256 in Solidity, it is recommended to store the result of the hash as a true constant. This can be done by computing the hash outside of the contract and then hard-coding the resulting value as a constant variable. Alternatively, if the hash must be computed within the contract, it is recommended to perform the computation within a function and then store the result in a true constant variable for later use.

Here's an example of how to compute the hash outside of the contract and then hard-code the resulting value:

pragma solidity 0.8.0;

contract KeccakExample {
bytes32 constant MY_HASH = 0x8ad4fd4b2a4960d7cc1cde8a5f5e5e5c44a82d883d6f316db16b7c28b2e659bc;

function myHash() public pure returns (bytes32) {
return MY_HASH;
}
}

In this code, we compute the keccak256 hash of the string my_string outside of the contract and then hard-code the resulting value as the constant MY_HASH. Using this approach, there are no additional gas costs associated with the computation of the hash within the contract.

Overall, it is important to be mindful of how constant keccak256 variables are treated in Solidity and to take steps to avoid unnecessary gas costs.