signed.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2022 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
  9. # https://gitlab.com/mmgen/mmgen
  10. """
  11. proto.eth.tx.signed: Ethereum signed transaction class
  12. """
  13. import mmgen.tx.signed as TxBase
  14. from .completed import Completed,TokenCompleted
  15. from ..contract import Token
  16. from ....obj import Str,CoinTxID,ETHNonce,HexStr
  17. from ....addr import CoinAddr,TokenAddr
  18. from ....amt import ETHAmt
  19. class Signed(Completed,TxBase.Signed):
  20. desc = 'signed transaction'
  21. def parse_txfile_serialized_data(self):
  22. from ..pyethereum.transactions import Transaction
  23. from .. import rlp
  24. etx = rlp.decode(bytes.fromhex(self.serialized),Transaction)
  25. d = etx.to_dict() # ==> hex values have '0x' prefix, 0 is '0x'
  26. for k in ('sender','to','data'):
  27. if k in d:
  28. d[k] = d[k].replace('0x','',1)
  29. o = {
  30. 'from': CoinAddr(self.proto,d['sender']),
  31. # NB: for token, 'to' is token address
  32. 'to': CoinAddr(self.proto,d['to']) if d['to'] else Str(''),
  33. 'amt': ETHAmt(d['value'],'wei'),
  34. 'gasPrice': ETHAmt(d['gasprice'],'wei'),
  35. 'startGas': ETHAmt(d['startgas'],'wei'),
  36. 'nonce': ETHNonce(d['nonce']),
  37. 'data': HexStr(d['data']) }
  38. if o['data'] and not o['to']: # token- or contract-creating transaction
  39. # NB: could be a non-token contract address:
  40. o['token_addr'] = TokenAddr(self.proto,etx.creates.hex())
  41. self.disable_fee_check = True
  42. txid = CoinTxID(etx.hash.hex())
  43. assert txid == self.coin_txid,"txid in tx.serialized doesn't match value in MMGen transaction file"
  44. self.tx_gas = o['startGas'] # approximate, but better than nothing
  45. self.txobj = o
  46. return d # 'token_addr','decimals' required by Token subclass
  47. class TokenSigned(TokenCompleted,Signed):
  48. desc = 'signed transaction'
  49. def parse_txfile_serialized_data(self):
  50. raise NotImplementedError(
  51. 'Signed transaction files cannot be parsed offline, because tracking wallet is required!')