I'm trying to write a deployer function which would allow me do deploy arbitraty code. So far, I can deploy a contract with parameters using this snippet found here:

// js truffle
const tokenWeb3 = web3.eth.contract(Token.abi)
const tokenData = tokenWeb3.new.getData(totalSupply, name, symbol, decimals, { data: Token.bytecode })
await contract.deploy(tokenData)

// solidity
function deploy(bytes _code) public {
    address tokenAddress;
    assembly {
        tokenAddress := create(0, add(_code, 0x20), mload(_code))
        if iszero(extcodesize(tokenAddress)) { revert(0, 0) }

What I need is to append this new token address as a parameter to a new deployment, something like this:

// solidity
function deploy(bytes _code1, bytes _code2) public {
    address tokenAddress;
    assembly {
        tokenAddress := create(0, add(_code, 0x20), mload(_code))

        // converts address to bytes?
        let m := mload(0x40)
        mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, tokenAddress))
        mstore(0x40, add(m, 52))
        let b := m

        // adds address to deployment bytecode?
        let appended := add(_code2, b)

        saleAddress := create(0, add(appended, 0x20), mload(_code2))
        if iszero(extcodesize(saleAddress)) { revert(0, 0) }

But the transaction get reverted. The _code2 bytecode contract constructor has only one parameter, which is the token address. I'm not sure I can just append parameters like this, I'm gonna take a look at web3 contract.new.getData(). I'm not familiar with solidity assembly, so help?

  • 1
    Check the solidity ABI params are always padded to 32 bytes. In your second create your are passing the address as bytecode and not the bytecode from _code2. FYI add(_code, 0x20) is a pointer to the bytecode and mload(_code) returns the length of the bytecode. One problem you didn't solve is how to append the address to the bytecode. One solution is to allocate memory of _code2.length + 32, and copy there the bytecode from _code2 and append the address, then you can call create with the allocated pointer and length + 32. – Ismael May 21 '18 at 3:20
  • Great info, Ismael, gonna give it a try and return the results. Thanks. – AFMeirelles May 21 '18 at 11:33
  • @Ismael my man, there is so little documentation about inline assembly, I'm walking in circles. Especially the add() function, how does it work? Looks like sometimes it is used to add parameters and in other, to add slots to the stack. Would you mind writing an example so I can follow? – AFMeirelles May 22 '18 at 21:43
  • There's nothing special about add(x,y) it will return x+y. If m is a memory pointer then add(m, 32) returns m+32, ie it will reference the memory at m+32 bytes. – Ismael May 23 '18 at 1:15

Your Answer

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

Browse other questions tagged or ask your own question.