Esempio n. 1
0
	def add_signature(self, sigb64):
		sig = base64.b64decode(sigb64).encode('hex')
		inserted_sig = False
		txhex = btc.serialize(self.latest_tx)
		
		#batch retrieval of utxo data
		utxo = {}
		ctr = 0
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo_for_checking = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if ins['script'] != '' or  utxo_for_checking in self.input_utxos.keys():
				continue
			utxo[ctr] = [index, utxo_for_checking]
			ctr += 1
		utxo_data = common.bc_interface.query_utxo_set([x[1] for x in utxo.values()])
		#insert signatures
		for i,u in utxo.iteritems():
			if utxo_data[i] == None:
				continue
			sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], *btc.deserialize_script(sig))
			if sig_good:
				debug('found good sig at index=%d' % (u[0]))
				self.latest_tx['ins'][u[0]]['script'] = sig
				inserted_sig = True
				break
		if not inserted_sig:
			debug('signature did not match anything in the tx')
			#TODO what if the signature doesnt match anything
			# nothing really to do except drop it, carry on and wonder why the
			# other guy sent a failed signature

		tx_signed = True
		for ins in self.latest_tx['ins']:
			if ins['script'] == '':
				tx_signed = False
		if not tx_signed:
			return
		debug('the entire tx is signed, ready to pushtx()')
		txhex = btc.serialize(self.latest_tx)
		debug('\n' + txhex)

		#TODO send to a random maker or push myself
		#self.msgchan.push_tx(self.active_orders.keys()[0], txhex)	
		self.txid = common.bc_interface.pushtx(txhex)
		debug('pushed tx ' + str(self.txid))
		if self.txid == None:
			debug('unable to pushtx')
		if self.finishcallback != None:
			self.finishcallback(self)
Esempio n. 2
0
def normalize_transaction(tx):
    _tx = deserialize(tx)
    _tx['segwit'] = True
    for i, vin in enumerate(_tx['ins']):
        if vin.get('txinwitness', '0' * 64) == '0' * 64:
            _tx['ins'][i]['txinwitness'] = ''
    return serialize(_tx)
Esempio n. 3
0
def to_rawtx(tx):
    """
    Take a tx object in the moneywagon format and convert it to the format
    that pybitcointools's `serialize` funcion takes, then return in raw hex
    format.
    """
    if tx.get('hex'):
        return tx['hex']

    new_tx = {}

    locktime = tx.get('locktime', 0)
    new_tx['locktime'] = locktime
    new_tx['version'] = tx.get('version', 1)
    new_tx['ins'] = [
        {
            'outpoint': {'hash': str(x['txid']), 'index': x['n']},
            'script': str(x['scriptSig'].replace(' ', '')),
            'sequence': x.get('sequence', 0xFFFFFFFF if locktime == 0 else None)
        } for x in tx['inputs']
    ]

    new_tx['outs'] = [
        {
            'script': str(x['scriptPubKey']),
            'value': x['amount']
        } for x in tx['outputs']
    ]

    return serialize(new_tx)
Esempio n. 4
0
    def test_native_P2WSH_SIGHASH_SINGLE_ANYONECANPAY(self):
        tx = TEST_CASES[2]
        deserialized = deserialize(tx['unsigned'])
        serialized = serialize(deserialized)
        self.assertEqual(serialized, tx['unsigned'])
        self.assertEqual(deserialized['locktime'], tx['locktime'])
        ins = self.get_pybtc_vins(tx)
        outs = self.get_pybtc_outs(tx)
        generated_tx = mktx(ins, outs)
        stripped_tx = strip_witness_data(generated_tx)
        self.assertEqual(stripped_tx, serialized)
        priv0 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey'])
        partially_signed = segwit_sign(generated_tx,
                                       0,
                                       priv0,
                                       int(0.16777215 * 10**8),
                                       hashcode=SIGHASH_SINGLE
                                       | SIGHASH_ANYONECANPAY,
                                       script=tx['ins'][0]['txinwitness'][1])

        signed = segwit_sign(partially_signed,
                             1,
                             priv0,
                             int(0.16777215 * 10**8),
                             hashcode=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY,
                             script=tx['ins'][1]['txinwitness'][1],
                             separator_index=tx['ins'][1]['separator'])
        self.assertEqual(signed, tx['signed'])
        print('[Native P2WSH] SIGHASH_SINGLE OK')
Esempio n. 5
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.debug('txid = ' + self.txid)
        
        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;'
            ).fetchone()
            counterparty = crow['counterparty']
            log.debug('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True

        if not pushed:
            log.debug('unable to pushtx')
        return pushed
Esempio n. 6
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address),
                                    hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Esempio n. 7
0
def segwit_sign(tx,
                i,
                priv,
                amount,
                hashcode=SIGHASH_ALL,
                script=None,
                separator_index=None):
    i = int(i)
    txobj = tx if isinstance(tx, dict) else deserialize(tx)
    if not isinstance(tx, dict) and ((not is_python2 and isinstance(re, bytes))
                                     or not re.match('^[0-9a-fA-F]*$', tx)):
        return binascii.unhexlify(sign(binascii.hexlify(tx), i, priv))
    if len(priv) <= 33:
        priv = binascii.hexlify(priv)
    pub = privkey_to_pubkey(priv)
    address = pubkey_to_address(pub)
    wscript = mk_pubkey_script(address) if not script else script
    stripped_script = segwit_strip_script_separator(wscript, separator_index)
    signing_tx = segwit_signature_form(tx,
                                       i,
                                       stripped_script,
                                       amount,
                                       hashcode=hashcode)
    rawsig = ecdsa_raw_sign(
        hashlib.sha256(
            hashlib.sha256(
                binascii.unhexlify(signing_tx)).digest()).hexdigest(), priv)
    sig = der_encode_sig(*rawsig) + encode(hashcode, 16, 2)
    txobj['ins'][i]['txinwitness'] = [sig, pub if not script else script]
    return serialize(txobj)
