def partial_spend_p2sh_mediator(redeemScript, rein, mediator_address, mediator_sig=False): txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) (txins, total_value) = unspent_txins(txin_p2sh_address, rein.testnet) if len(txins) == 0: raise ValueError('No unspent txins found') txins_str = "" txins_obj = [] for txid, vout in txins: txins_str += " " + txid + "-" + str(vout) txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout))) fee = 0.00025 amount = round(total_value - fee, 8) if amount <= 0: raise ValueError('Not enough value in the inputs') if mediator_sig: txout = CMutableTxOut( amount * COIN, CBitcoinAddress(mediator_address).to_scriptPubKey()) tx = CMutableTransaction(txins_obj, [txout]) seckey = CBitcoinSecret(rein.user.dkey) ntxins = len(txins_obj) sig = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig += " " + b2x(seckey.sign(sighash) + x("01")) return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address), sig[1:]) return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address))
def main(): ''' Our main function. ''' SelectParams('mainnet') decoded_transaction = eval(open('transaction_to_sign.txt').read()) # pylint: disable=eval-used txin_txid = lx(decoded_transaction['vin'][0]['txid']) txin_vout = 0 tx_in = CMutableTxIn(COutPoint(txin_txid, txin_vout)) tx_out = [] for idx in range(len(decoded_transaction['vout'])): satoshis = int(COIN * decoded_transaction['vout'][idx]['value']) script_pub_key = CScript(bytes.fromhex(decoded_transaction['vout'][idx]['scriptPubKey']['hex'])) tx_out.append(CMutableTxOut(satoshis, script_pub_key)) tx_to_spend = CMutableTransaction([tx_in], tx_out) priv_1 = CBitcoinSecret.from_secret_bytes(bytes.fromhex(PRIV_HEX_1)) priv_2 = CBitcoinSecret.from_secret_bytes(bytes.fromhex(PRIV_HEX_2)) txin_redeem_script = CScript(bytes.fromhex(decoded_transaction['vin'][0]['scriptSig']['hex'])) # Input 0 is fixed. sighash = SignatureHash(txin_redeem_script, tx_to_spend, 0, SIGHASH_ALL) signatures = [] for priv in [priv_1, priv_2]: signatures.append(priv.sign(sighash) + bytes([SIGHASH_ALL])) tx_in.scriptSig = CScript([CScriptOp(0x00), signatures[0], signatures[1], txin_redeem_script]) # script_pub_key Defined in cycle. VerifyScript(tx_in.scriptSig, txin_redeem_script, tx_to_spend, 0, (SCRIPT_VERIFY_P2SH,)) print(b2x(tx_to_spend.serialize()))
def spend_p2sh_mediator(redeemScript, txins_str, amounts, daddrs, sig, rein): txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txins_obj = [] for txin_str in txins_str.split(): txin_list = txin_str.split("-") txins_obj.append( CMutableTxIn(COutPoint(lx(txin_list[0]), int(txin_list[1])))) txouts = [] len_amounts = len(amounts) for i in range(0, len_amounts): txouts.append( CMutableTxOut( round(amounts[i], 8) * COIN, CBitcoinAddress(daddrs[i]).to_scriptPubKey())) tx = CMutableTransaction(txins_obj, txouts) seckey = CBitcoinSecret(rein.user.dkey) ntxins = len(txins_obj) sig_list = [] for s in sig.split(): sig_list.append(x(s)) sig2_str = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig2 = seckey.sign(sighash) + x("01") sig2_str += " " + b2x(sig2) txins_obj[i].scriptSig = CScript( [OP_0, sig2, sig_list[i], txin_redeemScript]) VerifyScript(txins_obj[i].scriptSig, txin_scriptPubKey, tx, i, (SCRIPT_VERIFY_P2SH, )) tx_bytes = tx.serialize() hash = sha256(sha256(tx_bytes).digest()).digest() txid = b2x(hash[::-1]) txid_causeway = broadcast_tx(b2x(tx_bytes), rein) return (txid, sig2_str[1:])
def partial_spend_p2sh(redeemScript, rein, daddr=None, alt_amount=None, alt_daddr=None): if daddr is None: daddr = rein.user.daddr txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) (txins, total_value) = unspent_txins(txin_p2sh_address, rein.testnet) if len(txins) == 0: raise ValueError( 'Primary escrow is empty. Please inform client to add funds.') txins_str = "" txins_obj = [] for txid, vout in txins: txins_str += " " + txid + "-" + str(vout) txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout))) fee = float(PersistConfig.get(rein, 'fee', 0.001)) amount = round(total_value - fee, 8) if alt_amount: amount = round(amount - alt_amount, 8) if amount <= 0. or alt_amount > total_value - fee: click.echo("amount: " + str(amount) + " alt_amount: " + str(alt_amount) + " total_value: " + str(total_value)) raise ValueError( 'Primary escrow balance too low. Please inform client to add funds.' ) txouts = [] txout = CMutableTxOut(amount * COIN, CBitcoinAddress(daddr).to_scriptPubKey()) txouts.append(txout) if alt_amount: txout_alt = CMutableTxOut( round(alt_amount, 8) * COIN, CBitcoinAddress(alt_daddr).to_scriptPubKey()) txouts.append(txout_alt) tx = CMutableTransaction(txins_obj, txouts) ntxins = len(txins_obj) seckey = CBitcoinSecret(rein.user.dkey) sig = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig += " " + b2x(seckey.sign(sighash)) + "01" if alt_amount: return (txins_str[1:], "{:.8f}".format(amount), daddr, "{:.8f}".format(alt_amount), alt_daddr, sig[1:]) return (txins_str[1:], "{:.8f}".format(amount), daddr, sig[1:])
def sign_and_verify(private_key, message, address): key = CBitcoinSecret(private_key) signature = SignMessage(key=key, message=BitcoinMessage(message)) assert VerifyMessage(address=address, message=BitcoinMessage(message), sig=signature) return signature
def task_handler(database, bitcoind_address, local_address): """Task handler thread main function.""" logger.debug("Starting task handler.") logger.debug("bitcoind address: %s", bitcoind_address) Channel.bitcoind = bitcoin.rpc.Proxy(bitcoind_address) Channel.local_address = local_address try: root_key = database.Get(b'root_key') except KeyError: # TODO: grab a real private key from bitcoind root_key = CBitcoinSecret.from_secret_bytes( bytes(bitcoind_address, 'ascii')) database.Put(b'root_key', root_key) Channel.private_key = root_key while True: address, task = tasks.get() key = address.encode('utf-8') logger.debug("Task for %s: %r", address, task) try: channel = pickle.loads(database.Get(key)) except KeyError: channel = Channel(address) try: channel.handle(task) except: logger.exception("Error handling task %s for %s", task, address) try: channel.bob.error("An unexpected error occured, I'm dying") finally: raise database.Put(key, pickle.dumps(channel))
def test_get_coinbase_variables(self, m_execute_rpc): m_execute_rpc.side_effect = [ [{ "txid": 'tx_hash_1', 'address': 'address_hash_1', 'amount': 50 }, { "txid": 'tx_hash_2', 'address': 'address_hash_2', 'amount': 25 }], 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc', 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc' ] self.node.create_tx_chains() self.assertEqual(m_execute_rpc.call_count, 3) self.assertEqual(len(self.node._tx_chains), 2) chain_1 = self.node._tx_chains[0] self.assertEqual(chain_1.current_unspent_tx, 'tx_hash_1') self.assertEqual(chain_1.address, 'address_hash_1') self.assertEqual( chain_1.seckey, CBitcoinSecret( 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc')) self.assertEqual(chain_1.amount, 5000000000) chain_2 = self.node._tx_chains[1] self.assertEqual(chain_2.current_unspent_tx, 'tx_hash_2') self.assertEqual(chain_2.address, 'address_hash_2') self.assertEqual(chain_2.amount, 2500000000)
def Normal_Child__extended_private_key(self, index): """ Use an index between 0 and 2147483647. https://learnmeabitcoin.com/technical/hd-wallets """ parent_private_key = self.x_prv[:64] len_parent_public_key = len(self.x_pub) - len(self.chain_code) parent_public_key = self.x_pub[:len_parent_public_key] parent_chain_code = self.chain_code for i in range(index): # TODO: '4' to change index > 2**8 to byte is correctly ?? data = bytes.fromhex(parent_public_key) + i.to_bytes( 4, byteorder='big') key = bytes.fromhex(parent_chain_code) hmac_hash = hmac.new(key=key, msg=data, digestmod=hashlib.sha512).hexdigest() left_32bit = hmac_hash[:64] # 64 hex >> 32 bit child_chain_code = hmac_hash[64:] int_child_private_key = (int(parent_private_key, 16) + int( left_32bit, 16)) % int(Secp256k1_order, 16) child_private_key = hex(int_child_private_key)[2:] child_public_key = CBitcoinSecret.from_secret_bytes( x(child_private_key)).pub.hex() print(" #{}".format(i)) print("\tchild_private_key: {}".format(child_private_key)) print("\tchild_public_key : {}".format(child_public_key)) print("\tchild_chain_code : {}".format(child_chain_code))
def make_private_keys(): """ Convert a list of passphrases into a list of private keys. For the purposes of prototyping, the passphrases are static values. System random should be used for the real deal, though. """ # Note that this function uses python-bitcoinlib CBitcoinSecret objects. private_keys = [] passphrases = [ "password", "passphrase", "hello world", "hello cruel world", "correct horse battery staple", "correct horse battery staple 1", "correct horse battery staple 2", "correct horse battery staple 3", "correct horse battery staple 4", ] passphrases = [bytes(each, "utf-8") for each in passphrases] for passphrase in passphrases: hashed = sha256(passphrase) # compressed=True is default private_key = CBitcoinSecret.from_secret_bytes(hashed, compressed=True) private_keys.append(private_key) return private_keys
def get_public_addresses(key_file): keys = read_keys(key_file) bitcoin_secrets = [CBitcoinSecret(key) for key in keys] bitcoin_addresses = [ P2PKHBitcoinAddress.from_pubkey(key.pub) for key in bitcoin_secrets ] return bitcoin_addresses
def test_get_coinbase_variables(m_execute_rpc, setup): m_execute_rpc.side_effect = [ [{ "txid": 'tx_hash_1', 'address': 'address_hash_1', 'amount': 50 }, { "txid": 'tx_hash_2', 'address': 'address_hash_2', 'amount': 25 }], 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc', 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc' ] setup.create_tx_chains() assert m_execute_rpc.call_count == 3 assert len(setup._tx_chains) == 2 chain_1 = setup._tx_chains[0] assert chain_1.current_unspent_tx == 'tx_hash_1' assert chain_1.address == 'address_hash_1' assert chain_1.seckey == CBitcoinSecret( 'cTCrrgVLfBqEZ1dxmCnEwmiEWzeZHU8uw3CNvLVvbT4CrBeDdTqc') assert chain_1.amount == 5000000000 chain_2 = setup._tx_chains[1] assert chain_2.current_unspent_tx == 'tx_hash_2' assert chain_2.address == 'address_hash_2' assert chain_2.amount == 2500000000
def get_tz_priv(coin, path): session_id = bytes.fromhex(environ.get('TZ_SESSIONID', '')) if trezor and len(session_id) == 32: device = get_transport() client = TrezorClient(transport=device, ui=ClickUI(), session_id=session_id) n_path = parse_path( "m/10065'/0'") # Logical path for BIP0065 operation info = get_public_node(client, n_path, coin_name=coin) side, pubkey = (info.node.public_key[0], info.node.public_key[1:]) left = True if side == 2 else False print("seed", b2x(pubkey), side) priv = encrypt_keyvalue(client, n_path, path, pubkey, ask_on_decrypt=side, ask_on_encrypt=False) client.close() print("priv", b2x(priv), left) is_valid(priv) return CBitcoinSecret.from_secret_bytes(priv) else: print("trezorlib must be available") print("see: https://pypi.org/project/trezor/") print("TZ_SESSIONID enviroinment variable required") print("See: trezorctl get-session --help") sys.exit(2)
def privkey_to_address(privkey): try: key = CBitcoinSecret(privkey) address = str(P2PKHBitcoinAddress.from_pubkey(key.pub)) except: return False return address
def into_transaction(self, dust_secret: CBitcoinSecret, dust_outpoint: OutPointWithTx, feerate): if dust_outpoint.prevout.scriptPubKey != pubkey_to_P2PKH_scriptPubkey( dust_secret.pub): print(b2x(dust_outpoint.prevout.scriptPubKey)) print(b2x(pubkey_to_P2PKH_scriptPubkey(dust_secret.pub))) raise Exception("Outpoint has incorrect scriptPubKey") sum_in = dust_outpoint.prevout.nValue fees = int(tx_size(1, 2) / 1000 * feerate) refund = sum_in - fees - self._life_signal_amount print('fee: %f' % fees) print('amount: %f' % (sum_in - fees)) redeemScript = self.redeemScript unsigned_tx = CTransaction([CTxIn(dust_outpoint.outpoint)], [ CTxOut(self._life_signal_amount, redeemScript.to_p2sh_scriptPubKey()), CTxOut(refund, pubkey_to_P2PKH_scriptPubkey(dust_secret.pub)) ]) # spend the dust input sighash = SignatureHash(dust_outpoint.prevout.scriptPubKey, unsigned_tx, 0, SIGHASH_ALL) sig = dust_secret.sign(sighash) + bytes([SIGHASH_ALL]) sigScript = CScript([sig, dust_secret.pub]) signed_input = [CTxIn(unsigned_tx.vin[0].prevout, sigScript)] return CTransaction(signed_input, unsigned_tx.vout, unsigned_tx.nLockTime)
def before_request(): """Setup g context""" g.config = current_app.config g.bit = g.config['bitcoind'] secret = hashlib.sha256(g.config['secret']).digest() g.seckey = CBitcoinSecret.from_secret_bytes(secret) g.addr = 'http://localhost:%d/' % int(g.config['port']) g.logger = current_app.logger
def create_tx_chains(self): for unspent_tx in self.execute_rpc('listunspent'): seckey = CBitcoinSecret( self.execute_rpc('dumpprivkey', unspent_tx['address'])) tx_chain = TxChain(unspent_tx['txid'], unspent_tx['address'], seckey, unspent_tx['amount'] * 100000000) self._tx_chains.append(tx_chain)
def _scriptSig_by_sgx(self, seckey_sgx: CBitcoinSecret, unsigned_tx, n_in): # sgx spends the true branch branch = OP_TRUE sighash = SignatureHash(self._redeemScript(), unsigned_tx, n_in, SIGHASH_ALL) sig = seckey_sgx.sign(sighash) + bytes([SIGHASH_ALL]) return CScript([sig, seckey_sgx.pub, branch, self._redeemScript()])
def __init__(self, private_key, network=None): self.private_key = private_key self.public_key = CBitcoinSecret.from_secret_bytes( x(private_key)).pub.hex() if network is None: constants.set_mainnet() self.network = constants.net else: self.network = network
def create_checksum_signature(self): key = CBitcoinSecret(self.primary_private_key.wif()) address = P2PKHBitcoinAddress.from_pubkey(key.pub) signature = None print(self.primary_private_key.wif(), str(address)) return str(address), signature
def partial_spend_p2sh_mediator_2 (redeemScript,txins_str,amount,daddr,rein): txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txins_obj = [] for txin_str in txins_str.split(): txin_list = txin_str.split("-") txins_obj.append(CMutableTxIn(COutPoint(lx(txin_list[0]),int(txin_list[1])))) txout = CMutableTxOut(amount*COIN,CBitcoinAddress(daddr).to_scriptPubKey()) tx = CMutableTransaction(txins_obj,[txout]) seckey = CBitcoinSecret(rein.user.dkey) ntxins = len(txins_obj) for i in range(0,ntxins): sighash = SignatureHash(txin_redeemScript,tx,i,SIGHASH_ALL) sig = seckey.sign(sighash)+x("01") txins_obj[i].scriptSig = CScript([OP_0, sig, txin_redeemScript]) #VerifyScript(txins_obj[i].scriptSig, txin_scriptPubKey, tx, i, (SCRIPT_VERIFY_P2SH,)) tx_bytes = tx.serialize() return b2x(tx_bytes)
def makeSinglePrivKey(): """ make private key python bitcoin object :return: python-bitcoin key object """ randbits = generateNewSecretKey() wifPriv = wif.privToWif(randbits.hex()) cPrivObj = CBitcoinSecret(wifPriv) return cPrivObj
def __init__(self, private_key=None, encrypted_private_key=None, password=None): if private_key is None and encrypted_private_key is None: _, secret_hash = generate_secret_with_hash() self.private_key = CBitcoinSecret.from_secret_bytes(secret=secret_hash) elif private_key is not None: self.private_key = CBitcoinSecret(private_key) elif encrypted_private_key is not None and password is not None: self.private_key = CBitcoinSecret(self.decrypt_private_key(encrypted_private_key, password)) elif password is None: raise TypeError( "__init__() missing 'password' argument, since 'encrypted_private_key' argument was provided" ) self.public_key = self.private_key.pub self.address = str(P2PKHBitcoinAddress.from_pubkey(self.public_key))
def __init__(self, base_url): super().__init__(base_url) SelectParams("regtest") for key in self.private_keys: seckey = CBitcoinSecret.from_secret_bytes( codecs.decode(key, "hex_codec")) self.call("importprivkey", str(seckey))
def fetch_key_for_address(key_file, address): keys = read_keys(key_file) bitcoin_secrets = [CBitcoinSecret(key) for key in keys] for key in bitcoin_secrets: addr = P2PKHBitcoinAddress.from_pubkey(key.pub) if str(addr) == address: return key return None
def get_core_priv(): proxy = Proxy() address = proxy.getnewaddress() # address = 'tb1qntuv4la0lh072jtr6ce3avrsghnc200dgamlpq' proxy._call("walletpassphrase", "P@55w0rd", 5) wif = proxy.dumpprivkey(address) proxy._call("walletlock") print("address", address) return CBitcoinSecret(str(wif))
def make_self_transaction(): words = get_randomness('keys.txt') # seckey = CBitcoinSecret.from_secret_bytes(our_keys[1]) h = hashlib.sha256(words).digest() seckey = CBitcoinSecret.from_secret_bytes(h) input_hashes = [('08f7e2c1238cc9b918649e40d72815f32be6dc1ad538cb25331bd1f1c58a5f46',0), ('8642baa47de6ece50c2800221e5bc7eefd7adf4158f24af31fdcfa185cb54fce', 1)] address = P2PKHBitcoinAddress.from_pubkey(seckey.pub) # "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G" return make_transaction(0.00092, input_hashes, address, seckey)
def retrieve_wallettoken(bit_key): bitcoinlib_key = CBitcoinSecret.from_secret_bytes(x(bit_key.to_hex())) pub_key_hex = str(bitcoinlib_key.pub.hex()) message = "bitpost" + str(round( time.time() / 1000)) # we add a timestamp to make the proof valid for only ~ 1h sig = SignMessage(bitcoinlib_key, BitcoinMessage(message)) return bitpost_interface.get_wallettoken(pub_key_hex, sig)
def sign_certs(certificates_metadata): """Sign certificates. Internet should be off for the scope of this function.""" logging.info('signing certificates') pk = helpers.import_key() secret_key = CBitcoinSecret(pk) for uid, certificate_metadata in certificates_metadata.items(): with open(certificate_metadata.unsigned_certificate_file_name, 'r') as cert_in, \ open(certificate_metadata.signed_certificate_file_name, 'wb') as signed_cert: cert = do_sign(cert_in.read(), secret_key) signed_cert.write(bytes(cert, 'utf-8'))
def scriptSig_by_key1(self, secret_key: CBitcoinSecret, unsigned_tx: CTransaction, which_to_sign): assert secret_key.pub == self._key1 branch = OP_TRUE sighash = SignatureHash(self.redeemScript, unsigned_tx, which_to_sign, SIGHASH_ALL) sig = secret_key.sign(sighash) + bytes([SIGHASH_ALL]) return CScript([sig, self._key1, branch, self.redeemScript])
def sign_refund_tx(self, tx_hex, key_no=1, actor="us"): key_no -= 1 if key_no == 0: ecdsa = self.ecdsa_us[0] if key_no == 1: ecdsa = self.ecdsa_us[1] tx = CTransaction.deserialize(binascii.unhexlify(tx_hex)) sighash = SignatureHash(bond_redeem_script(self.ecdsa_us, self.ecdsa_them, self.factory.ecdsa_arbiters[0], actor)["bin"], tx, 0, SIGHASH_ALL) seckey = CBitcoinSecret.from_secret_bytes(ecdsa.get_private_key("bin"), compressed=True) sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) return sig
def __init__(self, key1: CPubKey, relative_timeout): """ a life signal is a coin that can be spent by key1 immediately or a tmp key after a relative_timeout :param key1: :param relative_timeout: """ self._key1 = key1 self._key2 = CBitcoinSecret.from_secret_bytes( Hash("tmpsecret".encode())) self._relative_timeout = relative_timeout self._life_signal_amount = 0.0001 * COIN
def test_sign_message_simple(self): key = CBitcoinSecret( "L4vB5fomsK8L95wQ7GFzvErYGht49JsCPJyJMHpB4xGM6xgi2jvG") address = "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G" message = address message = BitcoinMessage(message) signature = SignMessage(key, message) self.assertTrue(signature) self.assertTrue(VerifyMessage(address, message, signature))
def print_verbose(signature, key, msg): secret = CBitcoinSecret(key) address = P2PKHBitcoinAddress.from_pubkey(secret.pub) message = BitcoinMessage(msg) print('Address: %s' % address) print('Message: %s' % msg) print('Signature: %s' % signature) print('Verified: %s' % VerifyMessage(address, message, signature)) print('\nTo verify using bitcoin core:') print('\n`bitcoin-cli verifymessage %s \'%s\' \'%s\'`\n' % (address, signature.decode('ascii'), msg))
def make_paytopubkeyhash(self, n = None): if n is None: n = random.randrange(0, len(self.keypairs)) secret_bytes = Hash(self.seed + struct.pack('>L', n)) secret_key = CBitcoinSecret.from_secret_bytes(secret_bytes) # pay-to-pubkeyhash scriptPubKey = CScript([OP_DUP, OP_HASH160, Hash160(secret_key.pub), OP_EQUALVERIFY, OP_CHECKSIG]) self.keypairs[scriptPubKey] = secret_key return scriptPubKey
def make_multisig(self, n = None): if n is None: n = random.randrange(0, len(self.keypairs)) secret_bytes = Hash(self.seed + struct.pack('>L', n)) secret_key = CBitcoinSecret.from_secret_bytes(secret_bytes) # 1-of-1 CHECKMULTISIG scriptPubKey's scriptPubKey = CScript([1, secret_key.pub, 1, OP_CHECKMULTISIG]) self.keypairs[scriptPubKey] = secret_key return scriptPubKey
def get_private_key(self): """Attempt to parse the private key that was input.""" txt = str(self.privkey_edit.text()) privkey = None if is_hex(txt): txt = format_hex_string(txt, with_prefix=False) try: privkey = CBitcoinSecret.from_secret_bytes(x(txt)) except Exception: pass return privkey
def create_signature(self, privkey, reedem_script): """ Exports a raw signature suitable for use in a multisig transaction """ seckey = CBitcoinSecret.from_secret_bytes(x(bitcointools.encode_privkey(privkey, "hex"))) signatures = [] for i in range(len(self.tx.vin)): sighash = SignatureHash(CScript(x(reedem_script)), self.tx, i, SIGHASH_ALL) signatures.append({ "index": i, "signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex") }) return signatures
def test_build_send_script(self): """ Run simple sanity checks on script generation """ # Set up constants for this test sender_private_key = CBitcoinSecret.from_secret_bytes(x('4f65da9b656de4036076911707d2b2dbf065689245b8674faa8790e36d7e5850')) sender_public_key = sender_private_key.pub recipient_private_key = CBitcoinSecret.from_secret_bytes(x('cfe8e33672f7045f020210f3c7afbca660e053e4c9415c542ff185e97b175cf0')) recipient_public_key = recipient_private_key.pub send_to_key = CBitcoinSecret.from_secret_bytes(x('15a249b4c09286b877d4708191f1ee8de09903bae034dd9dc8e3286451fa1c80')) send_to_address = P2PKHBitcoinAddress.from_pubkey(send_to_key.pub) secret = x('88d6e51f777b0b8dc0f429da9f372fbc') secret_hash = Hash(secret) quantity = 1000 # Build the send transaction txins = [] # TODO: Provide some random inputs txouts = [CTxOut(quantity, build_send_out_script(sender_public_key, recipient_public_key, secret_hash))] send_tx = CMutableTransaction(txins, txouts) send_tx_n = 0 # We're working with the first transaction input # Build the refund transaction nLockTime = 1422177943 refund_tx = build_unsigned_refund_tx(send_tx, send_tx_n, send_to_address, nLockTime, CFeeRate(0)) # Actually verify the signatures sighash = SignatureHash(send_tx.vout[0].scriptPubKey, refund_tx, 0, SIGHASH_ALL) sender_sig = get_refund_tx_sig(refund_tx, sender_private_key, sender_public_key, recipient_public_key, secret_hash) self.assertTrue(sender_public_key.verify(sighash, sender_sig[:-1])) recipient_sig = get_refund_tx_sig(refund_tx, recipient_private_key, sender_public_key, recipient_public_key, secret_hash) self.assertTrue(recipient_public_key.verify(sighash, recipient_sig[:-1])) # Test building a complete refund transaction refund_tx = build_signed_refund_tx(send_tx, send_tx_n, refund_tx, recipient_sig, recipient_public_key, sender_private_key, secret_hash) # This throws an exception in case of a problem VerifyScript(refund_tx.vin[0].scriptSig, send_tx.vout[send_tx_n].scriptPubKey, refund_tx, 0, (SCRIPT_VERIFY_P2SH,))
def create_signature(self, privkey): """ Exports a raw signature suitable for use in a multisig transaction """ seckey = CBitcoinSecret.from_secret_bytes(unhexlify(privkey)) signatures = [] for i in range(len(self.tx.vin)): txin_scriptPubKey = self.tx.vin[i].scriptSig sighash = SignatureHash(txin_scriptPubKey, self.tx, i, SIGHASH_ALL) signatures.append({ "index": i, "signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex") }) return signatures
def sign(self, privkey): """ Sign each of the inputs with the private key. Inputs should all be sent to the same scriptPubkey so we should only need one key. """ seckey = CBitcoinSecret.from_secret_bytes(x(bitcointools.encode_privkey(privkey, "hex"))) for i in range(len(self.tx.vin)): txin_scriptPubKey = self.tx.vin[i].scriptSig sighash = SignatureHash(txin_scriptPubKey, self.tx, i, SIGHASH_ALL) sig = seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL) self.tx.vin[i].scriptSig = CScript([sig, seckey.pub]) VerifyScript(self.tx.vin[i].scriptSig, txin_scriptPubKey, self.tx, i, (SCRIPT_VERIFY_P2SH,))
def make_address_from_passphrase(passphrase, compressed=True, as_str=True): """ Create a Bitcoin address from a passphrase. The passphrase is hashed and then used as the secret bytes to construct the CBitcoinSecret. """ if not isinstance(passphrase, bytes): passphrase = bytes(passphrase, "utf-8") passphrasehash = hashlib.sha256(passphrase).digest() private_key = CBitcoinSecret.from_secret_bytes(passphrasehash, compressed=compressed) address = P2PKHBitcoinAddress.from_pubkey(private_key.pub) if as_str: return str(address) else: return address
def sign_setup_tx(tx_hex, redeem_script, ecdsa): tx = CTransaction.deserialize(binascii.unhexlify(tx_hex)) sighash = SignatureHash(redeem_script["bin"], tx, 0, SIGHASH_ALL) print(b"Signing = " + sighash) print(ecdsa.get_public_key()) seckey = CBitcoinSecret.from_secret_bytes(ecdsa.get_private_key("bin"), compressed=True) sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) print(b"Pub key = " + ecdsa.get_public_key("bin")) print(b"Sig = " + sig) print() return sig
sys.stderr.write('Sorry, Python 3.x required by this example.\n') sys.exit(1) import hashlib from bitcoin import SelectParams from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160 from bitcoin.core.script import CScript, OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret SelectParams('mainnet') # Create the (in)famous correct brainwallet secret key. h = hashlib.sha256(b'correct horse battery staple').digest() seckey = CBitcoinSecret.from_secret_bytes(h) # Create a redeemScript. Similar to a scriptPubKey the redeemScript must be # satisfied for the funds to be spent. txin_redeemScript = CScript([seckey.pub, OP_CHECKSIG]) print(b2x(txin_redeemScript)) # Create the magic P2SH scriptPubKey format from that redeemScript. You should # look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to # understand what's happening, as well as read BIP16: # https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() # Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it. # You'll need to send some funds to it to create a txout to spend. txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey)
def load_private_key(self, filename): real_path = self.get_path(filename) self.assert_file_exists(real_path) with open(real_path, 'r') as private_key_file: return CBitcoinSecret.from_secret_bytes(x(private_key_file.read()), True)
def generate_secret_key(): random_bytes = open("/dev/random", "rb").read(100) secret_bytes = sha256(random_bytes).digest() return CBitcoinSecret.from_secret_bytes(secret_bytes)
def __setstate__(self, state): self.__dict__.update(state) # convert text secrets back to CBitcoinSecrets for pubkey, seckey in self.keypairs.items(): self.keypairs[pubkey] = CBitcoinSecret.from_secret_bytes(seckey)
redeemer.mutate_spend(tx, n) unsigned_tx = CTransaction.from_tx(tx) for n,(_,_,redeemer) in enumerate(self.prevouts): txin = CMutableTxIn.from_txin(tx.vin[n]) txin.scriptSig = redeemer.sign_spend(unsigned_tx, n) tx.vin[n] = CTxIn.from_txin(txin) print(b2x(tx.serialize())) bitcoin.SelectParams('regtest') # parameters spend = CBitcoinSecret("cVFfsB2h1KHgPEWtpXrnZ5qjk18xw2o2fuxCTaf7BN2Z5PSvhq4M") refund = CBitcoinSecret("cRKSxo1yJKP1RwaHULWaumNYiyXiQu2tRGdTmUxzP1s4YeSM4ks1") sec = b'A pair of boiled eggs for lunch?' sechash = Hash160(sec) rev = x('4a120469b397556363c4e47f45d8f81b381f721af89baba372425f820ae7077c') revhash = Hash160(rev) # the two scripts: paying me or paying them (or refunding to me) htlcA = HTLCScript(spend.pub, refund.pub, sechash, 230, revhash, 'pay', 10) htlcB = HTLCScript(spend.pub, refund.pub, sechash, 230, revhash, 'refund', 10) # the six ways of resolving the scripts: spending, refunding or revoking, # for both types of script htlcAs = HTLCScript(spend.pub, refund.pub, sechash, 230,
def test_send_script_spend(self): """ Run more in-depth execution checks on the script generated for the send transaction """ sender_private_key = CBitcoinSecret.from_secret_bytes(x('4f65da9b656de4036076911707d2b2dbf065689245b8674faa8790e36d7e5850')) sender_public_key = sender_private_key.pub recipient_private_key = CBitcoinSecret.from_secret_bytes(x('cfe8e33672f7045f020210f3c7afbca660e053e4c9415c542ff185e97b175cf0')) recipient_public_key = recipient_private_key.pub secret = x('88d6e51f777b0b8dc0f429da9f372fbc') secret_hash = Hash(secret) send_to_key = CBitcoinSecret.from_secret_bytes(x('15a249b4c09286b877d4708191f1ee8de09903bae034dd9dc8e3286451fa1c80')) send_to_address = P2PKHBitcoinAddress.from_pubkey(send_to_key.pub) random_tx_id = x('8390b4c8198198c6447da1a6fad498209436a785459936b95a1e3b63618c1d8a') value = 10 * COIN send_tx_script_pub_key = build_send_out_script(sender_public_key, recipient_public_key, secret_hash) send_txins = [CMutableTxIn(COutPoint(random_tx_id, 0))] send_txouts = [CMutableTxOut(value, send_tx_script_pub_key)] send_tx = CMutableTransaction(send_txins, send_txouts) # Test the standard spend transaction txins = [CMutableTxIn(COutPoint(Hash(send_tx.serialize()), 0))] txouts = [CMutableTxOut(value, send_to_address.to_scriptPubKey())] recv_tx = CMutableTransaction(txins, txouts) sighash = SignatureHash(send_tx_script_pub_key, recv_tx, 0, SIGHASH_ALL) recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL]) recv_tx.vin[0].scriptSig = CScript([secret, 0, recipient_sig, recipient_public_key]) VerifyScript(recv_tx.vin[0].scriptSig, send_tx.vout[0].scriptPubKey, recv_tx, 0, (SCRIPT_VERIFY_P2SH,)) # Test a refund transaction refund_tx = CMutableTransaction(txins, txouts) sighash = SignatureHash(send_tx_script_pub_key, refund_tx, 0, SIGHASH_ALL) sender_sig = sender_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL]) recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL]) refund_tx.vin[0].scriptSig = CScript([sender_sig, sender_public_key, 1, recipient_sig, recipient_public_key]) VerifyScript(refund_tx.vin[0].scriptSig, send_tx_script_pub_key, refund_tx, 0, (SCRIPT_VERIFY_P2SH,)) # Test invalid transactions are rejected invalid_tx = CMutableTransaction(txins, txouts) sighash = SignatureHash(send_tx_script_pub_key, invalid_tx, 0, SIGHASH_ALL) sender_sig = sender_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL]) recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL]) invalid_tx.vin[0].scriptSig = CScript([]) with self.assertRaises(MissingOpArgumentsError): VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,)) invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 0]) with self.assertRaises(VerifyOpFailedError): VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,)) invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 1]) with self.assertRaises(VerifyOpFailedError): VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,)) invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 1, recipient_sig, recipient_public_key]) with self.assertRaises(VerifyOpFailedError): VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,)) invalid_tx.vin[0].scriptSig = CScript([sender_sig, sender_public_key, 1, sender_sig, sender_public_key]) with self.assertRaises(VerifyOpFailedError): VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))