diff --git a/CHANGELOG.md b/CHANGELOG.md index 103095b2e88..ab57f9b44f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,6 +141,7 @@ Released with 1.0.0-beta.37 code base. ### Added +- Add revert reason support to sendSignedTransaction - ENS module extended with the possibility to add a custom registry (#3301) - Missing ENS Registry methods and Resolver.supportsInterface method added (#3325) diff --git a/packages/web3-core-method/src/index.js b/packages/web3-core-method/src/index.js index f1031ed2325..3d4a06ed1fd 100644 --- a/packages/web3-core-method/src/index.js +++ b/packages/web3-core-method/src/index.js @@ -235,6 +235,13 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { params: 2, inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] }), + new Method({ + name: 'getTransactionByHash', + call: 'eth_getTransactionByHash', + params: 1, + inputFormatter: [null], + outputFormatter: formatters.outputTransactionFormatter + }), new Subscriptions({ name: 'subscribe', type: 'eth', @@ -421,10 +428,29 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { try { var revertMessage = null; - if (method.handleRevert && method.call === 'eth_sendTransaction') { + if ( method.handleRevert && + (method.call === 'eth_sendTransaction' || method.call === 'eth_sendRawTransaction')) + { + var txReplayOptions = payload.params[0]; + + // If send was raw, fetch the transaction and reconstitute the + // original params so they can be replayed with `eth_call` + if (method.call === 'eth_sendRawTransaction'){ + var txToReplay = await _ethereumCall.getTransactionByHash(receipt.transactionHash); + + txReplayOptions = formatters.inputTransactionFormatter({ + data: txToReplay.input, + to: txToReplay.to, + from: txToReplay.from, + gas: txToReplay.gas, + gasPrice: txToReplay.gasPrice, + value: txToReplay.value + }) + } + // Get revert reason string with eth_call revertMessage = await method.getRevertReason( - payload.params[0], + txReplayOptions, receipt.blockNumber ); diff --git a/packages/web3-eth/src/index.js b/packages/web3-eth/src/index.js index 630ce47a618..e42ed09f006 100644 --- a/packages/web3-eth/src/index.js +++ b/packages/web3-eth/src/index.js @@ -460,7 +460,8 @@ var Eth = function Eth() { name: 'sendSignedTransaction', call: 'eth_sendRawTransaction', params: 1, - inputFormatter: [null] + inputFormatter: [null], + abiCoder: abi }), new Method({ name: 'signTransaction', diff --git a/packages/web3-eth/types/index.d.ts b/packages/web3-eth/types/index.d.ts index 2fc9df1b2fb..0e0d6404bf4 100644 --- a/packages/web3-eth/types/index.d.ts +++ b/packages/web3-eth/types/index.d.ts @@ -300,7 +300,7 @@ export class Eth { sendSignedTransaction( signedTransactionData: string, callback?: (error: Error, hash: string) => void - ): PromiEvent; + ): PromiEvent; sign( dataToSign: string, diff --git a/packages/web3-eth/types/tests/eth.tests.ts b/packages/web3-eth/types/tests/eth.tests.ts index 2f7bac7de4a..b913880e546 100644 --- a/packages/web3-eth/types/tests/eth.tests.ts +++ b/packages/web3-eth/types/tests/eth.tests.ts @@ -393,9 +393,9 @@ eth.sendTransaction( (error: Error, hash: string) => {} ); -// $ExpectType PromiEvent +// $ExpectType PromiEvent eth.sendSignedTransaction('0xf889808609184e72a0008227109'); -// $ExpectType PromiEvent +// $ExpectType PromiEvent eth.sendSignedTransaction( '0xf889808609184e72a0008227109', (error: Error, hash: string) => {} diff --git a/test/e2e.method.signing.js b/test/e2e.method.signing.js index ae51b22c005..2bfc6f7d25a 100644 --- a/test/e2e.method.signing.js +++ b/test/e2e.method.signing.js @@ -313,6 +313,35 @@ describe('transaction and message signing [ @E2E ]', function() { } }); + it('sendSignedTransaction reverts with reason', async function(){ + const data = instance + .methods + .reverts() + .encodeABI(); + + const source = wallet[0].address; + const txCount = await web3.eth.getTransactionCount(source); + + const txObject = { + nonce: web3.utils.toHex(txCount), + to: instance.options.address, + gasLimit: web3.utils.toHex(400000), + gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei')), + data: data + }; + + const signed = await web3.eth.accounts.signTransaction(txObject, wallet[0].privateKey); + + web3.eth.handleRevert = true; + try { + await web3.eth.sendSignedTransaction(signed.rawTransaction); + assert.fail(); + } catch(err){ + assert.equal(err.receipt.status, false); + assert.equal(err.reason, "REVERTED WITH REVERT"); + } + }); + it('transactions sent with wallet error correctly (OOG)', function(done){ const data = instance .methods