Esempio n. 8
0
def to_rawtx(tx):
    """
    Take a tx object in the moneywagon format and convert it to the format
    that pybitcointools's `serialize` funcion takes, then return in raw hex
    format.
    """
    if tx.get('hex'):
        return tx['hex']

    new_tx = {}

    locktime = tx.get('locktime', 0)
    new_tx['locktime'] = locktime
    new_tx['version'] = tx.get('version', 1)
    new_tx['ins'] = [
        {
            'outpoint': {'hash': str(x['txid']), 'index': x['n']},
            'script': str(x['scriptSig'].replace(' ', '')),
            'sequence': x.get('sequence', 0xFFFFFFFF if locktime == 0 else None)
        } for x in tx['inputs']
    ]

    new_tx['outs'] = [
        {
            'script': str(x['scriptPubKey']),
            'value': x['amount']
        } for x in tx['outputs']
    ]

    return serialize(new_tx)
Esempio n. 9
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.debug('txid = ' + self.txid)

        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;').fetchone()
            counterparty = crow['counterparty']
            log.debug('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True

        if not pushed:
            log.debug('unable to pushtx')
        return pushed
Esempio n. 10
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(
            tx, i, btc.mk_pubkey_script(address), hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Esempio n. 11
0
def sign(tx, i, priv, t="default", script="", hashcode=SIGHASH_ALL):
    i = int(i)
    #if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx):
    if not re.match('^[0-9a-fA-F]*$', tx):
        return binascii.unhexlify(
            custom_sign(safe_hexlify(tx), i, priv, hashcode))
    if len(priv) <= 33:
        priv = b.safe_hexlify(priv)
    pub = b.privkey_to_pubkey(priv)
    address = b.pubkey_to_address(pub)
    if t not in ["atomic_1", "atomic_2"]:
        script = b.mk_pubkey_script(address)
    if script == "": error()
    signing_tx = b.signature_form(
        tx, i, script,
        hashcode)  #mk_pubkey_scrip needs to be our custom scriptn
    sig = b.ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = b.deserialize(tx)
    if t == "atomic_1":
        txobj["ins"][i]["script"] = b.serialize_script([sig])
    if t == "atomic_2":
        old_sig = txobj["ins"][i]["script"]
        txobj["ins"][i]["script"] = b.serialize_script([old_sig, sig, 1])
    else:
        txobj["ins"][i]["script"] = b.serialize_script([sig, pub])
    return b.serialize(txobj)
Esempio n. 12
0
    def test_native_P2WSH_SIGHASH_SINGLE_ANYONECANPAY(self):
        tx = TEST_CASES[2]
        deserialized = deserialize(tx['unsigned'])
        serialized = serialize(deserialized)
        self.assertEqual(serialized, tx['unsigned'])
        self.assertEqual(deserialized['locktime'], tx['locktime'])
        ins = self.get_pybtc_vins(tx)
        outs = self.get_pybtc_outs(tx)
        generated_tx = mktx(ins, outs)
        stripped_tx = strip_witness_data(generated_tx)
        self.assertEqual(stripped_tx, serialized)
        priv0 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey'])
        partially_signed = segwit_sign(generated_tx,
                                       0,
                                       priv0,
                                       int(0.16777215 * 10**8),
                                       hashcode=SIGHASH_SINGLE|SIGHASH_ANYONECANPAY,
                                       script=tx['ins'][0]['txinwitness'][1])

        signed = segwit_sign(partially_signed,
                             1,
                             priv0,
                             int(0.16777215 * 10 ** 8),
                             hashcode=SIGHASH_SINGLE|SIGHASH_ANYONECANPAY,
                             script=tx['ins'][1]['txinwitness'][1],
                             separator_index=tx['ins'][1]['separator'])
        self.assertEqual(signed, tx['signed'])
        print('[Native P2WSH] SIGHASH_SINGLE OK')
Esempio n. 13
0
def main():
    locktime = args.locktime
    privkey = args.privkey
    address = args.address

    script = getRedeemScript(locktime, privkey)
    ins, balance = getBalance(scriptaddr(script, 50))
    len_inputs = len(ins)

    tx = ''

    if balance > 0 and check_addr(address) and is_privkey(privkey):
        # Fee
        fee = round(base_fee + fee_per_input * len_inputs, 8)

        # Outputs
        out_value = int((balance - fee) * COIN)
        outs = [{'address' : address, 'value' : out_value}]

        # Make unsigned transaction
        tx = mktx(ins, outs)

        # Append nLockTime and reset nSequence
        unpacked = deserialize(tx)
        unpacked['locktime'] = locktime
        for i in range(len_inputs):
            unpacked['ins'][i]['sequence'] = 0
        tx = serialize(unpacked)

        # get all signatures
        sigs = []
        for i in range(len_inputs):
            sigs.append(multisign(tx, i, script, privkey))

        # sign inputs
        unpacked = deserialize(tx)
        for i in range(len_inputs):
            unpacked['ins'][i]['script'] = getLen(sigs[i]) + sigs[i]
            unpacked['ins'][i]['script'] += getLen(script) + script
        tx = serialize(unpacked)

    print('> BALANCE (%s): %f' % (scriptaddr(script, 50), balance))

    if len(tx) > 0:
        txid = broadcast(tx)
        print('> RESPONSE: %s' % txid.text)
Esempio n. 14
0
def tx_serialize( tx ):
     """
     Convert a bitcoin-given transaction into its hex string.
     tx format is {'vin': [...], 'vout': [...], 'locktime': ..., 'version': ...}, 
     with the same formatting rules as getrawtransaction.
     (in particular, each value in vout is a Decimal, in BTC)
     """
     tx_ins = []
     tx_outs = []

     try:
         for inp in tx['vin']:
             next_inp = {
                "outpoint": {
                   "index": int(inp['vout']),
                   "hash": str(inp['txid'])
                }
             }
             if 'sequence' in inp:
                 next_inp['sequence'] = int(inp['sequence'])
             else:
                 next_inp['sequence'] = pybitcoin.UINT_MAX

             if 'scriptSig' in inp:
                 next_inp['script'] = str(inp['scriptSig']['hex'])
             else:
                 next_inp['script'] = ""

             tx_ins.append(next_inp)

         for out in tx['vout']:
         
             assert out['value'] < 1000, "High transaction value\n%s" % simplejson.dumps(tx, indent=4, sort_keys=True)
             next_out = {
                'value': int(Decimal(out['value']) * Decimal(10**8)),
                'script': str(out['scriptPubKey']['hex'])
             }
             tx_outs.append(next_out)

         tx_fields = {
            "locktime": int(tx['locktime']),
            "version": int(tx['version']),
            "ins": tx_ins,
            "outs": tx_outs
         }

         tx_serialized = bitcoin.serialize( tx_fields )
         return str(tx_serialized)

     except KeyError, ke:
         if tx_is_coinbase(tx) and 'hex' in tx.keys():
             tx_serialized = tx['hex']
             return str(tx_serialized)

         import simplejson
         log.error("Key error in :\n%s" % simplejson.dumps(tx, indent=4, sort_keys=True))
         traceback.print_exc()
         raise ke
Esempio n. 15
0
 def on_peer_announce(tx):
     txhash = bitcoin.txhash(bitcoin.serialize(tx["tx"]))
     if txhash in self.subscriptions[address][0] and self.subscriptions[address][0][txhash][0] != "complete":
         self.subscriptions[address][0][txhash][0] += 1
         if self.subscriptions[address][0][txhash][0] >= self.subscriptions[address][0][txhash][1]:
             self.subscriptions[address][0][txhash][0] = "complete"
             self.subscriptions[address][1](tx["tx"])
     elif txhash not in self.subscriptions[address][0]:
         self.subscriptions[address][0][txhash] = [1, len(self.peers)/2]
Esempio n. 16
0
	def self_sign_and_push(self):
		#now sign it ourselves
		tx = btc.serialize(self.latest_tx)
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
		txhex = btc.serialize(self.latest_tx)
		debug('\n' + txhex)
		debug('txid = ' + btc.txhash(tx))
		#TODO send to a random maker or push myself
		#TODO need to check whether the other party sent it
		#self.msgchan.push_tx(self.active_orders.keys()[0], txhex)	
		self.txid = common.bc_interface.pushtx(tx)
		if self.txid == None:
			debug('unable to pushtx')
Esempio n. 17
0
	def add_signature(self, nick, sigb64):
		if nick not in self.nonrespondants:
			debug('add_signature => nick=' + nick + ' not in nonrespondants ' + str(self.nonrespondants))
			return
		sig = base64.b64decode(sigb64).encode('hex')
		inserted_sig = False
		txhex = btc.serialize(self.latest_tx)
		
		#batch retrieval of utxo data
		utxo = {}
		ctr = 0
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo_for_checking = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if ins['script'] != '' or  utxo_for_checking in self.input_utxos.keys():
				continue
			utxo[ctr] = [index, utxo_for_checking]
			ctr += 1
		utxo_data = common.bc_interface.query_utxo_set([x[1] for x in utxo.values()])
		#insert signatures
		for i,u in utxo.iteritems():
			if utxo_data[i] == None:
				continue
			sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], *btc.deserialize_script(sig))
			if sig_good:
				debug('found good sig at index=%d' % (u[0]))
				self.latest_tx['ins'][u[0]]['script'] = sig
				inserted_sig = True
				#check if maker has sent everything possible
				self.utxos[nick].remove(u[1])
				if len(self.utxos[nick]) == 0:
					debug('nick = ' + nick + ' sent all sigs, removing from nonrespondant list')
					self.nonrespondants.remove(nick)
				break
		if not inserted_sig:
			debug('signature did not match anything in the tx')
			#TODO what if the signature doesnt match anything
			# nothing really to do except drop it, carry on and wonder why the
			# other guy sent a failed signature

		tx_signed = True
		for ins in self.latest_tx['ins']:
			if ins['script'] == '':
				tx_signed = False
		if not tx_signed:
			return
		self.end_timeout_thread = True
		self.all_responded = True
		with self.timeout_lock:
			self.timeout_lock.notify()
		debug('all makers have sent their signatures')
		for index, ins in enumerate(self.latest_tx['ins']):
			#remove placeholders
			if ins['script'] == 'deadbeef':
				ins['script'] = ''
		if self.finishcallback != None:
			self.finishcallback(self)
