4

How can you find the signature of a transaction? web3.eth.getTransaction() doesn't appear to make that available.

  • Transaction signature is not available by common APIs like JavaScript web3 and JSON RPC. – Paweł Bylica Mar 21 '16 at 22:11
  • Why do you need it? – Paweł Bylica Mar 21 '16 at 22:16
  • Raw transactions including the signature are available on other blockchain implementations such as Bitcoin. Why not on Ethereum? – dbryson Mar 22 '16 at 2:15
  • 2
    It's because ethereum doesn't need to store all transaction signatures, since it is state-based, not UTXO based – Tjaden Hess Mar 22 '16 at 17:46
  • Good info. So does Ethereum actually store transaction signatures at all? – dbryson Mar 22 '16 at 18:16
5

This can be done using EthereumJS: a collection of libraries and utilities for Ethereum. https://github.com/ethereumjs

First, obtain the raw encoding of the block containing your target transaction. This can be done on live.ether.camp.

Alternatively, if you don't want to copy from live.ether.camp, you can recover the raw block encodings by loading your Ethereum chaindata into a leveldb and querying by blockhash.

Finally, using ethereumjs (see ethereumjs-block and ethereumjs-tx modules) you can easily recover transaction signatures.

2

Transaction signature is not available by common APIs like JavaScript web3 and JSON RPC

  • Pawel Bylica

The next natural question is: Why not?

Ethereum doesn't need to store all transaction signatures, since it is state-based, not UTXO (Unspent Transaction Output Set) based

  • Tjaden Hess

The next natural question is: What is UTXO and what does it have to do with transactions and why doesn't Ethereum have UTXO?

Vitalik writes about UTXO here. Key points summarized below.

What is UTXO and what does it have to do with transactions?

In Bitcoin, the way that a transaction actually works “under the hood” is that it consumes a collection of objects called unspent transaction outputs (“UTXOs”) created by one or more previous transactions, and then produces one or more new UTXOs, which can then be consumed by future transactions...A user’s balance is thus not stored as a number; rather, it can be computed as the total sum of the denominations of UTXOs that they own.

Why doesn't Ethereum do this?

  1. UTXOs are unnecessarily complicated, and the complexity gets even greater in the implementation than in the theory.

  2. UTXOs are stateless, and so are not well-suited to applications more complex than asset issuance and transfer that are generally stateful, such as various kinds of smart contracts.

It is clear how UTXOs do not mesh well with stateful smart contracts: if there is a need to create a contract with multiple phases, eg. where multiple parties must provide some form of input, then after some period of time those parties must perform some additional operation, and then finally the contract disburses funds as a function of those operations, then it is difficult to see how to fit that model into fundamentally stateless objects that can only be spent or not spent.

In summation, there is no real reason you need signature for Ethereum which is why it isn't provided by common APIs.

0

As for now (Feb 2019) there is a signature in eth_getTransactionByHash JSON RPC.

here is how you can retrievie a signature from Python:

In [1]: import web3
w3=web3.Web3(web3.HTTPProvider('https://geth.golem.network:55555'))
t=w3.eth.getTransactionFromBlock(w3.eth.blockNumber, 0)
t.hash                                                                                                                                                                                                                              
Out[1]: HexBytes('0xf4bbed857cc67a5ad8f49f12926e6e9b87f550cdd82542310bf196c8e78b838c')

In [2]: from eth_account.internal.signing import extract_chain_id, to_standard_v
s=w3.eth.account._keys.Signature(vrs=(to_standard_v(extract_chain_id(t.v)[1]), w3.toInt(t.r), w3.toInt(t.s)))
type(s)
Out[2]: eth_keys.datatypes.Signature

In [3]: s
Out[3]: '0xf8b1b27aa4746ee1950dcc125e10103e9aba49bdc03e7ccd101b02b94f9c062f17995e4d31cb5a7d8252c5628ec55635d67ba4d853a9a49dae49a05db3b05cef00'

You can use it further for example for recovering the public key of the signer.

In [4]: from eth_account.internal.transactions import ALLOWED_TRANSACTION_KEYS, serializable_unsigned_transaction_from_dict    
tt={k:t[k] for k in ALLOWED_TRANSACTION_KEYS - {'chainId', 'data'}}    
tt['data']=t.input    
tt['chainId']=extract_chain_id(t.v)[0]
ut=serializable_unsigned_transaction_from_dict(tt)

In [5]: s.recover_public_key_from_msg_hash(ut.hash())
Out[5]: '0x58ed29a99e06f14a5b7dc33a3d670f3274dfa7ebe891c20e3b8df2aa5d1de12676a3a8ca747d703db52126197a743535640450bb1b89c68a3848129fe5751ac3'

In [6]: s.recover_public_key_from_msg_hash(ut.hash()).to_checksum_address()
Out[6]: '0x5E032243d507C743b061eF021e2EC7fcc6d3ab89'

In [6]: t['from']
Out[6]: '0x5E032243d507C743b061eF021e2EC7fcc6d3ab89'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.