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:
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