Esempio n. 18
0
 def push(self, txd):
     tx = btc.serialize(txd)
     debug('\n' + tx)
     debug('txid = ' + btc.txhash(tx))
     #TODO send to a random maker or push myself
     #TODO need to check whether the other party sent it
     #self.msgchan.push_tx(self.active_orders.keys()[0], txhex)
     self.txid = common.bc_interface.pushtx(tx)
     if self.txid == None:
         debug('unable to pushtx')
Esempio n. 19
0
    def reorder_sigs( self, sigs ):
        reorderedSigs = []
        stx = bitcoin.serialize( self.tx )
        for pub in self.pubs:
            for sig in sigs:
                if bitcoin.verify_tx_input( stx, 0, self.redeemScript, sig, pub ):
                    reorderedSigs.append( sig )
                    break

        return reorderedSigs
Esempio n. 20
0
	def self_sign(self):
		#now sign it ourselves
		tx = btc.serialize(self.latest_tx)
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr))
		self.latest_tx = btc.deserialize(tx)
Esempio n. 21
0
	def push(self, txd):
		tx = btc.serialize(txd)
		debug('\n' + tx)
		debug('txid = ' + btc.txhash(tx))
		#TODO send to a random maker or push myself
		#TODO need to check whether the other party sent it
		#self.msgchan.push_tx(self.active_orders.keys()[0], txhex)	
		self.txid = common.bc_interface.pushtx(tx)
		if self.txid == None:
			debug('unable to pushtx')
Esempio n. 22
0
 def finishcallback(self, coinjointx):
     if coinjointx.all_responded:
         tx = btc.serialize(coinjointx.latest_tx)
         print 'unsigned tx = \n\n' + tx + '\n'
         log.debug('created unsigned tx, ending')
         self.taker.msgchan.shutdown()
         return
     self.ignored_makers += coinjointx.nonrespondants
     log.debug('recreating the tx, ignored_makers=' + str(
         self.ignored_makers))
     self.create_tx()
