Ejemplo n.º 1
0
Archivo: tx.py Proyecto: 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
Ejemplo n.º 2
0
def parse_arg1(arg, arg_id):

    m1 = 'First argument must be a numeric generator ID or two colon-separated generator IDs'
    m2 = 'Second part of first argument must be a numeric generator ID or one of {}'

    def check_gen_num(n):
        if not (1 <= int(n) <= len(g.key_generators)):
            die(1, '{}: invalid generator ID'.format(n))
        return int(n)

    if arg_id == 'a':
        if is_int(arg):
            a_num = check_gen_num(arg)
            return (KeyGenerator(proto, addr_type, a_num), a_num)
        else:
            die(1, m1)
    elif arg_id == 'b':
        if is_int(arg):
            return KeyGenerator(proto, addr_type, check_gen_num(arg))
        elif arg in ext_progs + ['ext']:
            return init_tool(get_tool(arg))
        else:
            die(1, m2.format(ext_progs))
Ejemplo n.º 3
0
    def _create_fake_unspent_data(self,
                                  adata,
                                  tx_data,
                                  non_mmgen_input='',
                                  non_mmgen_input_compressed=True):

        out = []
        for d in tx_data.values():
            al = adata.addrlist(al_id=d['al_id'])
            for n, (idx, coinaddr) in enumerate(al.addrpairs()):
                lbl = get_label(do_shuffle=True)
                out.append(
                    self._create_fake_unspent_entry(coinaddr,
                                                    d['al_id'],
                                                    idx,
                                                    lbl,
                                                    segwit=d['segwit']))
                if n == 0:  # create a duplicate address. This means addrs_per_wallet += 1
                    out.append(
                        self._create_fake_unspent_entry(coinaddr,
                                                        d['al_id'],
                                                        idx,
                                                        lbl,
                                                        segwit=d['segwit']))

        if non_mmgen_input:
            from mmgen.obj import PrivKey
            privkey = PrivKey(self.proto,
                              os.urandom(32),
                              compressed=non_mmgen_input_compressed,
                              pubkey_type='std')
            from mmgen.addr import AddrGenerator, KeyGenerator
            rand_coinaddr = AddrGenerator(self.proto, 'compressed').to_addr(
                KeyGenerator(self.proto, 'std').to_pubhex(privkey))
            of = joinpath(self.cfgs[non_mmgen_input]['tmpdir'], non_mmgen_fn)
            write_data_to_file(outfile=of,
                               data=privkey.wif + '\n',
                               desc=f'compressed {self.proto.name} key',
                               quiet=True,
                               ignore_opt_outdir=True)
            out.append(
                self._create_fake_unspent_entry(rand_coinaddr,
                                                non_mmgen=True,
                                                segwit=False))

        return out
Ejemplo n.º 4
0
    def _make_txcreate_cmdline(self, tx_data):
        from mmgen.obj import PrivKey
        privkey = PrivKey(self.proto,
                          os.urandom(32),
                          compressed=True,
                          pubkey_type='std')
        t = ('compressed', 'segwit')['S' in self.proto.mmtypes]
        from mmgen.addr import AddrGenerator, KeyGenerator
        rand_coinaddr = AddrGenerator(self.proto, t).to_addr(
            KeyGenerator(self.proto, 'std').to_pubhex(privkey))

        # total of two outputs must be < 10 BTC (<1000 LTC)
        mods = {
            'btc': (6, 4),
            'bch': (6, 4),
            'ltc': (600, 400)
        }[self.proto.coin.lower()]
        for k in self.cfgs:
            self.cfgs[k]['amts'] = [None, None]
            for idx, mod in enumerate(mods):
                self.cfgs[k]['amts'][idx] = '{}.{}'.format(
                    getrandnum(4) % mod,
                    str(getrandnum(4))[:5])

        cmd_args = ['--outdir=' + self.tmpdir]
        for num in tx_data:
            s = tx_data[num]
            cmd_args += [
                '{}:{},{}'.format(s['al_id'], s['addr_idxs'][0],
                                  self.cfgs[num]['amts'][0]),
            ]
            # + one change address and one BTC address
            if num is list(tx_data.keys())[-1]:
                cmd_args += ['{}:{}'.format(s['al_id'], s['addr_idxs'][1])]
                cmd_args += [
                    '{},{}'.format(rand_coinaddr, self.cfgs[num]['amts'][1])
                ]

        return cmd_args + [tx_data[num]['addrfile'] for num in tx_data]
