コード例 #1
0
ファイル: funding.py プロジェクト: rustyrussell/lnprototest
    def sign_our_inputs(self) -> None:
        assert self.tx is not None
        for idx, _in in enumerate(self.inputs):
            privkey = _in['privkey']

            if privkey and 'sig' not in _in:
                print('signing our input for tx', self.tx.serialize().hex())
                inkey = privkey_expand(privkey)
                inkey_pub = coincurve.PublicKey.from_secret(inkey.secret)

                # Really horrid hack to produce a signature for the
                # multisig utxo in tests/helpers.py
                if privkey == '38204720bc4f9647fd58c6d0a4bd3a6dd2be16d8e4273c4d1bdd5774e8c51eaf':
                    redeemscript = bytes.fromhex('51210253cdf835e328346a4f19de099cf3d42d4a7041e073cd4057a1c4fd7cdbb1228f2103ae903722f21f85e651b8f9b18fc854084fb90eeb76452bdcfd0cb43a16a382a221036c264d68a9727afdc75949f7d7fa71910ae9ae8001a1fbffa6f7ce000976597c21036429fa8a4ef0b2b1d5cb553e34eeb90a32ab19fae1f0024f332ab4f74283a7282103d4232f19ea85051e7b76bf5f01d03e17eea8751463dee36d71413a739de1a92755ae')
                else:
                    address = P2WPKHBitcoinAddress.from_scriptPubKey(CScript([script.OP_0, Hash160(inkey_pub.format())]))
                    redeemscript = address.to_redeemScript()

                sighash = script.SignatureHash(redeemscript,
                                               self.tx, idx, script.SIGHASH_ALL,
                                               amount=_in['sats'],
                                               sigversion=script.SIGVERSION_WITNESS_V0)
                sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL])

                if privkey == '38204720bc4f9647fd58c6d0a4bd3a6dd2be16d8e4273c4d1bdd5774e8c51eaf':
                    _in['sig'] = CTxInWitness(CScriptWitness([bytes([]), sig, redeemscript]))
                else:
                    _in['sig'] = CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))
コード例 #2
0
    def add_witnesses(self,
                      witness_stack) -> str:
        wits = []
        for idx, _in in enumerate(self.inputs):
            privkey = _in['privkey']
            serial_id = _in['serial_id']

            if privkey:
                inkey = privkey_expand(privkey)
                inkey_pub = coincurve.PublicKey.from_secret(inkey.secret)

                address = P2WPKHBitcoinAddress.from_scriptPubKey(CScript([script.OP_0, Hash160(inkey_pub.format())]))

                sighash = script.SignatureHash(address.to_redeemScript(),
                                               self.tx, idx, script.SIGHASH_ALL,
                                               amount=_in['sats'],
                                               sigversion=script.SIGVERSION_WITNESS_V0)
                sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL])

                wits.append(CTxInWitness(CScriptWitness([sig, inkey_pub.format()])))
                continue

            # Every input from the witness stack will be the accepter's
            # which is always an odd serial
            assert(serial_id % 2 == 1)
            elems = witness_stack.pop(0)['witness_element']

            stack = []
            for elem in elems:
                stack.append(bytes.fromhex(elem['witness']))

            wits.append(CTxInWitness(CScriptWitness(stack)))

        self.tx.wit = CTxWitness(wits)
        return self.tx.serialize().hex()
コード例 #3
0
ファイル: bitcoin.py プロジェクト: thorchain/heimdall
    def get_address_from_pubkey(cls, pubkey):
        """
        Get bitcoin address for a specific hrp (human readable part)
        bech32 encoded from a public key(secp256k1).

        :param string pubkey: public key
        :returns: string bech32 encoded address
        """
        script_pubkey = CScript([OP_0, Hash160(pubkey)])
        return str(P2WPKHBitcoinAddress.from_scriptPubKey(script_pubkey))
