Exemplo n.º 1
0
    def create_payment_tx(self, deposit_tx, redeem_script, amount, fee):
        # Find P2SH output index in deposit_tx
        deposit_utxo_index = deposit_tx.output_index_for_address(redeem_script.hash160())

        # Look up deposit amount
        deposit_amount = deposit_tx.outputs[deposit_utxo_index].value - fee

        # Build unsigned payment transaction
        inputs = [bitcoin.TransactionInput(deposit_tx.hash, deposit_utxo_index, bitcoin.Script(), 0xffffffff)]
        outputs = [
            bitcoin.TransactionOutput(
                amount, bitcoin.Script.build_p2pkh(redeem_script.merchant_public_key.hash160())),
            bitcoin.TransactionOutput(
                deposit_amount - amount, bitcoin.Script.build_p2pkh(redeem_script.customer_public_key.hash160()))]
        payment_tx = bitcoin.Transaction(bitcoin.Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, 0x0)

        # Sign payment transaction
        public_key = redeem_script.customer_public_key
        private_key = self._wallet.get_private_for_public(public_key)
        assert private_key, "Redeem script public key not found in wallet."
        sig = payment_tx.get_signature_for_input(0, bitcoin.Transaction.SIG_HASH_ALL, private_key, redeem_script)[0]

        # Update input script sig
        script_sig = bitcoin.Script([
            sig.to_der() + bitcoin.utils.pack_compact_int(bitcoin.Transaction.SIG_HASH_ALL),
            "OP_1", bytes(redeem_script)])
        payment_tx.inputs[0].script = script_sig

        return payment_tx
Exemplo n.º 2
0
def test_redeem_script():
    # Redeem script parmaeters
    merchant_public_key = mock.MockPaymentChannelServer.PRIVATE_KEY.public_key
    customer_public_key = mock.MockTwo1Wallet.PRIVATE_KEY.public_key
    expiration_time = 1450223410
    serialized_redeem_script = "63210316f5d704b828c3252432886a843649730e08ae01bbbd5c6bde63756d7f54f961ad670432a77056b175682103ee071c95cb772e57a6d8f4f987e9c61b857e63d9f3b5be7a84bdba0b5847099dac"  # nopep8

    # Test construction
    redeem_script = statemachine.PaymentChannelRedeemScript(
        merchant_public_key, customer_public_key, expiration_time)

    assert redeem_script.to_hex() == serialized_redeem_script
    assert redeem_script.merchant_public_key.compressed_bytes == merchant_public_key.compressed_bytes
    assert redeem_script.customer_public_key.compressed_bytes == customer_public_key.compressed_bytes
    assert redeem_script.expiration_time == expiration_time

    # Test deserialization
    redeem_script = statemachine.PaymentChannelRedeemScript.from_bytes(
        codecs.decode(serialized_redeem_script, "hex_codec"))

    assert redeem_script.to_hex() == serialized_redeem_script
    assert redeem_script.merchant_public_key.compressed_bytes == merchant_public_key.compressed_bytes
    assert redeem_script.customer_public_key.compressed_bytes == customer_public_key.compressed_bytes
    assert redeem_script.expiration_time == expiration_time

    # Test invalid deserialization
    with pytest.raises(ValueError):
        # Invalid length
        scr = bitcoin.Script(["OP_NOP"])
        statemachine.PaymentChannelRedeemScript.from_bytes(bytes(scr))
    with pytest.raises(ValueError):
        # Invalid opcode
        scr = bitcoin.Script.from_hex(serialized_redeem_script)
        scr[-1] = "OP_NOP"
        statemachine.PaymentChannelRedeemScript.from_bytes(bytes(scr))
Exemplo n.º 3
0
    def build_signed_transaction(self,
                                 addresses_and_amounts,
                                 use_unconfirmed=False,
                                 insert_into_cache=False,
                                 fees=None,
                                 expiration=0):
        address = list(addresses_and_amounts.keys())[0]
        amount = addresses_and_amounts[address]

        inputs = [
            bitcoin.TransactionInput(self.MOCK_UTXO, self.MOCK_UTXO_INDEX,
                                     bitcoin.Script(), 0xffffffff)
        ]
        outputs = [
            bitcoin.TransactionOutput(
                amount,
                bitcoin.Script.build_p2sh(
                    utils.address_to_key_hash(address)[1]))
        ]
        tx = bitcoin.Transaction(
            bitcoin.Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs,
            0x0)
        tx.sign_input(0, bitcoin.Transaction.SIG_HASH_ALL, self.PRIVATE_KEY,
                      self.MOCK_UTXO_SCRIPT_PUBKEY)

        return [tx]
