1

How can I encode the constructor arguments when deploying a contract?

Here is my deployment function:

async function deploy(abi, bin, args) {
    let contract = new this.web3.eth.Contract(JSON.parse(abi));
    let transaction = contract.deploy({data: "0x" + bin, arguments: args});
    let handle = await this.send(transaction);
    return new this.web3.eth.Contract(JSON.parse(abi), handle.contractAddress);
}

Inside this function, I can do the following:

  1. console.log(transaction.arguments);
  2. console.log(transaction.encodeABI());

The 1st option just prints the values of the arguments as is.

The second option prints the entire byte-code.

My encoded arguments indeed appear at the end of this byte-code.

But since I don't know the length of this suffix, I cannot easily "cut it" out of the byte-code.

One option I have in mind, is that the length of this suffix is 64 * args.length, since every argument is padded to 256-bits (64 hexadecimal digits).

But I don't think that this will work when some of the arguments are strings or arrays.

Is there any standard solution for this in web3.js?

Thank you!

  • Some additional observations: an array yields one additional "argument" which denotes the array-length (padded to 256 bits). This argument precedes the actual values in the array (each of which, also padded to 256 bits). – goodvibration Jan 9 at 11:56
1

I don't know about a standard solution, but the Solidity compiler can give you the binary data that will be placed on the blockchain through the bin-runtime command. This will be like the bin but without the constructor (the first part of the bin output) and the constructor arguments (the last part of the bin output). So you should be able to look at the end of bin-runtime and find where this occurs in the bin output. The first byte after this place should be the start of the ABI encoding of the constructor arguments.

  • I already wrote this in my question (quoting): My encoded arguments indeed appear at the end of this byte-code. But since I don't know the length of this suffix, I cannot easily "cut it" out of the byte-code.. So unless I'm missing something, I don't see how this answer adds anything to what I already know. I am looking for an automated way for extracting the constructor arguments encoded string from the deployed byte-code. – goodvibration Jan 9 at 12:08
  • My answer gives you a way of finding the length of the suffix. – Thorkil Værge Jan 9 at 12:09
  • So I need to look into the network (via etherscan or similar)? I already know how to do this, but it is not an automated way for achieving my purpose (and it is not via web3.js either). – goodvibration Jan 9 at 12:11
  • Do you have the source code of the contract you are deploying? I don't think you should have to look at the blockchain. You need to call the solidity compiler with the "bin-runtime" argument and compare that with the "bin" output. solc --bin-runtime file.sol – Thorkil Værge Jan 9 at 12:15
  • Oh, OK. In the answer that you've liked, I see eth.getCode(contractaddress) at the bottom. I will give it a try and update you. Thank you! – goodvibration Jan 9 at 12:20
1

OK, found a way to do this:

If the value of bin starts with 0x:

let encodedArgs = transaction.encodeABI().slice(bin.length)

If the value of bin does not start with 0x:

let encodedArgs = transaction.encodeABI().slice(2 + bin.length)

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.