コード例 #4
0
ファイル: funding.py プロジェクト: cdecker/lnprototest
    def from_utxo(txid_in: str,
                  tx_index_in: int,
                  sats: int,
                  privkey: str,
                  fee: int,
                  local_node_privkey: str,
                  local_funding_privkey: str,
                  remote_node_privkey: str,
                  remote_funding_privkey: str,
                  chain_hash: str = regtest_hash) -> Tuple['Funding', str]:
        """Make a funding transaction by spending this utxo using privkey: return Funding, tx."""

        # Create dummy one to start: we will fill in txid at the end.
        funding = Funding('', 0, sats - fee, local_node_privkey,
                          local_funding_privkey, remote_node_privkey,
                          remote_funding_privkey, chain_hash)

        # input private key.
        inkey = privkey_expand(privkey)
        inkey_pub = coincurve.PublicKey.from_secret(inkey.secret)

        # use RBF'able input (requirement for dual-funded things)
        txin = CTxIn(COutPoint(bytes.fromhex(txid_in), tx_index_in),
                     nSequence=0xFFFFFFFD)
        txout = CTxOut(
            sats - fee,
            CScript([script.OP_0,
                     sha256(funding.redeemscript()).digest()]))
        tx = CMutableTransaction([txin], [txout],
                                 nVersion=2,
                                 nLockTime=funding.locktime)

        # now fill in funding txid.
        funding.txid = tx.GetTxid().hex()
        funding.tx = tx

        # while we're here, sign the transaction.
        address = P2WPKHBitcoinAddress.from_scriptPubKey(
            CScript([script.OP_0, Hash160(inkey_pub.format())]))

        sighash = script.SignatureHash(address.to_redeemScript(),
                                       tx,
                                       0,
                                       script.SIGHASH_ALL,
                                       amount=sats,
                                       sigversion=script.SIGVERSION_WITNESS_V0)
        sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL])

        tx.wit = CTxWitness(
            [CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))])
        return funding, tx.serialize().hex()
コード例 #5
0
    def do_mesh_sendtoaddress(self, rem) :
        """ 
        Create a signed transaction and broadcast it over the connected mesh device. The transaction 
        spends some amount of satoshis to the specified address from the local bitcoind wallet and selected network. 

        Usage: mesh_sendtoaddress BECH32 ADDRESS SATS NETWORK(m|t)

        eg. txTenna> mesh_sendtoaddress 2N4BtwKZBU3kXkWT7ZBEcQLQ451AuDWiau2 13371337 t
        """
        try:

            proxy = bitcoin.rpc.Proxy()
            (addr, sats, network) = rem.split()

            # Create the txout. This time we create the scriptPubKey from a Bitcoin
            # address.
            p2wpkh_addr = P2WPKHBitcoinAddress(addr)
            txout = CMutableTxOut(sats, p2wpkh_addr.to_scriptPubKey())

            # Create the unsigned transaction.
            unfunded_transaction = CMutableTransaction([], [txout])
            funded_transaction = proxy.fundrawtransaction(unfunded_transaction)
            signed_transaction = proxy.signrawtransaction(funded_transaction["tx"])
            txhex = b2x(signed_transaction["tx"].serialize())
            txid = b2lx(signed_transaction["tx"].GetTxid())
            print("sendtoaddress_mesh (tx, txid, network): " + txhex + ", " + txid, ", " + network)

            # broadcast over mesh
            self.do_mesh_broadcast_rawtx( txhex + " " + txid + " " + network)

        except Exception: # pylint: disable=broad-except
            traceback.print_exc()

        try :
            # lock UTXOs used to fund the tx if broadcast successful
            vin_outpoints = set()
            for txin in funded_transaction["tx"].vin:
                vin_outpoints.add(txin.prevout)
            ## json_outpoints = [{'txid':b2lx(outpoint.hash), 'vout':outpoint.n}
            ##              for outpoint in vin_outpoints]
            ## print(str(json_outpoints))
            proxy.lockunspent(False, vin_outpoints)
            
        except Exception: # pylint: disable=broad-except
            ## TODO: figure out why this is happening
            print("RPC timeout after calling lockunspent")
コード例 #6
0
ファイル: __init__.py プロジェクト: csknk/revault-demo
def add_input(bitcoind, tx, fees):
    """Add another input to the transaction to bump the feerate."""
    # Don't be dust!
    if fees < 294:
        fees = 294

    # Create the first stage transaction
    new_prevout_addr = P2WPKHBitcoinAddress(bitcoind.getnewaddress())
    txid = bitcoind.sendtoaddress(str(new_prevout_addr), fees / COIN)
    out_index = get_output_index(bitcoind.getrawtransaction(txid, decode=True),
                                 fees)
    # Then gather the private key to unlock its output
    privkey = CKey(wif_decode(bitcoind.dumpprivkey(str(new_prevout_addr))))
    # Add the fetched coin as a new input.
    tx.vin.append(CTxIn(COutPoint(lx(txid), out_index)))
    # We only do this once, sign it with ALL
    tx_hash = SignatureHash(new_prevout_addr.to_redeemScript(), tx, 1,
                            SIGHASH_ALL, fees, SIGVERSION_WITNESS_V0)
    sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL])
    tx.wit.vtxinwit.append(CTxInWitness(CScriptWitness([sig, privkey.pub])))

    return tx
