Send signed transaction from Trezor hardware wallet

Question:

I’ve been trying to code a simple web3.py program to send a transaction from my Trezor. I’m able to sign the transaction on my Trezor, and the function that does that (ethereum.sign_tx()) returns a tuple of the V, R, and S signatures of the transaction, which looks like:

(42, b"", b')

My question is how can I convert those signatures into a serialized form that I can send using the Web3.eth.sendRawTransaction() function. Full code is:

from trezorlib.client import get_default_client
from trezorlib.tools import parse_path
from trezorlib import ethereum
from web3 import Web3


def main():
    # Use first connected device
    client = get_default_client()
    ropsten = Web3(Web3.HTTPProvider("https://ropsten.infura.io/v3/7xxxxxxxxx23dee70e4aa"))


    # Get the first address of first BIP44 account
    # (should be the same address as shown in wallet.trezor.io)
    bip32_path = parse_path("44'/60'/0'/0/0")
    address = ethereum.get_address(client, bip32_path)
    nonce = ropsten.eth.getTransactionCount(address)
    tx = ethereum.sign_tx(client, bip32_path, nonce, Web3.toWei(1, 'gwei'), 21000, "0x7ccc4a67eB76b5B1C8Efc62672A6884A9B7bFDb7", Web3.toWei(1, 'ether'), chain_id=3)
    #sent = ropsten.eth.sendRawTransaction(tx)


if __name__ == "__main__":
    main()
Asked By: Isaac

||

Answers:

you can do what trezorctl does and use rlp.encode:

import rlp

gas_price = Web3.toWei(1, 'gwei')
gas_limit = 21000
to_addr = "0x7ccc4a67eB76b5B1C8Efc62672A6884A9B7bFDb7"
amount = Web3.toWei(1, 'ether')
data = b""
rlp_prefix = (nonce, gas_price, gas_limit, to_addr, amount, data)

sent = ropsten.eth.sendRawTransaction(rlp.encode(rlp_prefix + tx))
Answered By: matejcik
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.