Esempio n. 23
0
def tx_serialize( inputs, outputs, locktime, version ):
    """
    Given (possibly signed) inputs and outputs, convert them 
    into a hex string.
    Each input must have:
    * transaction_hash: string 
    * output_index: int 
    * [optional] sequence: int 
    * [optional] script_sig: str 
    
    Each output must have:
    * value: int 
    * script_hex: string
    """
    
    tmp_inputs = []
    tmp_outputs = []
    
    # convert to a format bitcoin understands
    for inp in inputs:
        tmp_inp = {
            "outpoint": {
                "index": inp["output_index"],
                "hash": inp["transaction_hash"]
            }
        }
        if "sequence" in inp:
            tmp_inp["sequence"] = inp["sequence"]
        else:
            tmp_inp["sequence"] = pybitcoin.UINT_MAX 
            
        if "script_sig" in inp:
            tmp_inp["script"] = inp["script_sig"]
        else:
            tmp_inp["script"] = ""
            
        tmp_inputs.append( tmp_inp )
        
    for out in outputs:
        tmp_out = {
            "value": out["value"],
            "script": out["script_hex"]
        }
        
        tmp_outputs.append( tmp_out )
        
    txobj = {
        "locktime": locktime,
        "version": version,
        "ins": tmp_inputs,
        "outs": tmp_outputs
    }
    
    return bitcoin.serialize( txobj )
Esempio n. 24
0
 def finishcallback(self, coinjointx):
     if coinjointx.all_responded:
         tx = btc.serialize(coinjointx.latest_tx)
         print 'unsigned tx = \n\n' + tx + '\n'
         log.debug('created unsigned tx, ending')
         self.taker.msgchan.shutdown()
         return
     self.ignored_makers += coinjointx.nonrespondants
     log.debug('recreating the tx, ignored_makers=' +
               str(self.ignored_makers))
     self.create_tx()
Esempio n. 25
0
def tx_serialize( inputs, outputs, locktime, version ):
    """
    Given (possibly signed) inputs and outputs, convert them 
    into a hex string.
    Each input must have:
    * transaction_hash: string 
    * output_index: int 
    * [optional] sequence: int 
    * [optional] script_sig: str 
    
    Each output must have:
    * value: int 
    * script_hex: string
    """
    
    tmp_inputs = []
    tmp_outputs = []
    
    # convert to a format bitcoin understands
    for inp in inputs:
        tmp_inp = {
            "outpoint": {
                "index": inp["output_index"],
                "hash": inp["transaction_hash"]
            }
        }
        if "sequence" in inp:
            tmp_inp["sequence"] = inp["sequence"]
        else:
            tmp_inp["sequence"] = pybitcoin.UINT_MAX 
            
        if "script_sig" in inp:
            tmp_inp["script"] = inp["script_sig"]
        else:
            tmp_inp["script"] = ""
            
        tmp_inputs.append( tmp_inp )
        
    for out in outputs:
        tmp_out = {
            "value": out["value"],
            "script": out["script_hex"]
        }
        
        tmp_outputs.append( tmp_out )
        
    txobj = {
        "locktime": locktime,
        "version": version,
        "ins": tmp_inputs,
        "outs": tmp_outputs
    }
    
    return bitcoin.serialize( txobj )
Esempio n. 26
0
 def self_sign(self):
     #now sign it ourselves
     tx = btc.serialize(self.latest_tx)
     for index, ins in enumerate(self.latest_tx['ins']):
         utxo = ins['outpoint']['hash'] + ':' + str(
             ins['outpoint']['index'])
         if utxo not in self.input_utxos.keys():
             continue
         addr = self.input_utxos[utxo]['address']
         tx = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr))
     self.latest_tx = btc.deserialize(tx)
Esempio n. 27
0
    def add_signature(self, sigb64):
        sig = base64.b64decode(sigb64).encode('hex')
        inserted_sig = False
        tx = btc.serialize(self.latest_tx)
        for index, ins in enumerate(self.latest_tx['ins']):
            if ins['script'] != '':
                continue
            utxo = ins['outpoint']['hash'] + ':' + str(
                ins['outpoint']['index'])
            utxo_data = common.bc_interface.query_utxo_set(utxo)
            if utxo_data[0] == None:
                continue
            sig_good = btc.verify_tx_input(tx, index, utxo_data[0]['script'],
                                           *btc.deserialize_script(sig))
            if sig_good:
                debug('found good sig at index=%d' % (index))
                ins['script'] = sig
                inserted_sig = True
                break
        if not inserted_sig:
            debug('signature did not match anything in the tx')
            #TODO what if the signature doesnt match anything
            # nothing really to do except drop it, carry on and wonder why the
            # other guy sent a failed signature

        tx_signed = True
        for ins in self.latest_tx['ins']:
            if ins['script'] == '':
                tx_signed = False
        if not tx_signed:
            return
        debug('the entire tx is signed, ready to pushtx()')
        txhex = btc.serialize(self.latest_tx)
        debug('\n' + txhex)

        #TODO send to a random maker or push myself
        #self.msgchan.push_tx(self.active_orders.keys()[0], txhex)
        txid = common.bc_interface.pushtx(txhex)
        debug('pushed tx ' + str(txid))
        if self.finishcallback != None:
            self.finishcallback(self)
Esempio n. 28
0
def atomic(peer_pub, wallet, to, send, receive, secret_hash):
    tx1=mk_spend(wallet, to, send)#puts your money into the channel.
    tx=b.deserialize(tx1)
    script="6352"+serialize(peer_pub)+serialize(wallet["pub"])+"52af67aa"+serialize(secret_hash)+"87"+serialize(peer_pub)+"ad68"
    print("script: " +str(script))
    tx['outs'][0]['script']=script
    tx=b.serialize(tx)

    txd=txid(tx)
    txd={'output':(txd+':1'), 'block_height':None, 'value':send, 'address':wallet['address']}
    refund_tx=mk_spend_txids(wallet, wallet["address"], send-fee, [txd])
    return {"refund": refund_tx, "channel": tx, "script":script}
