15

How can I deploy a compiled contract with constructor arguments using geth rpc?

I have tested my call deployed the compiled contract bytecode just fine, I just don't understand how I can pass constructor arguments via an rpc call in the form:

{'jsonrpc': '2.0', 'method': 'eth_sendTransaction', 'params': [{'from': account, 'contract': contract}], 'id': 1}

Thanks

1 Answer 1

19

It is quite complicated to get this correct, but here's some information on how to work it out.

I'm using a simple contract as an example:

pragma solidity ^0.4.2;

contract Test {
    uint256 public v1;
    string public v2;

    function Test(uint256 _v1, string _v2) {
        v1 = _v1;
        v2 = _v2;
    }
}

Here is my deployment to a --dev blockchain using Browser Solidity:

enter image description here

Here's the bytecode from the Browser Solidity:

6060604052604051610235380380610235833981016040528051608051909101600082815581516001805492819052916020601f60026000196101008588161502019093169290920482018190047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf69081019392909186019083901060b657805160ff19168380011785555b5060a49291505b8082111560e357600081556001016092565b5050505061014e806100e76000396000f35b82800160010185558215608b579182015b82811115608b57825182600050559160200191906001019060c7565b509056606060405260e060020a60003504636854171d8114610029578063f3acae3a14610037575b610002565b346100025761009b60005481565b34610002576100ad60018054604080516020601f6002600019610100878916150201909516949094049384018190048102820181019092528281529291908301828280156101465780601f1061011b57610100808354040283529160200191610146565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161012957829003601f168201915b50505050508156

Before deploying the contract to the --dev blockchain, I ran the command debug.verbosity(4) in the geth console command line. When Browser Solidity is deploying the contract, the following information is displayed in geth:

I1222 14:09:50.670663 core/tx_pool.go:542] Promoting queued transaction:

TX(92a1308637d6ad0a63b181194701114780afdaacfcd73604a1f7f3b6985b9755)

Contract: false

From: 000d1009bd8f0b1301cc5edc28ed1222a3ce671e

To: [contract creation]

Nonce: 457

GasPrice: 20000000000

GasLimit 198696

Value: 0

Data: 0x6060604052604051610235380380610235833981016040528051608051909101600082815581516001805492819052916020601f60026000196101008588161502019093169290920482018190047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf69081019392909186019083901060b657805160ff19168380011785555b5060a49291505b8082111560e357600081556001016092565b5050505061014e806100e76000396000f35b82800160010185558215608b579182015b82811115608b57825182600050559160200191906001019060c7565b509056606060405260e060020a60003504636854171d8114610029578063f3acae3a14610037575b610002565b346100025761009b60005481565b34610002576100ad60018054604080516020601f6002600019610100878916150201909516949094049384018190048102820181019092528281529291908301828280156101465780601f1061011b57610100808354040283529160200191610146565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161012957829003601f168201915b50505050508156000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20576f726c642100000000000000000000000000000000000000

V: 0x1c

R: 0xe84786ff0c0ed7564a972d3e037ef74d9adada759f845f36246e818f987d2945

S: 0x38ce5aa5b1a283f3270acd4668e99d410cd7f65ac74f4ae72416b0068935bd51

Hex: f9030a8201c98504a817c800830308288080b902b56060604052604051610235380380610235833981016040528051608051909101600082815581516001805492819052916020601f60026000196101008588161502019093169290920482018190047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf69081019392909186019083901060b657805160ff19168380011785555b5060a49291505b8082111560e357600081556001016092565b5050505061014e806100e76000396000f35b82800160010185558215608b579182015b82811115608b57825182600050559160200191906001019060c7565b509056606060405260e060020a60003504636854171d8114610029578063f3acae3a14610037575b610002565b346100025761009b60005481565b34610002576100ad60018054604080516020601f6002600019610100878916150201909516949094049384018190048102820181019092528281529291908301828280156101465780601f1061011b57610100808354040283529160200191610146565b60408051918252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161012957829003601f168201915b50505050508156000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20576f726c6421000000000000000000000000000000000000001ca0e84786ff0c0ed7564a972d3e037ef74d9adada759f845f36246e818f987d2945a038ce5aa5b1a283f3270acd4668e99d410cd7f65ac74f4ae72416b0068935bd51

