tx-old2new.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env python
  2. import sys,os
  3. repo_root = os.path.split(os.path.abspath(os.path.dirname(sys.argv[0])))[0]
  4. sys.path = [repo_root] + sys.path
  5. from mmgen.common import *
  6. from mmgen.tool import *
  7. from mmgen.tx import *
  8. from mmgen.bitcoin import *
  9. from mmgen.obj import MMGenTXLabel
  10. from mmgen.seed import *
  11. from mmgen.term import do_pager
  12. help_data = {
  13. 'desc': "Convert MMGen transaction file from old format to new format",
  14. 'usage': "<tx file>",
  15. 'options': """
  16. -h, --help Print this help message
  17. -S, --stdout Write data to STDOUT instead of file
  18. """
  19. }
  20. import mmgen.opts
  21. cmd_args = opts.init(help_data)
  22. if len(cmd_args) != 1: opts.usage()
  23. def parse_tx_file(infile):
  24. err_str,err_fmt = '','Invalid %s in transaction file'
  25. tx_data = get_lines_from_file(infile)
  26. if len(tx_data) == 5:
  27. metadata,tx_hex,inputs_data,outputs_data,comment = tx_data
  28. elif len(tx_data) == 4:
  29. metadata,tx_hex,inputs_data,outputs_data = tx_data
  30. comment = ''
  31. else:
  32. err_str = 'number of lines'
  33. if not err_str:
  34. if len(metadata.split()) != 3:
  35. err_str = 'metadata'
  36. else:
  37. try: unhexlify(tx_hex)
  38. except: err_str = 'hex data'
  39. else:
  40. try: inputs_data = eval(inputs_data)
  41. except: err_str = 'inputs data'
  42. else:
  43. try: outputs_data = eval(outputs_data)
  44. except: err_str = 'btc-to-mmgen address map data'
  45. else:
  46. if comment:
  47. from mmgen.bitcoin import b58decode
  48. comment = b58decode(comment)
  49. if comment == False:
  50. err_str = 'encoded comment (not base58)'
  51. else:
  52. try:
  53. comment = MMGenTXLabel(comment)
  54. except:
  55. err_str = 'comment'
  56. if err_str:
  57. msg(err_fmt % err_str)
  58. sys.exit(2)
  59. else:
  60. return metadata.split(),tx_hex,inputs_data,outputs_data,comment
  61. def find_block_by_time(c,timestamp):
  62. secs = decode_timestamp(timestamp)
  63. block_num = c.getblockcount()
  64. # print 'secs:',secs, 'last block:',last_block
  65. top,bot = block_num,0
  66. m = 'Searching for block'
  67. msg_r(m)
  68. for i in range(40):
  69. msg_r('.')
  70. bhash = c.getblockhash(block_num)
  71. block = c.getblock(bhash)
  72. # print 'block_num:',block_num, 'mediantime:',block['mediantime'], 'target:',secs
  73. cur_secs = block['mediantime']
  74. if cur_secs > secs:
  75. top = block_num
  76. else:
  77. bot = block_num
  78. block_num = (top + bot) / 2
  79. if top - bot < 2:
  80. msg('\nFound: %s ' % block_num)
  81. break
  82. return block_num
  83. tx = MMGenTX()
  84. [tx.txid,send_amt,tx.timestamp],tx.hex,inputs,b2m_map,tx.label = parse_tx_file(cmd_args[0])
  85. tx.send_amt = Decimal(send_amt)
  86. g.testnet = False
  87. g.rpc_host = 'localhost'
  88. c = bitcoin_connection()
  89. # attrs = 'txid','vout','amt','comment','mmid','addr','wif'
  90. #pp_msg(inputs)
  91. for i in inputs:
  92. if not 'mmid' in i and 'account' in i:
  93. from mmgen.tw import parse_tw_acct_label
  94. a,b = parse_tw_acct_label(i['account'])
  95. if a:
  96. i['mmid'] = a.decode('utf8')
  97. if b: i['comment'] = b.decode('utf8')
  98. #pp_msg(inputs)
  99. tx.inputs = tx.decode_io_oldfmt(inputs)
  100. if tx.check_signed(c):
  101. msg('Transaction is signed')
  102. dec_tx = c.decoderawtransaction(tx.hex)
  103. tx.outputs = [MMGenTxOutput(addr=i['scriptPubKey']['addresses'][0],amt=i['value'])
  104. for i in dec_tx['vout']]
  105. for e in tx.outputs:
  106. if e.addr in b2m_map:
  107. f = b2m_map[e.addr]
  108. e.mmid = f[0]
  109. if f[1]: e.label = f[1].decode('utf8')
  110. else:
  111. for f in tx.inputs:
  112. if e.addr == f.addr and f.mmid:
  113. e.mmid = f.mmid
  114. if f.label: e.label = f.label.decode('utf8')
  115. #for i in tx.inputs: print i
  116. #for i in tx.outputs: print i
  117. #die(1,'')
  118. tx.blockcount = find_block_by_time(c,tx.timestamp)
  119. tx.write_to_file(ask_tty=False)