Esempio n. 29
0
 def test_native_P2WSH_SIGHASH_SINGLE(self):
     tx = TEST_CASES[1]
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs)
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     partially_signed = p2pk_sign(stripped_tx,
                                  0,
                                  self.append_compressed_flag_to_privkey(
                                      tx['ins'][0]['privkey']),
                                  hashcode=SIGHASH_ALL)
     priv0 = self.append_compressed_flag_to_privkey(
         tx['ins'][1]['privkeys'][0])
     priv1 = self.append_compressed_flag_to_privkey(
         tx['ins'][1]['privkeys'][1])
     pub0 = privtopub(priv0)
     pub1 = privtopub(priv1)
     REDEEM_SCRIPT_STRUCTURE = {
         'keys': [pub0, pub1],
         'schema': [{
             'reqs': 1,
             'keys': [0],
         }, {
             'reqs': 1,
             'keys': [1],
         }]
     }
     witness_script = mk_OPCS_multisig_script(REDEEM_SCRIPT_STRUCTURE)
     sign1 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv0,
                              49 * 10**8,
                              hashcode=SIGHASH_SINGLE)
     sign2 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv1,
                              49 * 10**8,
                              hashcode=SIGHASH_SINGLE,
                              separator_index=1)
     signed = apply_segwit_multisignatures(partially_signed,
                                           1,
                                           witness_script, [sign2, sign1],
                                           dummy=False)
     self.assertEqual(signed, tx['signed'])
     print('[Native P2WSH] SIGHASH_SINGLE OK')
Esempio n. 30
0
 def test_native_P2WSH_SIGHASH_SINGLE(self):
     tx = TEST_CASES[1]
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs)
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     partially_signed = p2pk_sign(stripped_tx,
                                  0,
                                  self.append_compressed_flag_to_privkey(tx['ins'][0]['privkey']),
                                  hashcode=SIGHASH_ALL)
     priv0 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkeys'][0])
     priv1 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkeys'][1])
     pub0 = privtopub(priv0)
     pub1 = privtopub(priv1)
     REDEEM_SCRIPT_STRUCTURE = {
         'keys': [
             pub0,
             pub1
         ],
         'schema': [
             {
                 'reqs': 1,
                 'keys': [0],
             },
             {
                 'reqs': 1,
                 'keys': [1],
             }
         ]
     }
     witness_script = mk_OPCS_multisig_script(REDEEM_SCRIPT_STRUCTURE)
     sign1 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv0,
                              49 * 10**8,
                              hashcode=SIGHASH_SINGLE)
     sign2 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv1,
                              49 * 10 ** 8,
                              hashcode=SIGHASH_SINGLE,
                              separator_index=1)
     signed = apply_segwit_multisignatures(partially_signed, 1, witness_script, [sign2, sign1], dummy=False)
     self.assertEqual(signed, tx['signed'])
     print('[Native P2WSH] SIGHASH_SINGLE OK')
Esempio n. 31
0
def apply_segwit_multisignatures(tx, i, witness_program, signatures, dummy=True, nested=False):
    o = [""] + signatures + [witness_program] if dummy else signatures + [witness_program]
    txobj = deserialize(tx)
    txobj['ins'][i]['txinwitness'] =  o
    if nested:
        redeem_script = hashlib.sha256(binascii.unhexlify(
            witness_program
        )).hexdigest()
        length = len(redeem_script) // 2
        redeem_script = serialize_script(
            [length + 2, None, redeem_script])
        txobj["ins"][i]["script"] = redeem_script
    return serialize(txobj)
Esempio n. 32
0
 def push(self, txd):
     tx = btc.serialize(txd)
     log.debug('\n' + tx)
     log.debug('txid = ' + btc.txhash(tx))
     # TODO send to a random maker or push myself
     # TODO need to check whether the other party sent it
     # self.msgchan.push_tx(self.active_orders.keys()[0], txhex)
     pushed = jm_single().bc_interface.pushtx(tx)
     if pushed[0]:
         self.txid = btc.txhash(tx)
     else:
         log.debug('unable to pushtx, reason: '+str(pushed[1]))
     return pushed[0]
Esempio n. 33
0
	def add_signature(self, sigb64):
		sig = base64.b64decode(sigb64).encode('hex')
		inserted_sig = False
		tx = btc.serialize(self.latest_tx)
		for index, ins in enumerate(self.latest_tx['ins']):
			if ins['script'] != '':
				continue
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			utxo_data = common.bc_interface.query_utxo_set(utxo)
			if utxo_data[0] == None:
				continue
			sig_good = btc.verify_tx_input(tx, index, utxo_data[0]['script'], *btc.deserialize_script(sig))
			if sig_good:
				debug('found good sig at index=%d' % (index))
				ins['script'] = sig
				inserted_sig = True
				break
		if not inserted_sig:
			debug('signature did not match anything in the tx')
			#TODO what if the signature doesnt match anything
			# nothing really to do except drop it, carry on and wonder why the
			# other guy sent a failed signature

		tx_signed = True
		for ins in self.latest_tx['ins']:
			if ins['script'] == '':
				tx_signed = False
		if not tx_signed:
			return
		debug('the entire tx is signed, ready to pushtx()')
		txhex = btc.serialize(self.latest_tx)
		debug('\n' + txhex)

		#TODO send to a random maker or push myself
		#self.msgchan.push_tx(self.active_orders.keys()[0], txhex)	
		txid = common.bc_interface.pushtx(txhex)
		debug('pushed tx ' + str(txid))
		if self.finishcallback != None:
			self.finishcallback(self)
Esempio n. 34
0
 def on_peer_announce(tx):
     txhash = bitcoin.txhash(bitcoin.serialize(tx["tx"]))
     if txhash in self.subscriptions[address][0] and self.subscriptions[
             address][0][txhash][0] != "complete":
         self.subscriptions[address][0][txhash][0] += 1
         if self.subscriptions[address][0][txhash][
                 0] >= self.subscriptions[address][0][txhash][1]:
             self.subscriptions[address][0][txhash][0] = "complete"
             self.subscriptions[address][1](tx["tx"])
     elif txhash not in self.subscriptions[address][0]:
         self.subscriptions[address][0][txhash] = [
             1, len(self.peers) / 2
         ]
Esempio n. 35
0
 def push(self, txd):
     tx = btc.serialize(txd)
     log.debug('\n' + tx)
     log.debug('txid = ' + btc.txhash(tx))
     # TODO send to a random maker or push myself
     # TODO need to check whether the other party sent it
     # self.msgchan.push_tx(self.active_orders.keys()[0], txhex)
     pushed = jm_single().bc_interface.pushtx(tx)
     if pushed[0]:
         self.txid = pushed[1]
     else:
         log.debug('unable to pushtx, reason: ' + str(pushed[1]))
     return pushed[0]
