online.py 2.4 KB

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