Created
June 18, 2019 17:15
-
-
Save SurfingNerd/2be70efd789912b5a9a51d662c38ed40 to your computer and use it in GitHub Desktop.
Bug: Failing correct web3 extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Thomas Haller <[email protected]> | |
* @abstract showcases an issue creating a web3 transaction with RSV if R or S has a leading zeros | |
* Those leading zeros are optimized away by ethereumjs-tx but are required later by the RLP Logic. | |
* This code sample is designed to be easy adoptable to be picked up for an automatic test. | |
* it was tested with [email protected]. | |
* Since beta.51 ethereumjs-tx is referenced by web3. | |
* | |
* @see https://github.com/ethereumjs/ethereumjs-tx/issues/140 | |
*/ | |
const Web3 = require('web3') | |
const Tx = require('ethereumjs-tx'); | |
const web3_options = { | |
transactionConfirmationBlocks: 1, | |
defaultGasPrice: 1000000000 | |
} | |
const rpcAddress = 'http://127.0.0.1:9545/'; | |
var web3 = new Web3(rpcAddress, null, web3_options); | |
const txRaw = { | |
nonce: '0x00', | |
gasPrice: 1000000000, | |
gas: 21000, | |
to: '0x92d8099b5b4dd10234ec8f1f03e691aeea2f6527', | |
value: 1000 | |
}; | |
const tx = new Tx(txRaw); | |
const address = "0x0774fe042Bc23D01599B5A92b97B3125a4Cb20EE"; | |
// a valid signature for this transaction: | |
const r = "707f45cea1c62ded74d5a7ee2e40bebc4adf79f2cffc94e73527c5903b98cddb"; | |
const s = "00c3749242f56c7c06a842e516d43e97bd35e1127708a76277e998ea1257f6ed"; | |
const v = "1b"; | |
tx.r = "0x" + r; | |
tx.s = "0x" + s; | |
tx.v = "0x" + v; | |
var serializedTx = toHex(tx.serialize()); | |
var recoveredAddress; | |
try { | |
recoveredAddress = web3.eth.accounts.recoverTransaction(serializedTx) | |
console.assert(recoveredAddress == address, "Unexpected: recovery was success, but address is wrong:" + recoveredAddress) | |
console.log("hoorray - recover success - bug is fixed in web3 library: " + recoveredAddress); | |
return; | |
} catch(error) { | |
console.log("BUG is still here: RLP is wrong."); | |
} | |
//i am fixing the problem here by manipulating the serialized RLP string. | |
//i replace the problematic 31 byte long string with a 32 byte string | |
//and taking care about the RLP values as well. | |
// 9f is the size header in the case the leading zero has been optimized away | |
// a0 is the size header in the case where the leading zero is kept. | |
var searchString = "9f" + s.slice(2, 64); | |
var replaceString = "a0" + s; | |
console.log("searchString:" + searchString); | |
console.log("replaceString:" + replaceString); | |
serializedTx = serializedTx.replace(searchString, replaceString); | |
console.log("Repaired Transaction: " + serializedTx); | |
//now we have repaired the transaction and can prove that it is valid | |
try { | |
recoveredAddress = web3.eth.accounts.recoverTransaction(serializedTx) | |
console.assert(recoveredAddress == address, "Unexpected: recovery was success, but address is wrong:" + recoveredAddress) | |
console.log("recover success with repeaired transaction: " + recoveredAddress); | |
} catch(error) { | |
console.error("UNEXPECTED ERROR:", error); | |
} | |
function toHex(nonHex, prefix = true) { | |
let temp = nonHex.toString('hex'); | |
if (prefix) { | |
temp = `0x${temp}`; | |
} | |
return temp; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment