0

In the huff language, I am able to specify a constant variable with the constant keyword. (huff docs)

#define constant NUM = 0x420
#define constant HELLO_WORLD = 0x48656c6c6f2c20576f726c6421
#define constant FREE_STORAGE = FREE_STORAGE_POINTER()

How would I set up a solidity-like immutable variable that is defined in the constructor?

uint256 internal immutable myVal;

2 Answers 2

1

Unfortunately, Huff doesn't have builtin immutable variable implementation, though the core team is deliberating on whether it should be implemented (the bear case for a feature like this is that it would go against Huff's original goal of staying as low level as possible by adding further abstractions).

You're still able to implement immutable variables yourself, but until a feature is added, you need to do it manually.

Immutables are basically just pieces of data that are appended to the end of the contract's bytecode. Rather than reading the data from state when you need it, the Solidity compiler will just codecopy the info saving you a ton of gas.

You're able to append data to the end of your Huff contract's bytecode using foundry-huff's deploy_with_args function. Once you've done that, you're able to read the data from the contract bytecode by doing the following. Note that this example assumes that your data is 32 bytes long and that you're storing it in memory at position 0.

0x20               // 32, represents size of data
dup1 codesize sub  // offset of data in bytecode
0x00               // offset in memory
codecopy           // copy the data
0

Summary

You can't use an immutable like keyword in huff, instead, your framework or tooling should swap out your constant variable at run time. You can do it with a framework like foundry or with the huff compiler.

Foundry Exmaple

In the huff AddressGetter Contract:

#define constant MY_ADDRESS = 0x0000000000000000000000000000000000000000

In your solidity script/test

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "foundry-huff/HuffDeployer.sol";
import "forge-std/Test.sol";

contract AddressGetterTest is Test {
  AddressGetter public addressGetter;

  function setUp() public {
    address addressToSwapIn = 0x514910771af9ca656af840dff83e8264ecf986ca;

    addressGetter = AddressGetter(HuffDeployer.config().with_addr_constant("MY_ADDRESS", addressToSwapIn).deploy("AddressGetter"))
  }
}

interface AddressGetter {
    function getAddress() external view returns (address);
}

Huffc

huffc AddressGetter --constants <CONSTANTS>...

More information on immutables in huff.

Detailed Answer

Huff doesn't support immutable since it's a bit of a high-level abstraction. In solidity they do it like so:

… during contract creation, a dedicated memory area is reserved for the values of immutables. The constructor code can then store the intended values for the immutables in that memory area. The compiler-generated part of the creation code that is executed after the constructor and returns the contract’s runtime code will read back the values of the immutables and insert them into all occurrences in the runtime bytecode.

immutable variables in solidity are stored in the contract’s runtime bytecode, however their values are not known at compile-time. To get around this, the solidity compiler instead adds placeholders that are replaced with PUSH32 <value> upon the immutables being defined in the contract’s constructor. The runtime bytecode is then altered within the constructor, at runtime to fill these placeholders. This is much different from the behavior of constant variables, which have known values at compile-time and can be directly inlined before deployment.

So, what huff choses for, is to swap out the constants right before compile time using parameters added to the compiler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.