Middleware to sign transactions locally
See original GitHub issue- Version: 4
What was wrong?
It would be convenient to use the Web3.eth
interface as if you were using your node’s account management features, even if the key is only available locally.
Basically, we want this to work:
from web3.auto import w3
# some middleware setup on w3, with private key 0x000...0001
w3.eth.sendTransaction({ ... normal transaction ... , 'from': '0xAccountForPrivateKey1'})
How can it be fixed?
Intercept and Sign Transaction Middleware
A reasonable approach is to add a new middleware that is configured with a private key. It would look for transactions from the account with the associated private key, sign it locally, and send it to the node already signed.
This new middleware should live in it’s own module under web3.middleware
. It should probably be implemented as a factory similar to how web3.middleware.fixture.construct_fixture_middleware
is done.
This new middleware could be called something like one of the following names.
intercept_and_sign_transaction_middleware
transaction_signing_middleware
in_flight_transaction_signing_middleware
- or anything else that captures what it does
The factory function should at minimum accept a PrivateKey
object from the eth-keys
API. The middleware would then behave as follows.
- if the
method
is not"eth_sendTransaction"
then do nothing.
We can then pull the transaction object out of the params
.
- if the
from
key in the transaction object is not the same address as the one generated from our private key then do nothing.
Now that we know that the RPC request is to eth_sendTransaction
and that the from
address of the transaction matches our private key, we do the following.
- sign the transaction using our private key and rlp encode it into the hex encoded raw transaction format.
- call
make_request
withmethod="eth_sendRawTransaction", params=[hex_encoded_raw_transaction]
The logic for signing is already present in the web3.utils.signing.LocalAccount
object and should be re-used in some format.
Extra considerations
- For convenience, it would be good for the middleware factory function to accept the key in any of the following formats.
- raw bytes
- hex encoded string
PrivateKey
object frometh-keys
LocalAccount
object as returned by theweb3.eth.account
API
- Nonce handling
- The
nonce
field will almost always need to be filled in. This can be done naively via callingmake_request(method='eth_getTransactionCount', params=[the_from_address])
.
- The
- Other optional txn fields
- We’ll also need to fill in the other optional fields for the transaction.
gas
viaeth_estimateGas
gas_price
viaeth_gasPrice
: also see #494
Issue Analytics
- State:
- Created 6 years ago
- Comments:27 (19 by maintainers)
Top GitHub Comments
Also – WIP pull request is open now. #517
#649 has been merged.