def get_address_from_input_script(bytes): decoded = [ x for x in script_GetOp(bytes) ] # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): return public_key_to_bc_address(decoded[1][1]) # p2sh transaction, 2 of n match = [ opcodes.OP_0, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): bytes = decoded[3][1] dec2 = [ x for x in script_GetOp(bytes) ] # 2 of 2 match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2, opcodes.OP_CHECKMULTISIG ] if match_decoded(dec2, match2): pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex') ] s = multisig_script(pubkeys) return hash_160_to_bc_address(hash_160(s.decode('hex')), 5) # 2 of 3 match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG ] if match_decoded(dec2, match2): pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex'), dec2[3][1].encode('hex') ] s = multisig_script(pubkeys) return hash_160_to_bc_address(hash_160(s.decode('hex')), 5) return "p2sh, unknown" return "(None)"
def serialize_preimage(self, i): nVersion = int_to_hex(1, 4) nHashType = int_to_hex(1, 4) nLocktime = int_to_hex(self.locktime, 4) inputs = self.inputs() outputs = self.outputs() txin = inputs[i] if self.is_segwit_input(txin): hashPrevouts = Hash(''.join(self.serialize_outpoint(txin) for txin in inputs).decode('hex')).encode('hex') hashSequence = Hash(''.join(int_to_hex(txin.get('sequence', 0xffffffff), 4) for txin in inputs).decode('hex')).encode('hex') hashOutputs = Hash(''.join(self.serialize_output(o) for o in outputs).decode('hex')).encode('hex') outpoint = self.serialize_outpoint(txin) pubkey = txin['pubkeys'][0] pkh = bitcoin.hash_160(pubkey.decode('hex')).encode('hex') redeemScript = '00' + push_script(pkh) scriptCode = push_script('76a9' + push_script(pkh) + '88ac') script_hash = bitcoin.hash_160(redeemScript.decode('hex')).encode('hex') scriptPubKey = 'a9' + push_script(script_hash) + '87' amount = int_to_hex(txin['value'], 8) nSequence = int_to_hex(txin.get('sequence', 0xffffffff), 4) preimage = nVersion + hashPrevouts + hashSequence + outpoint + scriptCode + amount + nSequence + hashOutputs + nLocktime + nHashType else: txins = var_int(len(inputs)) + ''.join(self.serialize_input(txin, self.get_preimage_script(txin) if i==k else '') for k, txin in enumerate(inputs)) txouts = var_int(len(outputs)) + ''.join(self.serialize_output(o) for o in outputs) preimage = nVersion + txins + txouts + nLocktime + nHashType return preimage
def get_address_from_input_script(bytes): try: decoded = [x for x in script_GetOp(bytes)] except: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return [], [], "(None)" # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): return ([decoded[1][1].encode('hex')], [decoded[0][1].encode('hex')], public_key_to_bc_address(decoded[1][1])) # p2sh transaction, 2 of n match = [opcodes.OP_0] while len(match) < len(decoded): match.append(opcodes.OP_PUSHDATA4) if match_decoded(decoded, match): redeemScript = decoded[-1][1] signatures = map(lambda x: x[1].encode('hex'), decoded[1:-1]) dec2 = [x for x in script_GetOp(redeemScript)] # 2 of 2 match2 = [opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2, opcodes.OP_CHECKMULTISIG] if match_decoded(dec2, match2): pubkeys = [dec2[1][1].encode('hex'), dec2[2][1].encode('hex')] return (pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), chain.script_version)) # 2 of 3 match2 = [opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG] if match_decoded(dec2, match2): pubkeys = [dec2[1][1].encode('hex'), dec2[2][1].encode('hex'), dec2[3][1].encode('hex')] return (pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), chain.script_version)) print_error("cannot find address in input script", bytes.encode('hex')) return [], [], "(None)"
def get_address_from_input_script(bytes): try: decoded = [x for x in script_GetOp(bytes)] except: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return [], [], "(None)" # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): return ([decoded[1][1].encode('hex')], [decoded[0][1].encode('hex')], public_key_to_bc_address(decoded[1][1])) # p2sh transaction, 2 of n match = [opcodes.OP_0] while len(match) < len(decoded): match.append(opcodes.OP_PUSHDATA4) if match_decoded(decoded, match): redeemScript = decoded[-1][1] signatures = map(lambda x: x[1].encode('hex'), decoded[1:-1]) dec2 = [x for x in script_GetOp(redeemScript)] # 2 of 2 match2 = [opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2, opcodes.OP_CHECKMULTISIG] if match_decoded(dec2, match2): pubkeys = [dec2[1][1].encode('hex'), dec2[2][1].encode('hex')] return (pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5)) # 2 of 3 match2 = [opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG] if match_decoded(dec2, match2): pubkeys = [dec2[1][1].encode('hex'), dec2[2][1].encode('hex'), dec2[3][1].encode('hex')] return (pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5)) print_error("cannot find address in input script", bytes.encode('hex')) return [], [], "(None)"
def sign(self, keypairs): for i, txin in enumerate(self.inputs()): num = txin['num_sig'] pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin) for j, x_pubkey in enumerate(x_pubkeys): signatures = filter(None, txin['signatures']) if len(signatures) == num: # txin is complete break fd_key = 'fd00' + bitcoin.hash_160( pubkeys[j].decode('hex')).encode('hex') if x_pubkey in keypairs.keys() or fd_key in keypairs.keys(): print_error("adding signature for", x_pubkey) sec = keypairs.get(x_pubkey) or keypairs.get(fd_key) pubkey = public_key_from_private_key(sec) assert pubkey == pubkeys[j] # add signature pre_hash = Hash(self.serialize_preimage(i).decode('hex')) pkey = regenerate_key(sec) secexp = pkey.secret private_key = bitcoin.MySigningKey.from_secret_exponent( secexp, curve=SECP256k1) public_key = private_key.get_verifying_key() sig = private_key.sign_digest_deterministic( pre_hash, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der) assert public_key.verify_digest( sig, pre_hash, sigdecode=ecdsa.util.sigdecode_der) txin['signatures'][j] = sig.encode('hex') txin['x_pubkeys'][j] = pubkey self._inputs[i] = txin print_error("is_complete", self.is_complete()) self.raw = self.serialize()
def sign(self, keypairs): for i, txin in enumerate(self.inputs()): num = txin['num_sig'] pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin) for j, x_pubkey in enumerate(x_pubkeys): signatures = filter(None, txin['signatures']) if len(signatures) == num: # txin is complete break fd_key = 'fd00' + bitcoin.hash_160(pubkeys[j].decode('hex')).encode('hex') if x_pubkey in keypairs.keys() or fd_key in keypairs.keys(): print_error("adding signature for", x_pubkey) sec = keypairs.get(x_pubkey) or keypairs.get(fd_key) pubkey = public_key_from_private_key(sec) assert pubkey == pubkeys[j] # add signature pre_hash = Hash(self.serialize_preimage(i).decode('hex')) pkey = regenerate_key(sec) secexp = pkey.secret private_key = bitcoin.MySigningKey.from_secret_exponent(secexp, curve = SECP256k1) public_key = private_key.get_verifying_key() sig = private_key.sign_digest_deterministic(pre_hash, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der) assert public_key.verify_digest(sig, pre_hash, sigdecode = ecdsa.util.sigdecode_der) txin['signatures'][j] = sig.encode('hex') txin['x_pubkeys'][j] = pubkey self._inputs[i] = txin print_error("is_complete", self.is_complete()) self.raw = self.serialize()
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = Transaction.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5) return {'address': address, 'redeemScript': redeem_script}
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = script.multisig_script(pubkeys, num) address = hash_160_to_bc_address( hash_160(redeem_script.decode('hex')), chainparams.get_active_chain().p2sh_version) return {'address': address, 'redeemScript': redeem_script}
def signtransaction(self, tx, privkey=None): """Sign a transaction. The wallet keys will be used unless a private key is provided.""" if privkey: pubkey = bitcoin.public_key_from_private_key(privkey) h160 = bitcoin.hash_160(pubkey.decode('hex')) x_pubkey = 'fd' + (chr(0) + h160).encode('hex') tx.sign({x_pubkey:privkey}) else: self.wallet.sign_transaction(tx, self._password) return tx.as_dict()
def serialize_for_sig(self, update_time=False): """Serialize the message for signing.""" if update_time: self.sig_time = int(time.time()) s = str(self.addr) s += str(self.sig_time) if self.protocol_version < 70201: # Decode the hex-encoded bytes for our keys. s += self.collateral_key.decode('hex') s += self.delegate_key.decode('hex') else: # Use the RIPEMD-160 hashes of our keys. s += bitcoin.hash_encode(bitcoin.hash_160(self.collateral_key.decode('hex'))) s += bitcoin.hash_encode(bitcoin.hash_160(self.delegate_key.decode('hex'))) s += str(self.protocol_version) return s
def get_preimage_script(self, txin): # only for non-segwit if txin['type'] == 'p2pkh': return get_scriptPubKey(txin['address']) elif txin['type'] == 'p2sh': pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin) return multisig_script(pubkeys, txin['num_sig']) elif txin['type'] == 'p2wpkh-p2sh': pubkey = txin['pubkeys'][0] pkh = bitcoin.hash_160(pubkey.decode('hex')).encode('hex') return '76a9' + push_script(pkh) + '88ac' else: raise TypeError('Unknown txin type', _type)
def serialize_preimage(self, i): nVersion = int_to_hex(1, 4) nHashType = int_to_hex(1, 4) nLocktime = int_to_hex(self.locktime, 4) inputs = self.inputs() outputs = self.outputs() txin = inputs[i] if self.is_segwit_input(txin): hashPrevouts = Hash(''.join( self.serialize_outpoint(txin) for txin in inputs).decode('hex')).encode('hex') hashSequence = Hash(''.join( int_to_hex(txin.get('sequence', 0xffffffff), 4) for txin in inputs).decode('hex')).encode('hex') hashOutputs = Hash(''.join( self.serialize_output(o) for o in outputs).decode('hex')).encode('hex') outpoint = self.serialize_outpoint(txin) pubkey = txin['pubkeys'][0] pkh = bitcoin.hash_160(pubkey.decode('hex')).encode('hex') redeemScript = '00' + push_script(pkh) scriptCode = push_script('76a9' + push_script(pkh) + '88ac') script_hash = bitcoin.hash_160( redeemScript.decode('hex')).encode('hex') scriptPubKey = 'a9' + push_script(script_hash) + '87' amount = int_to_hex(txin['value'], 8) nSequence = int_to_hex(txin.get('sequence', 0xffffffff), 4) preimage = nVersion + hashPrevouts + hashSequence + outpoint + scriptCode + amount + nSequence + hashOutputs + nLocktime + nHashType else: txin_script = lambda txin: txin.get( 'redeemScript') or get_scriptPubKey(txin['address']) txins = var_int(len(inputs)) + ''.join( self.serialize_input(txin, txin_script(txin) if i == k else '') for k, txin in enumerate(inputs)) txouts = var_int(len(outputs)) + ''.join( self.serialize_output(o) for o in outputs) preimage = nVersion + txins + txouts + nLocktime + nHashType return preimage
def get_address_from_input_script(bytes): decoded = [ x for x in script_GetOp(bytes) ] # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): return None, None, public_key_to_bc_address(decoded[1][1]) # p2sh transaction, 2 of n match = [ opcodes.OP_0 ] while len(match) < len(decoded): match.append(opcodes.OP_PUSHDATA4) if match_decoded(decoded, match): redeemScript = decoded[-1][1] num = len(match) - 2 signatures = map(lambda x:x[1].encode('hex'), decoded[1:-1]) dec2 = [ x for x in script_GetOp(redeemScript) ] # 2 of 2 match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2, opcodes.OP_CHECKMULTISIG ] if match_decoded(dec2, match2): pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex') ] return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5) # 2 of 3 match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG ] if match_decoded(dec2, match2): pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex'), dec2[3][1].encode('hex') ] return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5) raise BaseException("no match for scriptsig")
def get_preimage_script(self, txin): preimage_script = txin.get('preimage_script', None) if preimage_script is not None: return preimage_script pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin) if txin['type'] == 'p2pkh': return bitcoin.address_to_script(txin['address']) elif txin['type'] in ['p2sh', 'p2wsh', 'p2wsh-p2sh']: return multisig_script(pubkeys, txin['num_sig']) elif txin['type'] in ['p2wpkh', 'p2wpkh-p2sh']: pubkey = pubkeys[0] pkh = bh2u(bitcoin.hash_160(bfh(pubkey))) return '76a9' + push_script(pkh) + '88ac' elif txin['type'] == 'p2pk': pubkey = pubkeys[0] return bitcoin.public_key_to_p2pk_script(pubkey) else: raise TypeError('Unknown txin type', txin['type'])
def privCKD(self, child_num, hardened=False): if child_num >= 2**31: raise Exception('BIP32.privCKD: child number too large') if hardened: child_num = child_num | 2**31 data = chr(0) + self.privkey + ('%08x' % child_num).decode('hex') else: data = self.pubkey + ('%08x' % child_num).decode('hex') I = hmac.new(self.chaincode, data, hashlib.sha512).digest() Il = I[:32] Ir = I[32:] self.depth = self.depth + 1 self.fingerprint = bitcoin.hash_160(self.pubkey)[:4] self.chaincode = Ir priv = (int(Il.encode('hex'), 16) + int(self.privkey.encode('hex'), 16)) % ecc.cN self.privkey = ('%064x' % priv).decode('hex') self.pubkey = bitcoin.privkeyToPubkey(self.privkey) self.is_private = True self.child_num = child_num & ((2**31) - 1) self.hard = hardened
def pubCKD(self, child_num, hardened=False): if child_num >= 2**31: raise Exception('BIP32.pubCKD: child number too large') if hardened: raise Exception('BIP32.pubCKD: no hardened paths allowed') else: data = self.pubkey + ('%08x' % child_num).decode('hex') I = hmac.new(self.chaincode, data, hashlib.sha512).digest() Il = I[:32] Ir = I[32:] self.depth = self.depth + 1 self.fingerprint = bitcoin.hash_160(self.pubkey)[:4] self.chaincode = Ir self.privkey = None pub = bitcoin.privkeyToPubkey(Il, False) point_1 = bitcoin.pubkeyToPoint(pub) point_2 = bitcoin.pubkeyToPoint(self.pubkey) point_3 = ecc.EC_add(point_1, point_2) self.pubkey = bitcoin.pointToPubkey(point_3) self.is_private = False self.child_num = child_num & ((2**31) - 1) self.hard = False
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = script.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), chainparams.get_active_chain().p2sh_version) return {'address':address, 'redeemScript':redeem_script}
def parse_scriptSig(d, _bytes): try: decoded = [ x for x in script_GetOp(_bytes) ] except Exception as e: # coinbase transactions raise an exception print_error("parse_scriptSig: cannot find address in input script (coinbase?)", bh2u(_bytes)) return match = [ opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == 0: # segwit embedded into p2sh # witness version 0 d['address'] = bitcoin.hash160_to_p2sh(bitcoin.hash_160(item)) if len(item) == 22: d['type'] = 'p2wpkh-p2sh' elif len(item) == 34: d['type'] = 'p2wsh-p2sh' else: print_error("unrecognized txin type", bh2u(item)) elif opcodes.OP_1 <= item[0] <= opcodes.OP_16: # segwit embedded into p2sh # witness version 1-16 pass else: # assert item[0] == 0x30 # pay-to-pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [bh2u(item)] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # p2pkh TxIn transactions push a signature # (71-73 bytes) and then their public key # (33 or 65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = bh2u(decoded[0][1]) x_pubkey = bh2u(decoded[1][1]) try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) except: print_error("parse_scriptSig: cannot find address in input script (p2pkh?)", bh2u(_bytes)) return d['type'] = 'p2pkh' d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [ opcodes.OP_0 ] + [ opcodes.OP_PUSHDATA4 ] * (len(decoded) - 1) if match_decoded(decoded, match): x_sig = [bh2u(x[1]) for x in decoded[1:-1]] redeem_script_unsanitized = decoded[-1][1] # for partial multisig txn, this has x_pubkeys try: m, n, x_pubkeys, pubkeys, redeem_script = parse_redeemScript_multisig(redeem_script_unsanitized) except NotRecognizedRedeemScript: print_error("parse_scriptSig: cannot find address in input script (p2sh?)", bh2u(_bytes)) # we could still guess: # d['address'] = hash160_to_p2sh(hash_160(decoded[-1][1])) return # write result in d d['type'] = 'p2sh' d['num_sig'] = m d['signatures'] = parse_sig(x_sig) d['x_pubkeys'] = x_pubkeys d['pubkeys'] = pubkeys d['redeem_script'] = redeem_script d['address'] = hash160_to_p2sh(hash_160(bfh(redeem_script))) return print_error("parse_scriptSig: cannot find address in input script (unknown)", bh2u(_bytes))
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = Transaction.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode("hex")), 5) return {"address": address, "redeemScript": redeem_script}
def cert2hashx(cert): return tohex(hash_160(cert.data.SerializeToString()))
def parse_scriptSig(d, bytes): try: decoded = [x for x in script_GetOp(bytes)] except Exception: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return match = [opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == chr(0): redeemScript = item.encode('hex') d['address'] = bitcoin.hash160_to_p2sh( bitcoin.hash_160(redeemScript.decode('hex'))) d['type'] = 'p2wpkh-p2sh' d['redeemScript'] = redeemScript d['x_pubkeys'] = ["(witness)"] d['pubkeys'] = ["(witness)"] d['signatures'] = ['(witness)'] d['num_sig'] = 1 else: # payto_pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [item.encode('hex')] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') x_pubkey = decoded[1][1].encode('hex') try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) except BaseException: print_error("cannot find address in input script", bytes.encode('hex')) return d['type'] = 'p2pkh' d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [x for x in script_GetOp(decoded[-1][1])] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [safe_parse_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) # write result in d d['type'] = 'p2sh' d['num_sig'] = m d['signatures'] = parse_sig(x_sig) d['x_pubkeys'] = x_pubkeys d['pubkeys'] = pubkeys d['redeemScript'] = redeemScript d['address'] = hash160_to_p2sh(hash_160(redeemScript.decode('hex')))
def alias2pubkeyx(alias,versionin = versno): return hash2pubkeyx(hash_160(norm(alias,versionin)))
asc = binascii.b2a_base64(cert.SerializeToString())[:-1] # without trailing newline asc += '=' # checksum is seperated by = asc += binascii.b2a_base64(('%06x'%crc).decode('hex')) res = '-----BEGIN BTCPKI CERTIFICATE-----\n' res += 'Version: '+cert.version+'\n\n' res += '\n'.join(asc[i:i+72] for i in xrange(0, len(asc), 72)) res += '-----END BTCPKI CERTIFICATE-----\n' return res # TODO: AsciiToCert from e import derivepubkey normalized = 'v0.3_F02' id = hash_160(derivepubkey(hash_160(normalized))).encode('hex') #fname = '$HOME/.bitcoin/testnet3/bcerts/'+id+'.bcrt' fname = id+'.bcrt' f=open(fname,'wb') f.write(cert.SerializeToString()) f.close() print "binary cert written to: "+fname fname = id+'.acrt' f=open(fname,'wb') f.write(CertToAscii(cert)) f.close() print "ascii cert written to: "+fname fname = 'my.data'
if (pubkey == None) or (chain == None): print "Error loading config." sys.exit(0) def generate_from_pub(path, pubkey, chain): """ generate_from_pub(path, pubkey, chain) -> pubkey2, pubkey2_compressed, chain2 path is a list of tuples like [(index1, is_hardened),(index2, is_hardened)] pubkey is the root pubkey chain is the root chain pubkey2, pubkey2_compressed, and chain2 are the results of following this BIP32 derivation path Because this is a pubkey-based generation, none of the path elements may be hardened. """ (index, is_hardened), path2 = path[0], path[1:] if is_hardened: raise Exception("Error: Trying to derive a hardened address using the pubkey") bip32_i = index key2, key2_comp, chain2 = bitcoin.CKD_prime(pubkey,chain, bip32_i) if len(path2) == 0: return key2, key2_comp, chain2 else: return generate(path2, key2, chain2) for is_change in [0,1]: receiving_pubkey, receiving_pubkey_compressed, receiving_chain = generate_from_pub([(is_change,False)], main_pubkey, main_chain) for path, i in [([(i,False)],i) for i in range(5)]: _, addr_pubkey_compressed, _ = generate_from_pub(path, receiving_pubkey, receiving_chain) addr = bitcoin.hash_160_to_bc_address(bitcoin.hash_160(addr_pubkey_compressed)) print "m/{}/{} = {}".format(is_change, i, addr)
fname = "foo1_p2csingle.bcrt" f = open(fname, "wb") f.write(cert.SerializeToString()) f.close() print "binary cert written to: " + fname # fname = id+'.acrt' # f=open(fname,'wb') # f.write(CertToAscii(cert)) # f.close() # print "ascii cert written to: "+fname # fname = 'my.data' # f=open(fname,'wb') # f.write(cert.data.SerializeToString()) # f.close() # print "binary data part written to: "+fname # see the hash print "hash of data part is: " + hash_160(cert.data.SerializeToString()).encode("hex") print "hex binary cert: " + cert.SerializeToString().encode("hex") # print CertToAscii(cert) # print CertToAsciiMsg(cert) # OLD # from subprocess import Popen,PIPE,check_call,call # p = Popen(['./bitcoind','-testnet','registeralias','foo3','0.5',hash],stdout=PIPE) # result = p.stdout.read() # print result
key2 and chain2 are the results of following this BIP32 derivation path """ (index, is_hardened), path2 = path[0], path[1:] bip32_i = index + bitcoin.BIP32_PRIME if is_hardened else index key2, chain2 = bitcoin.CKD(key, chain, bip32_i) if len(path2) == 0: return key2, chain2 else: return generate(path2, key2, chain2) # An Array of (index,is_hardened) tuples path = [(0, True), (0, False)] # Corresponds to /0h/0 main_key, main_chain = generate(path, k, c) for is_change in [0, 1]: receiving_key, receiving_chain = generate([(is_change, False)], main_key, main_chain) for path, i in [([(i, False)], i) for i in range(5)]: addr_key, _ = generate(path, receiving_key, receiving_chain) pubkey, pubkey_compressed = bitcoin.get_pubkeys_from_secret(addr_key) addr = bitcoin.hash_160_to_bc_address( bitcoin.hash_160(pubkey_compressed)) print "m/0h/0/{}/{} = {}".format(is_change, i, addr) main_pubkey, main_pubkey_compressed = bitcoin.get_pubkeys_from_secret(main_key) print "Writing to file." with open("bitcoin_config.txt", "w") as config_file: config_file.write("master_pubkey: " + main_pubkey.encode('hex') + "\n") config_file.write("master_chain: " + main_chain.encode('hex') + "\n")
def aliastofilename(alias,versionin = versno): # legacy version return hash2idx(hash_160(norm(alias,versionin)))
def alias2idx(alias,versionin = versno): return hash2idx(hash_160(norm(alias,versionin)))
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = transaction.multisig_script(pubkeys, num) address = bitcoin.hash160_to_p2sh(hash_160(redeem_script.decode('hex'))) return {'address':address, 'redeemScript':redeem_script}
def createmultisig(self, num, pubkeys): assert isinstance(pubkeys, list) redeem_script = Transaction.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), bitcoin.SCRIPT_ADDR) return {'address':address, 'redeemScript':redeem_script}
def point2id(p): return bitcoin.hash_160(point2pubkey(p))
def parse_scriptSig(d, bytes): try: decoded = [ x for x in script_GetOp(bytes) ] except Exception: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return match = [ opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == chr(0): redeemScript = item.encode('hex') d['address'] = bitcoin.hash160_to_p2sh(bitcoin.hash_160(redeemScript.decode('hex'))) d['type'] = 'p2wpkh-p2sh' d['redeemScript'] = redeemScript d['x_pubkeys'] = ["(witness)"] d['pubkeys'] = ["(witness)"] d['signatures'] = ['(witness)'] d['num_sig'] = 1 else: # payto_pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [item.encode('hex')] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') x_pubkey = decoded[1][1].encode('hex') try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) except: import traceback traceback.print_exc(file=sys.stdout) print_error("cannot find address in input script", bytes.encode('hex')) return d['type'] = 'p2pkh' d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [ opcodes.OP_0 ] + [ opcodes.OP_PUSHDATA4 ] * (len(decoded) - 1) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [ x for x in script_GetOp(decoded[-1][1]) ] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [ op_m ] + [opcodes.OP_PUSHDATA4]*n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [xpubkey_to_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) # write result in d d['type'] = 'p2sh' d['num_sig'] = m d['signatures'] = parse_sig(x_sig) d['x_pubkeys'] = x_pubkeys d['pubkeys'] = pubkeys d['redeemScript'] = redeemScript d['address'] = hash160_to_p2sh(hash_160(redeemScript.decode('hex')))
def createmultisig(self, num, pubkeys): assert isinstance(pubkeys, list) redeem_script = Transaction.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5) return {'address':address, 'redeemScript':redeem_script}
def point2idx(p): return tohex(bitcoin.hash_160(point2pubkey(p)))
def pubkey2id(pubkey): return bitcoin.hash_160(toraw(pubkey))
def cert2hash(cert): return hash_160(cert.data.SerializeToString())