Exemplo n.º 4
0
    def create_unsigned_payment_tx(self, deposit_tx, redeem_script, amount,
                                   fee):
        # Find P2SH output index in deposit_tx
        deposit_utxo_index = deposit_tx.output_index_for_address(
            redeem_script.hash160())

        # Look up deposit amount
        deposit_amount = deposit_tx.outputs[deposit_utxo_index].value - fee

        # Build unsigned payment transaction
        inputs = [
            bitcoin.TransactionInput(deposit_tx.hash, deposit_utxo_index,
                                     bitcoin.Script(), 0xffffffff),
        ]

        outputs = [
            bitcoin.TransactionOutput(
                amount,
                bitcoin.Script.build_p2pkh(
                    redeem_script.merchant_public_key.hash160())),
            bitcoin.TransactionOutput(
                deposit_amount - amount,
                bitcoin.Script.build_p2pkh(
                    redeem_script.customer_public_key.hash160())),
        ]

        payment_tx = bitcoin.Transaction(
            bitcoin.Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs,
            0x0)

        return payment_tx
Exemplo n.º 5
0
    def create_refund_tx(self, deposit_tx, redeem_script, expiration_time,
                         fee):
        # Find P2SH output index in deposit_tx
        deposit_utxo_index = deposit_tx.output_index_for_address(
            redeem_script.hash160())

        # Look up deposit amount
        deposit_amount = deposit_tx.outputs[deposit_utxo_index].value - fee

        # Build unsigned refund transaction
        inputs = [
            bitcoin.TransactionInput(deposit_tx.hash, deposit_utxo_index,
                                     bitcoin.Script(), 0xfffffffe),
        ]

        outputs = [
            bitcoin.TransactionOutput(
                deposit_amount,
                bitcoin.Script.build_p2pkh(
                    redeem_script.customer_public_key.hash160())),
        ]

        refund_tx = bitcoin.Transaction(
            bitcoin.Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs,
            expiration_time)

        # Sign refund transaction
        public_key = redeem_script.customer_public_key
        private_key = self._wallet.get_private_for_public(public_key)
        assert private_key, "Redeem script public key not found in wallet."
        sig = refund_tx.get_signature_for_input(
            0, bitcoin.Transaction.SIG_HASH_ALL, private_key, redeem_script)[0]

        # Update input script sig
        hash_type = bitcoin.utils.pack_compact_int(
            bitcoin.Transaction.SIG_HASH_ALL)
        script_sig = bitcoin.Script(
            [sig.to_der() + hash_type, b"\x00",
             bytes(redeem_script)])
        refund_tx.inputs[0].script = script_sig

        return refund_tx
Exemplo n.º 6
0
def _build_void_transaction(price=None, address=None):
    price = price or 1000
    address = address or '19tAqnusJv2XoyxsC1UzuBTdG9dCAgafEX'
    _, hash160 = bitcoin.utils.address_to_key_hash(address)
    h = codecs.encode(b'test hash for a fake payment txn', 'hex_codec').decode()
    outpoint = bitcoin.Hash(h)
    inputs = [bitcoin.TransactionInput(
        outpoint=outpoint, outpoint_index=0, script=bitcoin.Script(), sequence_num=0xffffffff
    )]
    outputs = [bitcoin.TransactionOutput(value=price, script=bitcoin.Script.build_p2pkh(hash160))]
    txn = bitcoin.Transaction(
        version=bitcoin.Transaction.DEFAULT_TRANSACTION_VERSION, inputs=inputs, outputs=outputs, lock_time=0
    )
    return txn
Exemplo n.º 7
0
    def create_payment_tx(self, deposit_tx, redeem_script, amount, fee):
        payment_tx = self.create_unsigned_payment_tx(deposit_tx, redeem_script,
                                                     amount, fee)

        # Sign payment transaction
        public_key = redeem_script.customer_public_key
        private_key = self._wallet.get_private_for_public(public_key)
        assert private_key, "Redeem script public key not found in wallet."
        sig = payment_tx.get_signature_for_input(
            0, bitcoin.Transaction.SIG_HASH_ALL, private_key, redeem_script)[0]

        # Update input script sig
        hash_type = bitcoin.utils.pack_compact_int(
            bitcoin.Transaction.SIG_HASH_ALL)
        script_sig = bitcoin.Script(
            [sig.to_der() + hash_type, "OP_1",
             bytes(redeem_script)])
        payment_tx.inputs[0].script = script_sig

        return payment_tx