Esempio n. 36
0
def apply_segwit_multisignatures(tx,
                                 i,
                                 witness_program,
                                 signatures,
                                 dummy=True,
                                 nested=False):
    txobj = deserialize(tx)
    signed = apply_segwit_multisignatures_deserialized_data(txobj,
                                                            i,
                                                            witness_program,
                                                            signatures,
                                                            dummy=dummy,
                                                            nested=nested)
    return serialize(signed)
Esempio n. 37
0
def segwit_sign(tx, i, priv, amount, hashcode=SIGHASH_ALL, script=None, separator_index=None):
    i = int(i)
    txobj = tx if isinstance(tx, dict) else deserialize(tx)
    if not isinstance(tx, dict) and ((not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx)):
        return binascii.unhexlify(sign(binascii.hexlify(tx), i, priv))
    if len(priv) <= 33:
        priv = binascii.hexlify(priv)
    pub = privkey_to_pubkey(priv)
    address = pubkey_to_address(pub)
    wscript = mk_pubkey_script(address) if not script else script
    stripped_script = segwit_strip_script_separator(wscript, separator_index)
    signing_tx = segwit_signature_form(tx, i, stripped_script, amount, hashcode=hashcode)
    rawsig = ecdsa_raw_sign(hashlib.sha256(hashlib.sha256(binascii.unhexlify(signing_tx)).digest()).hexdigest(), priv)
    sig = der_encode_sig(*rawsig)+encode(hashcode, 16, 2)
    txobj['ins'][i]['txinwitness'] = [sig, pub if not script else script]
    return serialize(txobj)
Esempio n. 38
0
	def finishcallback(self, coinjointx):
		if coinjointx.all_responded:
			#now sign it ourselves
			tx = btc.serialize(coinjointx.latest_tx)
			for index, ins in enumerate(coinjointx.latest_tx['ins']):
				utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
				if utxo != self.taker.auth_utxo:
					continue
				addr = coinjointx.input_utxos[utxo]['address']
				tx = btc.sign(tx, index, coinjointx.wallet.get_key_from_addr(addr))
			print 'unsigned tx = \n\n' + tx + '\n'
			debug('created unsigned tx, ending')
			self.taker.msgchan.shutdown()
			return
		self.ignored_makers += coinjointx.nonrespondants
		debug('recreating the tx, ignored_makers=' + str(self.ignored_makers))
		self.create_tx()
Esempio n. 39
0
def apply_segwit_multisignatures(tx,
                                 i,
                                 witness_program,
                                 signatures,
                                 dummy=True,
                                 nested=False):
    o = [""] + signatures + [witness_program
                             ] if dummy else signatures + [witness_program]
    txobj = deserialize(tx)
    txobj['ins'][i]['txinwitness'] = o
    if nested:
        redeem_script = hashlib.sha256(
            binascii.unhexlify(witness_program)).hexdigest()
        length = len(redeem_script) // 2
        redeem_script = serialize_script([length + 2, None, redeem_script])
        txobj["ins"][i]["script"] = redeem_script
    return serialize(txobj)
Esempio n. 40
0
def test_serialization_roundtrip2():
    #Data extracted from:
    #https://github.com/bitcoin/bitcoin/blob/master/src/test/data/tx_valid.json
    #These are a variety of rather strange edge case transactions, which are
    #still valid.
    #Note that of course this is only a serialization, not validity test, so
    #only currently of very limited significance
    with open("test/tx_valid.json", "r") as f:
        json_data = f.read()
    valid_txs = json.loads(json_data)
    for j in valid_txs:
        #ignore comment entries
        if len(j) < 2:
            continue
        print j
        deserialized = btc.deserialize(str(j[0]))
        print deserialized
        assert j[0] == btc.serialize(deserialized)
Esempio n. 41
0
def test_serialization_roundtrip2():
    #Data extracted from:
    #https://github.com/bitcoin/bitcoin/blob/master/src/test/data/tx_valid.json
    #These are a variety of rather strange edge case transactions, which are
    #still valid.
    #Note that of course this is only a serialization, not validity test, so
    #only currently of very limited significance
    with open("test/tx_valid.json", "r") as f:
        json_data = f.read()
    valid_txs = json.loads(json_data)
    for j in valid_txs:
        #ignore comment entries
        if len(j) < 2:
            continue
        print j
        deserialized = btc.deserialize(str(j[0]))
        print deserialized
        assert j[0] == btc.serialize(deserialized)
Esempio n. 42
0
def atomic(peer_pub, wallet, to, send, receive, secret_hash):
    tx1 = mk_spend(wallet, to, send)  #puts your money into the channel.
    tx = b.deserialize(tx1)
    script = "6352" + serialize(peer_pub) + serialize(
        wallet["pub"]) + "52af67aa" + serialize(
            secret_hash) + "87" + serialize(peer_pub) + "ad68"
    print("script: " + str(script))
    tx['outs'][0]['script'] = script
    tx = b.serialize(tx)

    txd = txid(tx)
    txd = {
        'output': (txd + ':1'),
        'block_height': None,
        'value': send,
        'address': wallet['address']
    }
    refund_tx = mk_spend_txids(wallet, wallet["address"], send - fee, [txd])
    return {"refund": refund_tx, "channel": tx, "script": script}
Esempio n. 43
0
 def finishcallback(self, coinjointx):
     if coinjointx.all_responded:
         #now sign it ourselves
         tx = btc.serialize(coinjointx.latest_tx)
         for index, ins in enumerate(coinjointx.latest_tx['ins']):
             utxo = ins['outpoint']['hash'] + ':' + str(
                 ins['outpoint']['index'])
             if utxo != self.taker.auth_utxo:
                 continue
             addr = coinjointx.input_utxos[utxo]['address']
             tx = btc.sign(tx, index,
                           coinjointx.wallet.get_key_from_addr(addr))
         print 'unsigned tx = \n\n' + tx + '\n'
         debug('created unsigned tx, ending')
         self.taker.msgchan.shutdown()
         return
     self.ignored_makers += coinjointx.nonrespondants
     debug('recreating the tx, ignored_makers=' + str(self.ignored_makers))
     self.create_tx()
