Example #1
0
File: tx.py Project: voidp34r/mmgen
	def sign(self,tx_num_str,keys):

		if self.marked_signed():
			die(1,'Transaction is already signed!')

		self.die_if_incorrect_chain()

		if (self.has_segwit_inputs() or self.has_segwit_outputs()) and not g.proto.cap('segwit'):
			die(2,yellow("TX has Segwit inputs or outputs, but {} doesn't support Segwit!".format(g.coin)))

		qmsg('Passing {} key{} to {}'.format(len(keys),suf(keys,'s'),g.proto.daemon_name))

		if self.has_segwit_inputs():
			from mmgen.addr import KeyGenerator,AddrGenerator
			kg = KeyGenerator('std')
			ag = AddrGenerator('segwit')
			keydict = MMGenDict([(d.addr,d.sec) for d in keys])

		sig_data = []
		for d in self.inputs:
			e = dict([(k,getattr(d,k)) for k in ('txid','vout','scriptPubKey','amt')])
			e['amount'] = e['amt']
			del e['amt']
			if d.mmid and d.mmid.mmtype == 'S':
				e['redeemScript'] = ag.to_segwit_redeem_script(kg.to_pubhex(keydict[d.addr]))
			sig_data.append(e)

		msg_r('Signing transaction{}...'.format(tx_num_str))
		wifs = [d.sec.wif for d in keys]
		ret = g.rpch.signrawtransaction(self.hex,sig_data,wifs,g.proto.sighash_type,on_fail='return')

		from mmgen.rpc import rpc_error,rpc_errmsg
		if rpc_error(ret):
			errmsg = rpc_errmsg(ret)
			if 'Invalid sighash param' in errmsg:
				m  = 'This is not the BCH chain.'
				m += "\nRe-run the script without the --coin=bch option."
			else:
				m = errmsg
			msg(yellow(m))
			return False
		else:
			if ret['complete']:
#				Msg(pretty_hexdump(unhexlify(self.hex),cols=16)) # DEBUG
#				pmsg(make_chksum_6(unhexlify(self.hex)).upper())
				self.hex = ret['hex']
				self.compare_size_and_estimated_size()
				dt = DeserializedTX(self.hex)
				self.check_hex_tx_matches_mmgen_tx(dt)
				self.coin_txid = CoinTxID(dt['txid'],on_fail='return')
				self.check_sigs(dt)
				assert self.coin_txid == g.rpch.decoderawtransaction(self.hex)['txid'],(
											'txid mismatch (after signing)')
				msg('OK')
				return True
			else:
				msg('failed\n{} returned the following errors:'.format(g.proto.daemon_name.capitalize()))
				msg(repr(ret['errors']))
				return False
Example #2
0
    def sign(self, c, tx_num_str, keys):

        self.die_if_incorrect_chain()

        if g.coin == 'BCH' and (self.has_segwit_inputs()
                                or self.has_segwit_outputs()):
            die(
                2,
                yellow(
                    "Segwit inputs cannot be spent or spent to on the BCH chain!"
                ))

        qmsg('Passing {} key{} to bitcoind'.format(len(keys), suf(keys, 's')))

        if self.has_segwit_inputs():
            from mmgen.addr import KeyGenerator, AddrGenerator
            kg = KeyGenerator()
            ag = AddrGenerator('segwit')
            keydict = MMGenDict([(d.addr, d.sec) for d in keys])

        sig_data = []
        for d in self.inputs:
            e = dict([(k, getattr(d, k))
                      for k in ('txid', 'vout', 'scriptPubKey', 'amt')])
            e['amount'] = e['amt']
            del e['amt']
            if d.mmid and d.mmid.mmtype == 'S':
                e['redeemScript'] = ag.to_segwit_redeem_script(
                    kg.to_pubhex(keydict[d.addr]))
            sig_data.append(e)

        msg_r('Signing transaction{}...'.format(tx_num_str))
        ht = ('ALL',
              'ALL|FORKID')[g.coin == 'BCH']  # sighashtype defaults to 'ALL'
        wifs = [d.sec.wif for d in keys]
        #		keys.pmsg()
        #		pmsg(wifs)
        ret = c.signrawtransaction(self.hex,
                                   sig_data,
                                   wifs,
                                   ht,
                                   on_fail='return')

        from mmgen.rpc import rpc_error, rpc_errmsg
        if rpc_error(ret):
            errmsg = rpc_errmsg(ret)
            if 'Invalid sighash param' in errmsg:
                m = 'This is not the BCH chain.'
                m += "\nRe-run the script without the --aug1hf or --coin=bch option."
            else:
                m = errmsg
            msg(yellow(m))
            return False
        else:
            if ret['complete']:
                self.hex = ret['hex']
                vmsg('Signed transaction size: {}'.format(len(self.hex) / 2))
                dt = DeserializedTX(self.hex)
                txid = dt['txid']
                self.check_sigs(dt)
                assert txid == c.decoderawtransaction(
                    self.hex)['txid'], 'txid mismatch (after signing)'
                self.btc_txid = BitcoinTxID(txid, on_fail='return')
                msg('OK')
                return True
            else:
                msg('failed\nBitcoind returned the following errors:')
                msg(repr(ret['errors']))
                return False
Example #3
0
ag = AddrGenerator(('p2pkh', 'segwit')[bool(opt.segwit)])

if a and b:
    m = "Comparing address generators '{}' and '{}'"
    qmsg(green(m.format(g.key_generators[a - 1], g.key_generators[b - 1])))
    last_t = time.time()
    kg_a = KeyGenerator(a)
    kg_b = KeyGenerator(b)

    for i in range(rounds):
        if time.time() - last_t >= 0.1:
            qmsg_r('\rRound %s/%s ' % (i + 1, rounds))
            last_t = time.time()
        sec = PrivKey(os.urandom(32), compressed)
        a_addr = ag.to_addr(kg_a.to_pubhex(sec))
        b_addr = ag.to_addr(kg_b.to_pubhex(sec))
        vmsg('\nkey:  %s\naddr: %s\n' % (sec.wif, a_addr))
        if a_addr != b_addr:
            match_error(sec, sec.wif, a_addr, b_addr, a, b)
        if not opt.segwit:
            compressed = not compressed
    qmsg_r('\rRound %s/%s ' % (i + 1, rounds))

    qmsg(green(('\n', '')[bool(opt.verbose)] + 'OK'))
elif a and not fh:
    m = "Testing speed of address generator '{}'"
    qmsg(green(m.format(g.key_generators[a - 1])))
    from struct import pack, unpack
    seed = os.urandom(28)
    print 'Incrementing key with each round'