コード例 #7
0
ファイル: signing.py プロジェクト: kanzure/python-vaults
def parameterize_witness_template_by_signing(some_input, parameters):
    """
    Take a specific witness template, a bag of parameters, and a
    transaction, and then produce a parameterized witness (including all
    necessary valid signatures).

    Make a sighash for the bitcoin transaction.
    """
    p2wsh_redeem_script = some_input.utxo.p2wsh_redeem_script
    tx = some_input.transaction.bitcoin_transaction
    txin_index = some_input.transaction.inputs.index(some_input)

    computed_witness = []

    selection = some_input.witness_template_selection
    script_template = some_input.utxo.script_template
    witness_template = script_template.witness_templates[selection]

    amount = some_input.utxo.amount

    # TODO: Might have to update the witness_templates values to give a
    # correct ordering for which signature should be supplied first.
    # (already did this? Re-check for VerifyScript errors)

    witness_tmp = witness_template.split(" ")
    for (idx, section) in enumerate(witness_tmp):
        if section[0] == "<" and section[-1] == ">":
            section = section[1:-1]
            if section == "user_key":
                computed_witness.append(parameters["user_key"]["public_key"])
                continue
            elif section not in script_template.witness_template_map.keys():
                raise VaultException(
                    "Missing key mapping for {}".format(section))

            key_param_name = script_template.witness_template_map[section]
            private_key = parameters[key_param_name]["private_key"]

            if script_template != UserScriptTemplate:
                # This is a P2WSH transaction.
                redeem_script = p2wsh_redeem_script
            elif script_template == UserScriptTemplate:
                # This is a P2WPKH transaction.
                user_address = P2WPKHBitcoinAddress.from_scriptPubKey(
                    CScript(
                        [OP_0,
                         Hash160(parameters["user_key"]["public_key"])]))
                redeem_script = user_address.to_redeemScript()
                # P2WPKH redeemScript: OP_DUP OP_HASH160 ....

            sighash = SignatureHash(redeem_script,
                                    tx,
                                    txin_index,
                                    SIGHASH_ALL,
                                    amount=amount,
                                    sigversion=SIGVERSION_WITNESS_V0)
            signature = private_key.sign(sighash) + bytes([SIGHASH_ALL])
            computed_witness.append(signature)

        else:
            # dunno what to do with this, probably just pass it on really..
            computed_witness.append(section)

    if script_template == UserScriptTemplate:
        # P2WPKH
        # Witness already completed. No redeem_script to append.
        pass
    else:
        # P2WSH
        # Append the p2wsh redeem script.
        computed_witness.append(p2wsh_redeem_script)

    computed_witness = CScript(computed_witness)
    some_input.witness = computed_witness
    return computed_witness
