Both at signature creation and at verification the processing shall be done over the same data. Based on the description the following bytes shall be put together in an RLP-encoded form to be processed and hashed with Keccak-256 (non-NIST SHA3-256):
RLP(nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0)
At verification we can retrieve all these data from the raw_transaction which contains in addition the signature value parameters (v, r, s) as well:
RLP(nonce, gasPrice, gasLimit, to, value, data, v, r, s)
I have tried to do this verification (to perform public key recovery) with php-ecrecover. I have made some cross-tests, so it seems that base functions of php-ecrecover work correctly. I have used the valid transaction 0x0c79e3ae36150eb36d6a631cc8d6250db4b9b832a82ac58ea356357f5987debe in block 0xda214d1b1d458e7ae0e626b69a52a59d19762c51a53ff64813c4d31256282fdf. I have parsed the raw_transaction (0xf8708308f7da8506fc23ac0083015f9094ef9f4c1d4103d42e05d54063337086d6884aee9a880e0c8912851e356c801ba04ed3077c674d49918f3dce6e25781070fce36b915e4c36554e704556f6a3e00ba03974fb9426ce34d0c520f1245e75f5b14a62795dd01c69063079a5353eb6cfb7) element of this transaction at MyCrypto.com.
{
"nonce": 587738, //0x08f7da
"gasPrice": {
"type": "BigNumber",
"hex": "0x06fc23ac00"
},
"gasLimit": {
"type": "BigNumber",
"hex": "0x015f90"
},
"to": "0xeF9F4c1d4103D42E05d54063337086D6884aEe9a",
"value": {
"type": "BigNumber",
"hex": "0x0e0c8912851e356c"
},
"data": "0x", //NULL??? 0x80???
"chainId": 0, //0x00
"v": 27, //0x1b
"r": "0x4ed3077c674d49918f3dce6e25781070fce36b915e4c36554e704556f6a3e00b",
"s": "0x3974fb9426ce34d0c520f1245e75f5b14a62795dd01c69063079a5353eb6cfb7",
"from": "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",
"hash": "0x0c79e3ae36150eb36d6a631cc8d6250db4b9b832a82ac58ea356357f5987debe",
"type": null
}
I have put together the data-to-be-hashed in an RLP-encoded form (Recursive Length Prefix). I have verified it with an online RLP Debugger. From RLP-encoding syntax aspect it seems to be correct, but I am not sure whether NULL value of data is correctly set based on RLP standard, or even 0 value of chainId and r and s are properly encoded at the end of data-to-be-processed string...
data-to-be-processed (RLP(nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0)) f8308308f7da8506fc23ac0083015f9094ef9f4c1d4103d42e05d54063337086d6884aee9a880e0c8912851e356c80000000
signature (r + s + v with no length) 4ed3077c674d49918f3dce6e25781070fce36b915e4c36554e704556f6a3e00b3974fb9426ce34d0c520f1245e75f5b14a62795dd01c69063079a5353eb6cfb71b
But, unfortunately the calculated value (provided by php-ecrecover) and the expected value (provided by MyCrypto) differs:
calculated value: 0x50d2a6dab68933716b9226db43884233dcdca315
expected value: 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8
What am I wrong? Are the RLP-encoded NULL and 0 values correct in my data-to-be-processed string (80000000)?
f08308f7da8506fc23ac0083015f9094ef9f4c1d4103d42e05d54063337086d6884aee9a880e0c8912851e356c80018080
.chainId
,r
,s
weren't hashed.