online.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2023 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.btc.tx.online: Bitcoin online signed transaction class
  12. """
  13. import mmgen.tx.online as TxBase
  14. from .signed import Signed
  15. from ....util import msg,ymsg,rmsg,die
  16. class OnlineSigned(Signed,TxBase.OnlineSigned):
  17. async def send(self,prompt_user=True,exit_on_fail=False):
  18. self.check_correct_chain()
  19. if not self.cfg.bogus_send:
  20. if self.has_segwit_outputs() and not self.rpc.info('segwit_is_active'):
  21. die(2,'Transaction has Segwit outputs, but this blockchain does not support Segwit'
  22. + ' at the current height')
  23. if self.fee > self.proto.max_tx_fee:
  24. die(2,'Transaction fee ({}) greater than {} max_tx_fee ({} {})!'.format(
  25. self.fee,
  26. self.proto.name,
  27. self.proto.max_tx_fee,
  28. self.proto.coin ))
  29. await self.status.display()
  30. if prompt_user:
  31. self.confirm_send()
  32. if self.cfg.bogus_send:
  33. ret = None
  34. else:
  35. try:
  36. ret = await self.rpc.call('sendrawtransaction',self.serialized)
  37. except Exception as e:
  38. errmsg = str(e)
  39. ret = False
  40. if ret == False: # TODO: test send errors
  41. if errmsg.count('Signature must use SIGHASH_FORKID'):
  42. m = ('The Aug. 1 2017 UAHF has activated on this chain.\n'
  43. + 'Re-run the script with the --coin=bch option.' )
  44. elif errmsg.count('Illegal use of SIGHASH_FORKID'):
  45. m = ('The Aug. 1 2017 UAHF is not yet active on this chain.\n'
  46. + 'Re-run the script without the --coin=bch option.' )
  47. elif errmsg.count('64: non-final'):
  48. m = "Transaction with nLockTime {!r} can't be included in this block!".format(
  49. self.strfmt_locktime(self.get_serialized_locktime()) )
  50. else:
  51. m = errmsg
  52. ymsg(m)
  53. rmsg(f'Send of MMGen transaction {self.txid} failed')
  54. if exit_on_fail:
  55. sys.exit(1)
  56. return False
  57. else:
  58. if self.cfg.bogus_send:
  59. m = 'BOGUS transaction NOT sent: {}'
  60. else:
  61. m = 'Transaction sent: {}'
  62. assert ret == self.coin_txid, 'txid mismatch (after sending)'
  63. msg(m.format(self.coin_txid.hl()))
  64. self.add_timestamp()
  65. self.add_blockcount()
  66. self.desc = 'sent transaction'
  67. return True
  68. def print_contract_addr(self):
  69. pass