Browse Source

new conversion utility: scripts/tx-btc2bch.py

- Beginning with v0.9.5, BCH and BTC transaction files differ.
  This utility converts old BCH transaction files to the new format.
philemon 7 years ago
parent
commit
333278ce35
2 changed files with 104 additions and 9 deletions
  1. 42 9
      mmgen/tx.py
  2. 62 0
      scripts/tx-btc2bch.py

+ 42 - 9
mmgen/tx.py

@@ -157,8 +157,32 @@ class MMGenTX(MMGenObject):
 		for k in txio_attrs: locals()[k] = txio_attrs[k]
 		is_chg = MMGenListItemAttr('is_chg',bool,typeconv=False)
 
-	class MMGenTxInputList(list,MMGenObject): pass
-	class MMGenTxOutputList(list,MMGenObject): pass
+	class MMGenTxInputList(list,MMGenObject):
+
+		desc = 'transaction inputs'
+		member_type = 'MMGenTxInput'
+
+		def convert_coin(self,verbose=False):
+			from mmgen.protocol import CoinProtocol
+			io = getattr(MMGenTX,self.member_type)
+			if verbose:
+				msg('{}:'.format(self.desc.capitalize()))
+			for i in self:
+				d = i.__dict__
+				d['amt'] = g.proto.coin_amt(d['amt'])
+				i = io(**d)
+				if verbose:
+					pmsg(i.__dict__)
+
+		def check_coin_mismatch(self):
+			for i in self:
+				if type(i.amt) != g.proto.coin_amt:
+					die(2,'Coin mismatch in transaction: amount {} not of type {}!'.format(i.amt,g.proto.coin_amt))
+
+	class MMGenTxOutputList(MMGenTxInputList):
+
+		desc = 'transaction outputs'
+		member_type = 'MMGenTxOutput'
 
 	def __init__(self,filename=None,md_only=False):
 		self.inputs      = self.MMGenTxInputList()
@@ -435,6 +459,8 @@ class MMGenTX(MMGenObject):
 		self.blockcount = int(g.rpch.getblockcount())
 
 	def format(self):
+		self.inputs.check_coin_mismatch()
+		self.outputs.check_coin_mismatch()
 		lines = [
 			'{}{} {} {} {} {}'.format(
 				(g.coin+' ','')[g.coin=='BTC'],
@@ -678,16 +704,23 @@ class MMGenTX(MMGenObject):
 			ask_write=ask_write,
 			ask_write_default_yes=ask_write_default_yes)
 
-	def write_to_file(self,add_desc='',ask_write=True,ask_write_default_yes=False,ask_tty=True,ask_overwrite=True):
+	def write_to_file(  self,
+						add_desc='',
+						ask_write=True,
+						ask_write_default_yes=False,
+						ask_tty=True,
+						ask_overwrite=True,
+						fn=None):
 		if ask_write == False:
 			ask_write_default_yes=True
 		self.format()
-		fn = '{}{}[{}{}].{}'.format(
-			self.txid,
-			('-'+g.coin,'')[g.coin=='BTC'],
-			self.send_amt,
-			('',',{}'.format(self.btc2spb(self.get_fee())))[self.is_rbf()],
-			self.ext)
+		if not fn:
+			fn = '{}{}[{}{}].{}'.format(
+				self.txid,
+				('-'+g.coin,'')[g.coin=='BTC'],
+				self.send_amt,
+				('',',{}'.format(self.btc2spb(self.get_fee())))[self.is_rbf()],
+				self.ext)
 		write_data_to_file(fn,self.fmt_data,self.desc+add_desc,
 			ask_overwrite=ask_overwrite,
 			ask_write=ask_write,

+ 62 - 0
scripts/tx-btc2bch.py

@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
+# Copyright (C)2013-2017 Philemon <mmgen-py@yandex.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+tx-btc2bch: Convert MMGen transaction files from BTC to BCH format
+"""
+
+from mmgen.common import *
+
+opts_data = lambda: {
+	'desc': """Convert {pnm} transaction files from BTC to BCH format""".format(pnm=g.proj_name),
+	'usage':'[opts] [mmgen transaction file]',
+	'options': """
+-h, --help         Print this help message
+--, --longhelp     Print help message for long options (common options)
+-v, --verbose      Produce more verbose output
+"""
+}
+
+cmd_args = opts.init(opts_data)
+
+if g.coin != 'BTC':
+	die(1,"This program must be run with --coin set to 'BTC'")
+
+if len(cmd_args) != 1: opts.usage()
+
+from mmgen.protocol import CoinProtocol
+
+import mmgen.tx
+tx = mmgen.tx.MMGenTX(cmd_args[0])
+
+if opt.verbose:
+	gmsg('Original transaction is in {} format'.format(g.coin))
+
+g.coin = 'BCH'
+g.proto = CoinProtocol(g.coin,g.testnet)
+
+reload(sys.modules['mmgen.tx'])
+
+if opt.verbose:
+	gmsg('Converting transaction to {} format'.format(g.coin))
+
+tx.inputs.convert_coin(verbose=opt.verbose)
+tx.outputs.convert_coin(verbose=opt.verbose)
+
+tx.desc = 'converted transaction'
+tx.write_to_file(ask_write=False,ask_overwrite=False)