コード例 #8
0
def initialize(private_key=None):
    """
    Setup and initialize a new vault in the current working directory. This is
    the primary entrypoint for the prototype.
    """

    check_vaultfile_existence()
    check_private_key_is_conformant(private_key)

    #amount = random.randrange(0, 100 * COIN)
    #amount = 7084449357
    amount = 2 * COIN

    # TODO: A more sophisticated private key system is required, for any real
    # production use.
    some_private_keys = [CBitcoinSecret(private_key)] * 6

    parameter_names = [
        "user_key",
        "ephemeral_key_1",
        "ephemeral_key_2",
        "cold_key1",
        "cold_key2",
        "hot_wallet_key",
    ]

    parameters = {
        "num_shards":
        5,
        "enable_burn_transactions":
        True,
        "enable_graphviz":
        True,
        "enable_graphviz_popup":
        False,
        "amount":
        amount,
        "unspendable_key_1":
        CPubKey(
            x("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
              )),
    }

    for some_name in parameter_names:
        private_key = some_private_keys.pop()
        public_key = private_key.pub
        parameters[some_name] = {
            "private_key": private_key,
            "public_key": public_key
        }

    parameters["user_key_hash160"] = b2x(
        Hash160(parameters["user_key"]["public_key"]))

    # consistency check against required parameters
    required_parameters = ScriptTemplate.get_required_parameters()

    missing_parameters = False
    for required_parameter in required_parameters:
        if required_parameter not in parameters.keys():
            logger.error(f"Missing parameter: {required_parameter}")
            missing_parameters = True
    if missing_parameters:
        logger.error("Missing parameters!")
        sys.exit(1)

    # connect to bitcoind (ideally, regtest)
    connection = get_bitcoin_rpc_connection()

    # setup the user private key (for P2WPKH)
    connection._call("importprivkey",
                     str(parameters["user_key"]["private_key"]), "user")

    # Mine some coins into the "user_key" P2WPKH address
    #user_address = "bcrt1qrnwea7zc93l5wh77y832wzg3cllmcquqeal7f5"
    # parsed_address = P2WPKHBitcoinAddress(user_address)
    user_address = P2WPKHBitcoinAddress.from_scriptPubKey(
        CScript([OP_0, Hash160(parameters["user_key"]["public_key"])]))
    blocks = 110
    if connection._call("getblockchaininfo")["blocks"] < blocks:
        try:
            connection._call("sendtoaddress", user_address, 50)
        except Exception:
            pass
        connection._call("generatetoaddress", blocks, str(user_address))

    # Now find an unspent UTXO.
    unspent = connection._call("listunspent", 6, 9999, [str(user_address)],
                               True, {"minimumAmount": amount / COIN})
    if len(unspent) == 0:
        raise VaultException(
            "can't find a good UTXO for amount {}".format(amount))

    # pick the first UTXO
    utxo_details = unspent[0]
    txid = utxo_details["txid"]

    # have to consume the whole UTXO
    amount = int(utxo_details["amount"] * COIN)

    initial_tx_txid = lx(utxo_details["txid"])
    initial_tx = InitialTransaction(txid=initial_tx_txid)

    segwit_utxo = PlannedUTXO(
        name="segwit input coin",
        transaction=initial_tx,
        script_template=UserScriptTemplate,
        amount=amount,
    )
    segwit_utxo._vout_override = utxo_details["vout"]
    initial_tx.output_utxos = [segwit_utxo]  # for establishing vout

    # ===============
    # Here's where the magic happens.
    vault_initial_utxo = setup_vault(segwit_utxo, parameters)
    # ===============

    # Check that the tree is conforming to applicable rules.
    safety_check(segwit_utxo.transaction)

    # To test that the sharded UTXOs have the right amounts, do the following:
    # assert (second_utxo_amount * 99) + first_utxo_amount == amount

    # Display all UTXOs and transactions-- render the tree of possible
    # transactions. Mostly helpful for debugging purposes.
    render_planned_tree_to_text_file(segwit_utxo,
                                     filename=TEXT_RENDERING_FILENAME)

    # stats
    logger.info("*** Stats and numbers")
    logger.info(
        f"{PlannedUTXO.__counter__} UTXOs, {PlannedTransaction.__counter__} transactions"
    )

    sign_transaction_tree(segwit_utxo, parameters)

    save(segwit_utxo)

    # TODO: Delete the ephemeral keys.

    # (graph generation can wait until after key deletion)
    if parameters["enable_graphviz"] == True:
        generate_graphviz(segwit_utxo, parameters, output_filename="output.gv")

    # Create another planned transaction tree this time using
    # OP_CHECKTEMPLATEVERIFY from bip119. This can be performed after key
    # deletion because OP_CTV standard template hashes are not based on keys
    # and signatures.
    make_planned_transaction_tree_using_bip119_OP_CHECKTEMPLATEVERIFY(
        initial_tx, parameters=parameters)
    save(segwit_utxo, filename="transaction-store.ctv.json")

    # A vault has been established. Write the vaultfile.
    make_vaultfile()
コード例 #9
0
ファイル: spend-p2wpkh.py プロジェクト: weicuivt/pqBitcoinTX
SelectParams("regtest")
connection = Proxy()

if connection._call("getblockchaininfo")["chain"] != "regtest":
    sys.stderr.write("This example is intended for regtest only.\n")
    sys.exit(1)

# Create the (in)famous correct brainwallet secret key.
h = hashlib.sha256(b'correct horse battery staple').digest()
seckey = CBitcoinSecret.from_secret_bytes(h)

# Create an address from that private key.
public_key = seckey.pub
scriptPubKey = CScript([OP_0, Hash160(public_key)])
address = P2WPKHBitcoinAddress.from_scriptPubKey(scriptPubKey)

# Give the private key to bitcoind (for ismine, listunspent, etc).
connection._call("importprivkey", str(seckey))

# Check if there's any funds available.
unspentness = lambda: connection._call("listunspent", 6, 9999, [str(address)],
                                       True, {"minimumAmount": 1.0})
unspents = unspentness()
while len(unspents) == 0:
    # mine some funds into the address
    connection._call("generatetoaddress", 110, str(address))
    unspents = unspentness()

# Choose the first UTXO, let's spend it!
unspent_utxo_details = unspents[0]