Recuperar la firma de una transacción en la cadena de bloques

¿Cómo se puede encontrar la firma de una transacción? web3.eth.getTransaction()no parece que esté disponible.

La firma de transacciones no está disponible para API comunes como JavaScript web3 y JSON RPC.
¿Por qué lo necesitas?
Las transacciones sin procesar, incluida la firma, están disponibles en otras implementaciones de blockchain, como Bitcoin. ¿Por qué no en Ethereum?
Es porque ethereum no necesita almacenar todas las firmas de transacciones, ya que está basado en estado, no en UTXO.
buena informacion Entonces, ¿Ethereum realmente almacena firmas de transacciones?
@TjadenHess, publique su comentario como respuesta y posiblemente elimine esta pregunta de la categoría Sin respuesta.

Respuestas (3)

Esto se puede hacer usando EthereumJS: una colección de bibliotecas y utilidades para Ethereum. https://github.com/ethereumjs

Primero, obtenga la codificación sin procesar del bloque que contiene su transacción de destino. Esto se puede hacer en live.ether.camp.

Alternativamente, si no desea copiar desde live.ether.camp, puede recuperar las codificaciones de bloque sin procesar cargando sus datos de cadena de Ethereum en un leveldb y consultando por blockhash.

Finalmente, usando ethereumjs (vea los módulos ethereumjs-block y ethereumjs-tx) puede recuperar fácilmente las firmas de transacciones.

La firma de transacciones no está disponible para API comunes como JavaScript web3 y JSON RPC

  • Pawel Bylica

La siguiente pregunta natural es: ¿Por qué no?

Ethereum no necesita almacenar todas las firmas de transacciones, ya que se basa en el estado, no en UTXO (Conjunto de salida de transacciones no gastadas)

  • tjaden hess

La siguiente pregunta natural es: ¿Qué es UTXO y qué tiene que ver con las transacciones y por qué Ethereum no tiene UTXO?

Vitalik escribe sobre UTXO aquí . Puntos clave resumidos a continuación.

¿Qué es UTXO y qué tiene que ver con las transacciones?

En Bitcoin, la forma en que una transacción realmente funciona "bajo el capó" es que consume una colección de objetos llamados salidas de transacción no gastadas ("UTXO") creados por una o más transacciones anteriores, y luego produce uno o más UTXO nuevos, que luego puede ser consumido por transacciones futuras... Por lo tanto, el saldo de un usuario no se almacena como un número; más bien, se puede calcular como la suma total de las denominaciones de UTXO que poseen.

¿Por qué Ethereum no hace esto?

  1. Los UTXO son innecesariamente complicados, y la complejidad es aún mayor en la implementación que en la teoría.

  2. Los UTXO no tienen estado, por lo que no se adaptan bien a aplicaciones más complejas que la emisión y transferencia de activos que generalmente tienen estado, como varios tipos de contratos inteligentes.

Está claro cómo los UTXO no encajan bien con los contratos inteligentes con estado: si existe la necesidad de crear un contrato con múltiples fases, p. donde varias partes deben proporcionar algún tipo de entrada, luego de un período de tiempo esas partes deben realizar alguna operación adicional, y finalmente el contrato desembolsa fondos como una función de esas operaciones, entonces es difícil ver cómo encajar ese modelo en fundamentalmente objetos sin estado que solo pueden gastarse o no gastarse.

En resumen, no hay una razón real por la que necesite una firma para Ethereum, razón por la cual las API comunes no la proporcionan.

Por ahora (febrero de 2019) hay una firma en eth_getTransactionByHashJSON RPC.

así es como puede recuperar una firma de 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'

Puede usarlo más, por ejemplo, para recuperar la clave pública del firmante.

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'