Sending the Data: part above as the data: parameter in your JSON-RPC eth_sendTransaction transaction will achieve the same action of deploying the contract onto the blockchain with the same constructor arguments.

You can see the first part of the Data: field (not bolded) matching the contract bytecode, and the second part of the Data: field (bolded) represents the constructor arguments.

The constructor arguments are:

// _v1: 0x7b = 123
000000000000000000000000000000000000000000000000000000000000007b
// 0x40 = 64. This is the offset from the beginning of _v1
// directly above to the start of the next set of hex strings
// ending below
0000000000000000000000000000000000000000000000000000000000000040
// 0xd = 13 - the length of the "Hello, World!" string
000000000000000000000000000000000000000000000000000000000000000d
// In geth, 
// > web3.toUtf8("48656c6c6f2c20576f726c642100000000000000000000000000000000000000")
// "Hello, World!"
48656c6c6f2c20576f726c642100000000000000000000000000000000000000

Further references:



Responding to comment below

I've added two more examples to demonstrate the calculation of the offsets.

Example 2

pragma solidity ^0.4.2;

contract Test {
    uint256 public v1;
    uint256 public v2;
    string public v3;

    function Test(uint256 _v1, uint256 _v2, string _v3) {
        v1 = _v1;
        v2 = _v2;
        v3 = _v3;
    }
}

Deployed contract above with the following parameters:

123,456,"thequickbrownfoxjumpsoverthelazydog"

Here is the data to deploy the contract with the constructor, with the parameters bolded:

0x60606040526040516102de3803806102de833981016040528080519060200190919080519060200190919080518201919060200150505b82600060005081905550816001600050819055508060026000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009957805160ff19168380011785556100ca565b828001600101855582156100ca579182015b828111156100c95782518260005055916020019190600101906100ab565b5b5090506100f591906100d7565b808211156100f157600081815060009055506001016100d7565b5090565b50505b5050506101d5806101096000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480636257a38e146100525780636854171d146100d2578063f3acae3a146100fa5761004d565b610002565b34610002576100646004805050610122565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100c45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610002576100e460048050506101c3565b6040518082815260200191505060405180910390f35b346100025761010c60048050506101cc565b6040518082815260200191505060405180910390f35b60026000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101bb5780601f10610190576101008083540402835291602001916101bb565b820191906000526020600020905b81548152906001019060200180831161019e57829003601f168201915b505050505081565b60006000505481565b6001600050548156000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000023746865717569636b62726f776e666f786a756d70736f7665727468656c617a79646f670000000000000000000000000000000000000000000000000000000000

// _v1: 0x7b = 123
000000000000000000000000000000000000000000000000000000000000007b
// _v2: 0x1c8 = 456
00000000000000000000000000000000000000000000000000000000000001c8
// 0x60 = 96. This is the offset from the start of _v1 to the
// start of v3. 32 x 3 = 96
0000000000000000000000000000000000000000000000000000000000000060
// _v3: 0x23 = 35
0000000000000000000000000000000000000000000000000000000000000023
// In geth:
// > web3.toUtf8("746865717569636b62726f776e666f786a756d70736f7665727468656c617a79646f67")
// "thequickbrownfoxjumpsoverthelazydog" (35 chars)
746865717569636b62726f776e666f786a756d70736f7665727468656c617a79
646f670000000000000000000000000000000000000000000000000000000000

Example 3

pragma solidity ^0.4.2;

