signed.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/env python3
  2. #
  3. # MMGen Wallet, a terminal-based cryptocurrency wallet
  4. # Copyright (C)2013-2024 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen-wallet
  9. # https://gitlab.com/mmgen/mmgen-wallet
  10. """
  11. proto.eth.tx.signed: Ethereum signed transaction class
  12. """
  13. from ....tx import signed as TxBase
  14. from ....obj import CoinTxID, ETHNonce, HexStr
  15. from ....addr import CoinAddr, TokenAddr
  16. from .completed import Completed, TokenCompleted
  17. class Signed(Completed,TxBase.Signed):
  18. desc = 'signed transaction'
  19. def parse_txfile_serialized_data(self):
  20. from ..pyethereum.transactions import Transaction
  21. from .. import rlp
  22. etx = rlp.decode(bytes.fromhex(self.serialized),Transaction)
  23. d = etx.to_dict() # ==> hex values have '0x' prefix, 0 is '0x'
  24. for k in ('sender','to','data'):
  25. if k in d:
  26. d[k] = d[k].replace('0x','',1)
  27. o = {
  28. 'from': CoinAddr(self.proto,d['sender']),
  29. # NB: for token, 'to' is token address
  30. 'to': CoinAddr(self.proto,d['to']) if d['to'] else None,
  31. 'amt': self.proto.coin_amt(d['value'], from_unit='wei'),
  32. 'gasPrice': self.proto.coin_amt(d['gasprice'], from_unit='wei'),
  33. 'startGas': self.proto.coin_amt(d['startgas'], from_unit='wei'),
  34. 'nonce': ETHNonce(d['nonce']),
  35. 'data': HexStr(d['data']) }
  36. if o['data'] and not o['to']: # token- or contract-creating transaction
  37. # NB: could be a non-token contract address:
  38. o['token_addr'] = TokenAddr(self.proto,etx.creates.hex())
  39. self.disable_fee_check = True
  40. txid = CoinTxID(etx.hash.hex())
  41. assert txid == self.coin_txid,"txid in tx.serialized doesn't match value in MMGen transaction file"
  42. self.gas = o['startGas'] # approximate, but better than nothing
  43. self.txobj = o
  44. return d # 'token_addr','decimals' required by Token subclass
  45. class TokenSigned(TokenCompleted,Signed):
  46. desc = 'signed transaction'
  47. def parse_txfile_serialized_data(self):
  48. raise NotImplementedError(
  49. 'Signed transaction files cannot be parsed offline, because tracking wallet is required!')
  50. class AutomountSigned(TxBase.AutomountSigned, Signed):
  51. pass
  52. class TokenAutomountSigned(TxBase.AutomountSigned, TokenSigned):
  53. pass