Ejemplo n.º 5
0
if not b and type(arg2) == int:
    speed_test(a, ag, arg2)
elif not b and hasattr(arg2, 'read'):
    dump_test(a, ag, arg2)
elif a and b and type(arg2) == int:
    if opt.all:
        from mmgen.protocol import CoinProtocol, init_genonly_altcoins
        init_genonly_altcoins(testnet=proto.testnet)
        for coin in ci.external_tests[proto.network][b.desc]:
            if coin.lower() not in CoinProtocol.coins:
                #				ymsg('Coin {} not configured'.format(coin))
                continue
            proto = init_proto(coin)
            if addr_type not in proto.mmtypes:
                continue
            # proto has changed, so reinit kg and ag
            a = KeyGenerator(proto, addr_type, a_num)
            ag = AddrGenerator(proto, addr_type)
            b_chk = ci.get_test_support(proto.coin,
                                        addr_type.name,
                                        proto.network,
                                        tool=b.desc,
                                        verbose=not opt.quiet)
            if b_chk == b.desc:
                gentool_test(a, b, ag, arg2)
    else:
        gentool_test(a, b, ag, arg2)
else:
    opts.usage()
Ejemplo n.º 6
0
        assert 1 <= a <= len(
            g.key_generators), '{}: invalid key generator'.format(a)
        if b in ('ext', 'pyethereum', 'pycoin', 'keyconv', 'zcash_mini'):
            init_external_prog()
        else:
            b = int(b)
            assert 1 <= b <= len(
                g.key_generators), '{}: invalid key generator'.format(b)
        assert a != b, 'Key generators are the same!'
    except Exception as e:
        die(1, '{}\n{}: invalid generator argument'.format(e[0], cmd_args[0]))

from mmgen.addr import KeyGenerator, AddrGenerator
from mmgen.obj import PrivKey

kg_a = KeyGenerator(addr_type, a)
ag = AddrGenerator(addr_type)

if a and b:
    if opt.all:
        from mmgen.protocol import init_coin, init_genonly_altcoins, CoinProtocol
        init_genonly_altcoins('btc', trust_level=0)
        mmgen_supported = CoinProtocol.get_valid_coins(upcase=True)
        for coin in ci.external_tests[('mainnet',
                                       'testnet')[g.testnet]][ext_lib]:
            if coin not in mmgen_supported: continue
            init_coin(coin)
            tmp_addr_type = addr_type if addr_type in g.proto.mmtypes else MMGenAddrType(
                g.proto.dfl_mmtype)
            kg_a = KeyGenerator(tmp_addr_type, a)
            ag = AddrGenerator(tmp_addr_type)
Ejemplo n.º 7
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
Ejemplo n.º 8
0
""".format(sec, wif, a_addr, b_addr, pnm=g.proj_name, a=m[a], b=m[b]).rstrip())


# Begin execution
compressed = True

from mmgen.addr import KeyGenerator, AddrGenerator
from mmgen.obj import PrivKey

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))
Ejemplo n.º 9
0
arg2 = parse_arg2()

ag = AddrGenerator(addr_type)

if not b and type(arg2) == int:
	speed_test(a,ag,arg2)
elif not b and hasattr(arg2,'read'):
	dump_test(a,ag,arg2)
elif a and b and type(arg2) == int:
	if opt.all:
		from mmgen.protocol import CoinProtocol,init_genonly_altcoins
		init_genonly_altcoins(testnet=g.proto.testnet)
		for coin in ci.external_tests[g.proto.network][b.desc]:
			if coin.lower() not in CoinProtocol.coins:
#				ymsg('Coin {} not configured'.format(coin))
				continue
			g.proto = init_proto(coin)
			if addr_type not in g.proto.mmtypes:
				continue
			# g.proto has changed, so reinit kg and ag just to be on the safe side:
			a = KeyGenerator(addr_type,a_num)
			ag = AddrGenerator(addr_type)
			b_chk = ci.get_test_support(g.coin,addr_type.name,g.proto.network,tool=b.desc,verbose=not opt.quiet)
			if b_chk == b.desc:
				gentool_test(a,b,ag,arg2)
	else:
		gentool_test(a,b,ag,arg2)
else:
	opts.usage()