Esempio n. 44
0
def apply_multisignatures(*args):
    # tx,i,script,sigs OR tx,i,script,sig1,sig2...,sig[n]
    tx, i, script = args[0], int(args[1]), args[2]
    sigs = args[3] if isinstance(args[3], list) else list(args[3:])

    if isinstance(script, str) and re.match('^[0-9a-fA-F]*$', script):
        script = binascii.unhexlify(script)
    sigs = [binascii.unhexlify(x) if x[:2] == '30' else x for x in sigs]
    if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx):
        signed_tx = apply_multisignatures(binascii.unhexlify(tx), i, script, sigs)
        return binascii.hexlify(signed_tx)

    # Not pushing empty elements on the top of the stack if passing no
    # script (in case of bare multisig inputs there is no script)
    script_blob = [] if script.__len__() == 0 else [script]

    txobj = deserialize(tx)
    txobj["ins"][i]["script"] = serialize_script([None]+sigs+script_blob)
    return serialize(txobj)
def tx_to_hex(tx):
    """
     Convert a bitcoin-given transaction into its hex string.
     Does NOT work on coinbase transactions.
     """
    tx_ins = []
    tx_outs = []
    for inp in tx['vin']:
        next_inp = {
            "outpoint": {
                "index": int(inp['vout']),
                "hash": str(inp['txid'])
            }
        }
        if 'sequence' in inp:
            next_inp['sequence'] = int(inp['sequence'])
        else:
            next_inp['sequence'] = pybitcoin.UINT_MAX

        if 'scriptSig' in inp:
            next_inp['script'] = str(inp['scriptSig']['hex'])
        else:
            next_inp['script'] = ""

        tx_ins.append(next_inp)

    for out in tx['vout']:
        next_out = {
            'value': int(round(Decimal(out['value']) * Decimal(10**8))),
            'script': str(out['scriptPubKey']['hex'])
        }
        tx_outs.append(next_out)

    tx_fields = {
        "locktime": int(tx['locktime']),
        "version": int(tx['version']),
        "ins": tx_ins,
        "outs": tx_outs
    }

    tx_serialized = bitcoin.serialize(tx_fields)
    return str(tx_serialized)
Esempio n. 46
0
def tx_to_hex( tx ):
     """
     Convert a bitcoin-given transaction into its hex string.
     Does NOT work on coinbase transactions.
     """
     tx_ins = []
     tx_outs = []
     for inp in tx['vin']:
         next_inp = {
            "outpoint": {
               "index": int(inp['vout']),
               "hash": str(inp['txid'])
            }
         }
         if 'sequence' in inp:
             next_inp['sequence'] = int(inp['sequence'])
         else:
             next_inp['sequence'] = pybitcoin.UINT_MAX

         if 'scriptSig' in inp:
             next_inp['script'] = str(inp['scriptSig']['hex'])
         else:
             next_inp['script'] = ""

         tx_ins.append(next_inp)
     
     for out in tx['vout']:
         next_out = {
            'value': int(round(Decimal(out['value']) * Decimal(10**8))),
            'script': str(out['scriptPubKey']['hex'])
         }
         tx_outs.append(next_out)

     tx_fields = {
        "locktime": int(tx['locktime']),
        "version": int(tx['version']),
        "ins": tx_ins,
        "outs": tx_outs
     }

     tx_serialized = bitcoin.serialize( tx_fields )
     return str(tx_serialized)
Esempio n. 47
0
 def test_native_P2WPKH_SIGHASH_ALL(self):
     tx = TEST_CASES[0]
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs, locktime=tx['locktime'])
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     partially_signed = p2pk_sign(
         stripped_tx, 0,
         self.append_compressed_flag_to_privkey(tx['ins'][0]['privkey']))
     signed = segwit_sign(
         partially_signed, 1,
         self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey']),
         tx['ins'][1]['amount'] * 10**8)
     self.assertEqual(signed, tx['signed'])
     print('[Native P2WPKH] SIGHASH_ALL OK')
Esempio n. 48
0
def apply_multisignatures(*args):
    # tx,i,script,sigs OR tx,i,script,sig1,sig2...,sig[n]
    tx, i, script = args[0], int(args[1]), args[2]
    sigs = args[3] if isinstance(args[3], list) else list(args[3:])

    if isinstance(script, str) and re.match('^[0-9a-fA-F]*$', script):
        script = binascii.unhexlify(script)
    sigs = [binascii.unhexlify(x) if x[:2] == '30' else x for x in sigs]
    if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx):
        signed_tx = apply_multisignatures(binascii.unhexlify(tx), i, script,
                                          sigs)
        return binascii.hexlify(signed_tx)

    # Not pushing empty elements on the top of the stack if passing no
    # script (in case of bare multisig inputs there is no script)
    script_blob = [] if script.__len__() == 0 else [script]

    txobj = deserialize(tx)
    txobj["ins"][i]["script"] = serialize_script([None] + sigs + script_blob)
    return serialize(txobj)
Esempio n. 49
0
 def test_native_P2WPKH_SIGHASH_ALL(self):
     tx = TEST_CASES[0]
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs, locktime=tx['locktime'])
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     partially_signed = p2pk_sign(stripped_tx,
                                  0,
                                  self.append_compressed_flag_to_privkey(tx['ins'][0]['privkey']))
     signed = segwit_sign(partially_signed,
                          1,
                          self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey']),
                          tx['ins'][1]['amount'] * 10**8)
     self.assertEqual(signed, tx['signed'])
     print('[Native P2WPKH] SIGHASH_ALL OK')
Esempio n. 50
0
def bech32_sign(tx, i, priv, amount, script=None, hashcode=SIGHASH_ALL):
    from bitcoin import deserialize, segwit_signature_form, ecdsa_raw_sign, der_encode_sig, serialize, compress
    i = int(i)
    txobj = tx if isinstance(tx, dict) else deserialize(tx)
    if len(priv) <= 33:
        priv = binascii.hexlify(priv)
    pub = compress(privkey_to_pubkey(priv))
    script = script or ('76a914' + hash160(binascii.unhexlify(pub)) + '88ac')
    signing_tx = segwit_signature_form(tx,
                                       i,
                                       script,
                                       amount,
                                       hashcode=hashcode)
    rawsig = ecdsa_raw_sign(
        hashlib.sha256(
            hashlib.sha256(
                binascii.unhexlify(signing_tx)).digest()).hexdigest(), priv)
    sig = der_encode_sig(*rawsig) + encode(hashcode, 16, 2)
    txobj['ins'][i]['txinwitness'] = [sig, pub]
    return serialize(txobj)