contract Test {
    uint256 public v1;
    uint256 public v2;
    string public v3;
    string public v4;

    function Test(uint256 _v1, uint256 _v2, string _v3, string _v4) {
        v1 = _v1;
        v2 = _v2;
        v3 = _v3;
        v4 = _v4;
    }
}

Deployed contract above with the following parameters:

123,456,"thequickbrownfoxjumpsoverthelazydog","shesellsseashellsontheseashore"

Here is the data to deploy the contract with the constructor, with the parameters bolded:

0x60606040526040516104c13803806104c1833981016040528080519060200190919080519060200190919080518201919060200180518201919060200150505b83600060005081905550826001600050819055508160026000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a257805160ff19168380011785556100d3565b828001600101855582156100d3579182015b828111156100d25782518260005055916020019190600101906100b4565b5b5090506100fe91906100e0565b808211156100fa57600081815060009055506001016100e0565b5090565b50508060036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061014f57805160ff1916838001178555610180565b82800160010185558215610180579182015b8281111561017f578251826000505591602001919060010190610161565b5b5090506101ab919061018d565b808211156101a7576000818150600090555060010161018d565b5090565b50505b50505050610301806101c06000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480636257a38e1461005d5780636854171d146100dd578063bfa5750314610105578063f3acae3a1461018557610058565b610002565b346100025761006f60048050506101ad565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610002576100ef600480505061024e565b6040518082815260200191505060405180910390f35b34610002576101176004805050610257565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156101775780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b346100025761019760048050506102f8565b6040518082815260200191505060405180910390f35b60026000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102465780601f1061021b57610100808354040283529160200191610246565b820191906000526020600020905b81548152906001019060200180831161022957829003601f168201915b505050505081565b60006000505481565b60036000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102f05780601f106102c5576101008083540402835291602001916102f0565b820191906000526020600020905b8154815290600101906020018083116102d357829003601f168201915b505050505081565b6001600050548156000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c8000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000023746865717569636b62726f776e666f786a756d70736f7665727468656c617a79646f670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e73686573656c6c737365617368656c6c736f6e74686573656173686f72650000

And here is the decoding of the parameters:

// _v1: 0x7b = 123
000000000000000000000000000000000000000000000000000000000000007b
// _v2: 0x1c8 = 456
00000000000000000000000000000000000000000000000000000000000001c8
// 0x80 = 128. This is the offset from the start of _v1 to the
// start of v3. 32 + 32 + 32 + 32 = 128
0000000000000000000000000000000000000000000000000000000000000080
// 0xe0 = 224. This is the offset from the start of _v1 to the
// start of v4. 32 x 7 = 224
00000000000000000000000000000000000000000000000000000000000000e0
// _v3: 0x23 = 35
0000000000000000000000000000000000000000000000000000000000000023
// In geth:
// > web3.toUtf8("746865717569636b62726f776e666f786a756d70736f7665727468656c617a79646f67")
// "thequickbrownfoxjumpsoverthelazydog" (35 chars)
746865717569636b62726f776e666f786a756d70736f7665727468656c617a79
646f670000000000000000000000000000000000000000000000000000000000
// v4: 0x1e = 30
000000000000000000000000000000000000000000000000000000000000001e
// In geth:
// > web3.toUtf8("73686573656c6c737365617368656c6c736f6e74686573656173686f72650000")
// "shesellsseashellsontheseashore" (30 chars)
73686573656c6c737365617368656c6c736f6e74686573656173686f72650000
3
  • 1
    Thanks, that helps out loads, I read online the arguments somehow had to come after the bytecode but I wasn't sure in what form. The only part I don't understand is the "0x40" used for the offset? 64 is the offset of the integer? Commented Dec 23, 2016 at 2:08
  • 2
    I've added another 2 examples to demonstrate the use of the offset. Commented Dec 23, 2016 at 3:22
  • 1
    Very comprehensive examples, thanks for your time! Commented Jan 6, 2017 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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