[Ethereum] Deploying contract with constructor arguments via Geth RPC

abiconstructorcontract-deploymentcontract-developmentjson-rpc

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

Best Answer

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
Related Topic