Esempio n. 51
0
    def sign( self, privkey ):
	if( self.tx is None or self.redeemScript is None ):
            raise RuntimeError( "You have not entered in a tx to sign" )

        try:
            pub = bitcoin.privtopub( privkey )
            if pub not in self.pubs:
                pub = bitcoin.encode_pubkey( pub, 'hex_compressed' )
                if pub not in self.pubs: 
                    raise ValueError( "Key doesn't match any public keys in redeemscript" )
            
            stx = bitcoin.serialize( self.tx )
            sigs = self.extract_sigs( self.tx ) 
            sigs.append( bitcoin.multisign( stx, 0, self.redeemScript, privkey ) )
            sigs = self.reorder_sigs( sigs )
            stx = bitcoin.apply_multisignatures( stx, 0, self.redeemScript, sigs )
            return stx, ( len(sigs) >= self.neededSigs )
        except ValueError as e:
            raise RuntimeError( "Key Error", str( e ) )
        except Exception as e: 
            raise RuntimeError( "Unexpected Error", "Unexpected error formating key: " + str( e ) )
Esempio n. 52
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.info('txid = ' + self.txid)

        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;'
            ).fetchone()
            counterparty = crow['counterparty']
            log.info('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True
        elif tx_broadcast == 'tor':
            socks5_host = jm_single().config.get("MESSAGING",
                "socks5_host").split(",")[0]
            socks5_port = int(jm_single().config.get("MESSAGING",
                "socks5_port").split(",")[0])
            pushed = tor_broadcast_tx(tx, (socks5_host, socks5_port),
                testnet=(get_network() == "testnet"))

        if not pushed:
            log.error('unable to pushtx')
        return pushed
Esempio n. 53
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.info('txid = ' + self.txid)

        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;').fetchone()
            counterparty = crow['counterparty']
            log.info('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True
        elif tx_broadcast == 'tor':
            socks5_host = jm_single().config.get("MESSAGING",
                                                 "socks5_host").split(",")[0]
            socks5_port = int(jm_single().config.get(
                "MESSAGING", "socks5_port").split(",")[0])
            pushed = tor_broadcast_tx(tx, (socks5_host, socks5_port),
                                      testnet=(get_network() == "testnet"))

        if not pushed:
            log.error('unable to pushtx')
        return pushed
Esempio n. 54
0
def tx_sign_singlesig(tx, idx, private_key_info, hashcode=bitcoin.SIGHASH_ALL):
    """
    Sign a p2pkh input
    Return the signed transaction

    TODO: move to virtualchain

    NOTE: implemented here instead of bitcoin, since bitcoin.sign() can cause a stack overflow
    while converting the private key to a public key.
    """
    pk = virtualchain.BitcoinPrivateKey(str(private_key_info))
    pubk = pk.public_key()

    pub = pubk.to_hex()
    addr = pubk.address()

    script = virtualchain.make_payment_script(addr)
    sig = tx_make_input_signature(tx, idx, script, private_key_info, hashcode)

    txobj = bitcoin.deserialize(str(tx))
    txobj['ins'][idx]['script'] = bitcoin.serialize_script([sig, pub])
    return bitcoin.serialize(txobj)
Esempio n. 55
0
def sign(tx, i, priv, t="default", script="", hashcode=SIGHASH_ALL):
    i = int(i)
    #if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx):
    if not re.match('^[0-9a-fA-F]*$', tx):
        return binascii.unhexlify(custom_sign(safe_hexlify(tx), i, priv, hashcode))
    if len(priv) <= 33:
        priv = b.safe_hexlify(priv)
    pub = b.privkey_to_pubkey(priv)
    address = b.pubkey_to_address(pub)
    if t not in ["atomic_1", "atomic_2"]:
        script=b.mk_pubkey_script(address)
    if script=="": error()
    signing_tx = b.signature_form(tx, i, script, hashcode)#mk_pubkey_scrip needs to be our custom scriptn
    sig = b.ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = b.deserialize(tx)
    if t=="atomic_1":
        txobj["ins"][i]["script"] = b.serialize_script([sig])
    if t=="atomic_2":
        old_sig = txobj["ins"][i]["script"]
        txobj["ins"][i]["script"] = b.serialize_script([old_sig, sig, 1])
    else:
        txobj["ins"][i]["script"] = b.serialize_script([sig, pub])
    return b.serialize(txobj)
Esempio n. 56
0
def test_serialization_roundtrip(tx_type, tx_id, tx_hex):
    assert tx_hex == btc.serialize(btc.deserialize(tx_hex))
Esempio n. 57
0
 def test_P2SH_P2WSH_ALL_SIGHASH(self):
     tx = TEST_CASES[3]
     VIN_AMOUNT = int(9.87654321 * 10**8)
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs)
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     priv0 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][0])
     priv1 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][1])
     priv2 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][2])
     priv3 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][3])
     priv4 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][4])
     priv5 = self.append_compressed_flag_to_privkey(tx['ins'][0]['privkeys'][5])
     witness_script = mk_multisig_script(privtopub(priv0),
                                         privtopub(priv1),
                                         privtopub(priv2),
                                         privtopub(priv3),
                                         privtopub(priv4),
                                         privtopub(priv5),
                                         6)
     self.assertEqual(witness_script, tx['ins'][0]['witness_script'])
     sign0 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv0,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_ALL)
     sign1 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv1,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_NONE)
     sign2 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv2,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_SINGLE)
     sign3 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv3,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_ALL|SIGHASH_ANYONECANPAY)
     sign4 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv4,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_NONE|SIGHASH_ANYONECANPAY)
     sign5 = segwit_multisign(generated_tx,
                              0,
                              witness_script,
                              priv5,
                              VIN_AMOUNT,
                              hashcode=SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)
     signed = apply_segwit_multisignatures(stripped_tx, 0, witness_script,
                                           [sign0, sign1, sign2, sign3, sign4, sign5],
                                           nested=True)
     self.assertEqual(signed, tx['signed'])
     print('[P2WSH 6-of-6 multisig NESTED in P2SH] SIGHASH_SINGLE\SIGHASH_ALL\SIGHASH_NONE & ANYONECANPAY')