tx-old2new.py 3.0 KB

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