Trying to sign and send a raw transaction produces an error indicating the RPC request is invalid.
from web3 import Web3, HTTPProvider
w3 = Web3(HTTPProvider('https://mainnet.infura.io'))
transaction = {
'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
'value': 1000000000,
'gas': 2000000,
'gasPrice': 234567897654321,
'nonce': 0,
'chainId': 1
}
key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
signed = w3.eth.account.signTransaction(transaction, key)
print(Web3.toHex(signed.rawTransaction))
tx = w3.eth.sendRawTransaction(signed.rawTransaction)
Traceback (most recent call last):
File "justtesting.py", line 14, in <module>
tx = w3.eth.sendRawTransaction(signed.rawTransaction)
File "/Users/monokh/Code/web3.py/web3/eth.py", line 222, in sendRawTransaction
[raw_transaction],
File "/Users/monokh/Code/web3.py/web3/manager.py", line 92, in request_blocking
raise ValueError(response["error"])
ValueError: {'message': 'invalid argument 0: json: cannot unmarshal invalid hex string into Go value of type hexutil.Bytes', 'code': -32602}
testrpc produces similar error: ValueError: {'code': -32000, 'message': 'Error: Invalid SignatureThe web3py version produces the signed message: 0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428
The web3.js version produces an identical signed message.
Here's the web3.js version: ``
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io"));
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer('4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', 'hex')
var rawTx = {
'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
'value': web3.utils.toHex(1000000000),
'gas': web3.utils.toHex(2000000),
'gasPrice': web3.utils.toHex(234567897654321),
'nonce': web3.utils.toHex(0),
'chainId': 1
}
var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
if (!err) {
console.log(hash);
} else {
console.log(err);
}
});
So it seems the transaction signing is working correctly but something in the process of encoding that for the RPC request is going wrong.
ummm 馃槄 so right after i posted this issue, I tried this:
tx = w3.eth.sendRawTransaction(Web3.toHex(signed.rawTransaction)) instead of:
tx = w3.eth.sendRawTransaction(signed.rawTransaction)
which would matchup exactly with the web3.js API and i now get the error:
ValueError: {'message': 'insufficient funds for gas * price + value', 'code': -32000} which would mean it's working.
So is this the recommended way to do this? If so I can update the docs. Or otherwise do we want to do this conversion internally in sendRawTransaction ?
Thank you for the thoroughly researched/reported issue!
Your first instinct is right. It's a bug that this doesn't work:
tx = w3.eth.sendRawTransaction(signed.rawTransaction)
I tried this:
tx = w3.eth.sendRawTransaction(Web3.toHex(signed.rawTransaction))... it's working.
I would consider this a workaround, rather than the preferred approach.
@carver So would you say the intended behaviour would be for signTransaction to output the transaction in a 0x prefixed hex string or for sendRawTransaction to convert it to that format before sending it through?
@monokh sendRawTransaction should accept either bytes or a hex string. signTransaction is working as intended.
Released in v4.0.0-beta2
Most helpful comment
@monokh
sendRawTransactionshould accept either bytes or a hex string.signTransactionis working as intended.