Skip to content
This repository has been archived by the owner on Jul 4, 2022. It is now read-only.

How to pass arguments to the constructor? #26

Closed
Kayaba-Attribution opened this issue May 30, 2022 · 4 comments
Closed

How to pass arguments to the constructor? #26

Kayaba-Attribution opened this issue May 30, 2022 · 4 comments

Comments

@Kayaba-Attribution
Copy link

⊂(◉‿◉)つ HI!

I saw Huff and wanted to give it a try, is there any documentation available that explains the takes(0) returns (0) syntax on the macros?

  • How to pass an address to the constructor?

Tried to do it this way:

/* Constructor */
#define constant TEST_LOCATION = FREE_STORAGE_POINTER()

#define macro CONSTRUCTOR() = takes(1) returns (0) {
    [TEST_LOCATION] sstore
    // Set msg.sender as the owner of the contract.
    OWNABLE_CONSTRUCTOR()
}

and

    const Token = await ethers.getContractFactory("ERC20");
    token = await Token.deploy("0x0000000000000000000000000000000000000000");
    await token.deployed();

But it says wrong number of arguments, expecting 0 got 1

@virtualjpeg
Copy link
Collaborator

the takes and returns syntax effectively denotes the values the macro takes of the stack and the values it adds, or returns onto the stack.

as an example, a macro that performs basic addition would have the annotation takes (2) returns (1), as it takes two existing values from the stack (as an example: 3 and 2) and finally puts the result (5) on the stack.

if you want to pass an argument, you can do it as you do with a normal programming language.

@virtualjpeg
Copy link
Collaborator

also note that the compiler does not enforce these annotations - they are purely for readability.

@jtriley2p
Copy link
Contributor

jtriley2p commented May 30, 2022

Here is an ERC721 constructor example with the name and symbol:
https://github.com/exp-table/huffc/blob/0d572fc6131804fd1785df97d70d9451d05c4460/examples/erc721/contracts/ERC721.huff#L44

Constructor arguments are each padded to 32 bytes and appended to the end of the deployment bytecode.

You should be able to access an address by extracting the first 32 byte constructor argument as follows.

#define constant TEST_LOCATION = FREE_STORAGE_POINTER()

#define macro CONSTRUCTOR = takes (0) returns (0) {
    0x20                   // [arg0_size]
    0x20 codesize sub      // [arg0_offset, arg0_size]
    0x00                   // [mem_offset, arg0_offset, arg0_size]
    codecopy               // []
    0x00                   // [mem_offset]
    mload                  // [arg0]
    [TEST_LOCATION] sstore // []
}

@Kayaba-Attribution
Copy link
Author

@virtualjpeg , @JoshuaTrujillo15 Thank you for your help!

The example was awesome, I might go ahead and add the name and symbol for the ERC20 example (ᵔᴥᵔ)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants