示例#1
0
def test_encode_serialize() -> None:
    # from creator example
    psbt_str = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAAAAAA="
    psbt = Psbt.b64decode(psbt_str)
    assert psbt.b64encode() == psbt_str

    psbt_serialized = bytes.fromhex(
        "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000000000000000000"
    )
    assert psbt == Psbt.parse(psbt_serialized)
    assert psbt_serialized == psbt.serialize()
示例#2
0
def test_psbt() -> None:
    prev_out = OutPoint(
        "9dcfdb5836ecfe146bdaa896605ba21222f83cd014dd47adde14fab2aba7de9b", 1)
    script_sig = b""
    sequence = 0xFFFFFFFF
    tx_in = TxIn(prev_out, script_sig, sequence)

    tx_out1 = TxOut(2500000, "a914f987c321394968be164053d352fc49763b2be55c87")
    tx_out2 = TxOut(
        6381891,
        "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d")
    version = 1
    lock_time = 0
    tx = Tx(version, lock_time, [tx_in], [tx_out1, tx_out2])
    psbt = Psbt.from_tx(tx)
    assert psbt == Psbt.parse(psbt.serialize())
    assert psbt == Psbt.from_dict(psbt.to_dict())
示例#3
0
def test_exceptions() -> None:
    # from creator example
    psbt_str = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAAAAAA="

    psbt = Psbt.b64decode(psbt_str)
    psbt.outputs[0].redeem_script = "bad script"  # type: ignore
    with pytest.raises(TypeError):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.inputs[0].witness_script = "bad script"  # type: ignore
    with pytest.raises(TypeError):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.outputs[0].unknown = {"bad key": b""}  # type: ignore
    with pytest.raises(TypeError):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.outputs[0].unknown = {b"deadbeef": "bad value"}  # type: ignore
    with pytest.raises(TypeError):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.inputs[0].sig_hash_type = 101
    with pytest.raises(BTClibValueError, match="invalid sign_hash type: "):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.inputs[0].final_script_sig = "bad script"  # type: ignore
    with pytest.raises(TypeError):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    _, Q = dsa.gen_keys()
    pub_key = sec_point.bytes_from_point(Q)
    r = s = int.from_bytes(bytes.fromhex("FF" * 32),
                           byteorder="big",
                           signed=False)
    sig_bytes = der.Sig(r, s,
                        check_validity=False).serialize(check_validity=False)
    psbt.inputs[0].partial_sigs = {pub_key: sig_bytes}
    with pytest.raises(BTClibValueError, match="invalid partial signature: "):
        psbt.serialize()

    pub_key = bytes.fromhex("02" + 31 * "00" + "07")
    psbt.inputs[0].partial_sigs = {pub_key: sig_bytes}
    with pytest.raises(BTClibValueError,
                       match="invalid partial signature pub_key: "):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    err_msg = "invalid version: "
    psbt.version = -1
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.serialize()
    psbt.version = 0xFFFFFFFF + 1
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.serialize()
    psbt.version = 1
    # TODO: add to test vectors
    with pytest.raises(BTClibValueError, match="invalid non-zero version: "):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt_bin = psbt.serialize()
    psbt_bin = psbt_bin.replace(PSBT_SEPARATOR, PSBT_DELIMITER)
    # TODO: add to test vectors
    with pytest.raises(BTClibValueError,
                       match="malformed psbt: missing separator"):
        Psbt.parse(psbt_bin)

    psbt = Psbt.b64decode(psbt_str)
    psbt.inputs.pop()
    err_msg = "mismatched number of psb.tx.vin and psb.inputs: "
    # TODO: add to test vectors
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.tx.vin[0].script_witness = Witness([b""])
    err_msg = "non empty script_sig or witness"
    # TODO: add to test vectors
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.serialize()

    psbt = Psbt.b64decode(psbt_str)
    psbt.outputs.pop()
    err_msg = "mismatched number of psb.tx.vout and psbt.outputs: "
    # TODO: add to test vectors
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.serialize()

    psbt_str = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA"
    psbt = Psbt.b64decode(psbt_str)
    psbt.tx.vin[0].prev_out.tx_id, psbt.tx.vin[1].prev_out.tx_id = (
        psbt.tx.vin[1].prev_out.tx_id,
        psbt.tx.vin[0].prev_out.tx_id,
    )
    err_msg = "mismatched non-witness utxo / outpoint tx_id"
    with pytest.raises(BTClibValueError, match=err_msg):
        psbt.assert_valid()