def test_op_else():
    s = Script("OP_1 OP_IF OP_2 OP_3 OP_ELSE OP_15 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 3
    assert list(si.stack) == [2, 3, 4]
    assert len(si._if_else_stack) == 0

    s = Script("OP_0 OP_IF OP_2 OP_3 OP_ELSE OP_15 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 2
    assert list(si.stack) == [15, 4]
    assert len(si._if_else_stack) == 0

    s = Script(
        "OP_0 OP_IF OP_2 OP_3 OP_ELSE OP_1 OP_2 OP_SUB OP_IF OP_3 OP_ENDIF OP_ENDIF OP_4"
    )

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 2
    assert list(si.stack) == [3, 4]
    assert len(si._if_else_stack) == 0
def test_op_checkmultisig():
    txn = Transaction.from_hex(
        "01000000010506344de69d47e432eb0174500d6e188a9e63c1e84a9e8796ec98c99b7559f701000000fdfd00004730440220695a28c42daa23c13e192e36a20d03a2a79994e0fe1c3c6b612d0ae23743064602200ca19003e7c1ce0cecb0bbfba9a825fc3b83cf54e4c3261cd15f080d24a8a5b901483045022100aa9096ce71995c24545694f20ab0482099a98c99b799c706c333c521e51db66002206578f023fa46f4a863a6fa7f18b95eebd1a91fcdf6ce714e8795d902bd6b682b014c69522102b66fcb1064d827094685264aaa90d0126861688932eafbd1d1a4ba149de3308b21025cab5e31095551582630f168280a38eb3a62b0b3e230b20f8807fc5463ccca3c21021098babedb3408e9ac2984adcf2a8e4c48e56a785065893f76d0fa0ff507f01053aeffffffff01c8af0000000000001976a91458b7a60f11a904feef35a639b6048de8dd4d9f1c88ac00000000"
    )  # nopep8

    sig_script = txn.inputs[0].script
    redeem_script = Script(sig_script.ast[-1][-1])
    script_pub_key = Script.build_p2sh(redeem_script.hash160())

    si = ScriptInterpreter(txn=txn, input_index=0, sub_script=redeem_script)
    si.run_script(sig_script)
    assert len(si.stack) == 4
    si.run_script(script_pub_key)
    assert len(si.stack) == 4
    assert si.stack[-1] is True
    assert si.valid
    si._op_verify()

    # This will do the OP_CHECKMULTISIG
    si.run_script(redeem_script)
    assert len(si.stack) == 1
    assert si.stack[0] is True

    assert si.valid
    assert len(si.stack) == 1
def test_op_checkmultisig():
    txn = Transaction.from_hex("01000000010506344de69d47e432eb0174500d6e188a9e63c1e84a9e8796ec98c99b7559f701000000fdfd00004730440220695a28c42daa23c13e192e36a20d03a2a79994e0fe1c3c6b612d0ae23743064602200ca19003e7c1ce0cecb0bbfba9a825fc3b83cf54e4c3261cd15f080d24a8a5b901483045022100aa9096ce71995c24545694f20ab0482099a98c99b799c706c333c521e51db66002206578f023fa46f4a863a6fa7f18b95eebd1a91fcdf6ce714e8795d902bd6b682b014c69522102b66fcb1064d827094685264aaa90d0126861688932eafbd1d1a4ba149de3308b21025cab5e31095551582630f168280a38eb3a62b0b3e230b20f8807fc5463ccca3c21021098babedb3408e9ac2984adcf2a8e4c48e56a785065893f76d0fa0ff507f01053aeffffffff01c8af0000000000001976a91458b7a60f11a904feef35a639b6048de8dd4d9f1c88ac00000000")  # nopep8

    sig_script = txn.inputs[0].script
    redeem_script = Script(sig_script.ast[-1][-1])
    script_pub_key = Script.build_p2sh(redeem_script.hash160())

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=redeem_script)
    si.run_script(sig_script)
    assert len(si.stack) == 4
    si.run_script(script_pub_key)
    assert len(si.stack) == 4
    assert si.stack[-1] is True
    assert si.valid
    si._op_verify()

    # This will do the OP_CHECKMULTISIG
    si.run_script(redeem_script)
    assert len(si.stack) == 1
    assert si.stack[0] is True

    assert si.valid
    assert len(si.stack) == 1
def test_op_if():
    s = Script("OP_1 OP_IF OP_2 OP_3 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 3
    assert list(si.stack) == [2, 3, 4]
    assert len(si._if_else_stack) == 0

    s = Script("OP_0 OP_IF OP_2 OP_3 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [4]
    assert len(si._if_else_stack) == 0

    s = Script(
        "OP_1 OP_IF OP_2 OP_3 OP_IF OP_15 OP_ADD OP_ENDIF OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 2
    assert list(si.stack) == [17, 4]
    assert len(si._if_else_stack) == 0
def test_serialization():
    scr = 'OP_ADD OP_IF OP_DUP OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG OP_ELSE OP_IF OP_DUP OP_ELSE OP_2ROT OP_ENDIF OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUAL OP_ENDIF 0x010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101'    # nopep8

    s = Script(scr)
    assert s._tokens == ['OP_ADD', 'OP_IF', 'OP_DUP', 'OP_HASH160', b'h\xbf\x82z/\xa3\xb3\x1eS!^]\xd1\x92`\xd2\x1f\xdf\x05>', 'OP_EQUALVERIFY', 'OP_CHECKSIG', 'OP_ELSE', 'OP_IF', 'OP_DUP', 'OP_ELSE', 'OP_2ROT', 'OP_ENDIF', 'OP_HASH160', b'h\xbf\x82z/\xa3\xb3\x1eS!^]\xd1\x92`\xd2\x1f\xdf\x05>', 'OP_EQUAL', 'OP_ENDIF',  b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01']    # nopep8

    s_bytes = bytes(s)
    s_hex_str = bytes_to_str(s_bytes)

    s1 = Script.from_bytes(pack_var_str(s_bytes))[0]
    assert bytes(s1) == s_bytes

    raw_scr = "483045022100d60baf72dbaed8d15c3150e3309c9f7725fbdf91b0560330f3e2a0ccb606dfba02206422b1c73ce390766f0dc4e9143d0fbb400cc207e4a9fd9130e7f79e52bf81220121034ccd52d8f72cfdd680077a1a171458a1f7574ebaa196095390ae45e68adb3688"  # nopep8
    s = Script(bytes.fromhex(raw_scr))
    s._check_tokenized()
    assert s._tokens
    assert s._ast

    s_hex_str = bytes_to_str(bytes(s))
    assert s_hex_str == raw_scr

    s = Script('OP_0 OP_IF 0x1337c0de OP_ENDIF OP_1')
    b = bytes.fromhex("0063041337c0de6851")
    s1 = Script.from_bytes(pack_var_str(b))[0]
    assert bytes(s) == b
    assert bytes(s) == bytes(s1)
def test_op_within():
    s = Script("OP_4 OP_1 OP_15 OP_WITHIN")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_4 OP_5 OP_15 OP_WITHIN")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]

    s = Script("OP_4 OP_4 OP_15 OP_WITHIN")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_15 OP_4 OP_15 OP_WITHIN")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]
def test_op_checklocktimeverify():
    prev_txn_hash = Hash(
        '6eae1e03964799c4e29039db459ea4fad4df57c2b06f730b60032a48fb075620')
    txn_input = TransactionInput(prev_txn_hash, 0, Script(""), 1)

    addr = "1HJiL6AYYmtkbJzC9bxAorznWijwNK5Z8E"
    out_script_pub_key = Script.build_p2pkh(utils.address_to_key_hash(addr)[1])
    txn_output = TransactionOutput(9000, out_script_pub_key)

    # Create the txn
    txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, [txn_input],
                      [txn_output], 367987)

    # This is one more (367988) so it should fail
    s = Script("0x749d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid

    # This is negative, so it should fail
    s = Script("0xfff74d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid

    # This is one less (367986) so it should pass
    s = Script("0x729d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.stop

    # Now reformulate the txn so that the input is finalized
    txn_input.sequence_num = 0xffffffff
    si.run_script(s)

    assert not si.valid

    # The last check is if there are mismatching notions of locktime
    txn_input.sequence_num = 1
    txn.lock_time = 500000001
    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid
def test_validate_template():
    template = ['OP_HASH160', bytes, 'OP_EQUALVERIFY', 'OP_CHECKSIG']
    scr = Script('OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_NOP')

    assert not Script.validate_template(scr, template)

    scr[-1] = 'OP_CHECKSIG'

    assert Script.validate_template(scr, template)
Example #9
0
def test_list_operations():
    s = Script('OP_0 OP_1 OP_2')
    assert s[0] == 'OP_0'

    del s[2]
    assert s._tokens == ['OP_0', 'OP_1']

    s.append('OP_3')
    assert str(s) == 'OP_0 OP_1 OP_3'

    s.insert(2, 'OP_2')
    assert s._tokens == ['OP_0', 'OP_1', 'OP_2', 'OP_3']
    assert s._ast == ['OP_0', 'OP_1', 'OP_2', 'OP_3']

    for i, o in enumerate(s):
        assert o == 'OP_%d' % i

    s = Script('OP_1 OP_IF OP_2 OP_ELSE OP_3 OP_ENDIF')
    with pytest.raises(ScriptParsingError):
        del s[1]

    s = Script('OP_1 OP_IF OP_2 OP_ELSE OP_3 OP_ENDIF')
    del s[3]
    assert s._tokens == ['OP_1', 'OP_IF', 'OP_2', 'OP_3', 'OP_ENDIF']
    assert len(s) == 5
    assert str(s) == 'OP_1 OP_IF OP_2 OP_3 OP_ENDIF'

    s = Script('OP_1 OP_IF OP_2 OP_ELSE OP_3 OP_ENDIF')
    with pytest.raises(ScriptParsingError):
        del s[5]

    s = Script(['OP_1', 'OP_3'])
    assert len(s) == 2
    assert s._tokens == ['OP_1', 'OP_3']
Example #10
0
def test_remove_op():
    scr = "OP_ADD OP_CODESEPARATOR OP_DUP OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG"  # nopep8
    s = Script(scr)
    s1 = s.remove_op("OP_CODESEPARATOR")
    assert str(s1) == "OP_ADD OP_DUP OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG"

    s2 = s1.remove_op("OP_DUP")
    assert str(s2) == "OP_ADD OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG"

    s3 = s2.remove_op("OP_EQUAL")
    assert str(s2) == str(s3)
def test_op_negate():
    s = Script("OP_3 OP_NEGATE")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [-3]

    si.run_script(Script("OP_NEGATE"))

    assert list(si.stack) == [3]
def test_op_checksig():
    # This is from the same example as in test_signing.py
    txn = Transaction.from_hex(
        "0100000001205607fb482a03600b736fb0c257dfd4faa49e45db3990e2c4994796031eae6e000000001976a914e9f061ff2c9885c7b137de35e416cbd5d3e1087c88acffffffff0128230000000000001976a914f1fd1dc65af03c30fe743ac63cef3a120ffab57d88ac00000000"
    )  # nopep8

    pub_key_hex = "0x04e674caf81eb3bb4a97f2acf81b54dc930d9db6a6805fd46ca74ac3ab212c0bbf62164a11e7edaf31fbf24a878087d925303079f2556664f3b32d125f2138cbef"  # nopep8
    sig_hex = "0x3045022100ed84be709227397fb1bc13b749f235e1f98f07ef8216f15da79e926b99d2bdeb02206ff39819d91bc81fecd74e59a721a38b00725389abb9cbecb42ad1c939fd826201"  # nopep8
    s = Script("%s %s OP_CHECKSIG" % (sig_hex, pub_key_hex))
    prev_script_pub_key = Script.build_p2pkh(
        utils.address_to_key_hash("1NKxQnbtKDdL6BY1UaKdrzCxQHfn3TQnqZ")[1])

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is True

    s = Script("%s %s OP_CHECKSIGVERIFY" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 0
    assert not si.stop

    # Try it once more with an incorrect sig
    pub_key_hex = "0x04e674caf81eb3bb4a97f2acf81b54dc930d9db6a6805fd46ca74ac3ab212c0bbf62164a11e7edaf31fbf24a878087d925303079f2556664f3b32d125f2138cbef"  # nopep8
    sig_hex = "0x3045022100ed84be709227397fc1bc13b749f235e1f98f07ef8216f15da79e926b99d2bdeb02206ff39819d91bc81fecd74e59a721a38b00725389abb9cbecb42ad1c939fd826201"  # nopep8
    s = Script("%s %s OP_CHECKSIG" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is False

    s = Script("%s %s OP_CHECKSIGVERIFY" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 0
    assert si.stop
def test_op_0notequal():
    s = Script("OP_1 OP_0NOTEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    si.run_script(Script("OP_NOT"))
    assert list(si.stack) == [0]

    si.run_script(Script("OP_0NOTEQUAL"))
    assert list(si.stack) == [0]
def test_op_not():
    s = Script("OP_1 OP_NOT")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]

    si.run_script(Script("OP_2 OP_NOT"))
    assert list(si.stack) == [0, 0]

    si.run_script(Script("OP_NOT"))
    assert list(si.stack) == [0, 1]
def test_op_verify():
    s = Script("0x01 OP_VERIFY")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 0
    assert not si.stop

    s = Script("0x00 OP_VERIFY")
    si.run_script(s)

    assert len(si.stack) == 0
    assert si.stop
Example #16
0
def test_multisig_sig():
    sig_script = Script('OP_0 0x30440220762ce7bca626942975bfd5b130ed3470b9f538eb2ac120c2043b445709369628022051d73c80328b543f744aa64b7e9ebefa7ade3e5c716eab4a09b408d2c307ccd701 0x3045022100abf740b58d79cab000f8b0d328c2fff7eb88933971d1b63f8b99e89ca3f2dae602203354770db3cc2623349c87dea7a50cee1f78753141a5052b2d58aeb592bcf50f01 0x524104a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd41046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187410411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e8353ae')  # nopep8

    assert sig_script.is_multisig_sig()

    r = sig_script.extract_multisig_sig_info()
    redeem_info = r['redeem_script'].extract_multisig_redeem_info()
    assert len(r['signatures']) == 2
    assert r['redeem_script']
    assert isinstance(r['redeem_script'], Script)

    s = Script.build_multisig_sig(r['signatures'], r['redeem_script'])
    assert bytes(s) == bytes(sig_script)

    # This is a test case where there is no OP_PUSHDATA
    raw_scr = "00483045022100fa1225f8828fd6fe52665c3c4258169a84af52b41525f2e288082f174c032f47022022758d5519db3ab2cec4a330e96568b9289fb77c5653bce49397df01a3fcff5101475221038b5fa60aee4c4e9ab3a66e6bb32211a54da6b054c6143dd221c122ce936315d921023180e1b49b7f3fd1254a19c7aa8016ad995089b99c9dac89752cd17e40d9072d52ae"  # nopep8
    s, _ = Script.from_bytes(pack_var_str(bytes.fromhex(raw_scr)))

    assert sig_script.is_multisig_sig()

    r = s.extract_multisig_sig_info()
    assert len(r['signatures']) == 1
    assert r['redeem_script']
    assert isinstance(r['redeem_script'], Script)

    sig_addresses = sig_script.get_addresses()
    assert len(sig_addresses) == redeem_info['n'] + 1
    assert sig_addresses == ['1JzVFZSN1kxGLTHG41EVvY5gHxLAX7q1Rh',
                             '14JfSvgEq8A8S7qcvxeaSCxhn1u1L71vo4',
                             '1Kyy7pxzSKG75L9HhahRZgYoer9FePZL4R',
                             '347N1Thc213QqfYCz3PZkjoJpNv5b14kBd']
def test_op_pushdata():
    s = Script("0x" + "12" * 0x4e)

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] == bytes([0x12] * 0x4e)

    s = Script("0x" + "12" * 0x4eff)
    si.run_script(s)

    assert len(si.stack) == 2
    assert si.stack[1] == bytes([0x12] * 0x4eff)
Example #18
0
def txn_from_json(txn_json):
    inputs = []
    for i in txn_json['inputs']:
        if 'output_hash' in i:
            outpoint = Hash(i['output_hash'])
            script = Script(bytes.fromhex(i['script_signature_hex']))
            # Do this to test script de/serialization
            script._disassemble()
            inp = TransactionInput(outpoint, i['output_index'], script,
                                   i['sequence'])
        else:
            # Coinbase txn, we pass in a block version of 1 since the
            # coinbase script from api.chain.com already has the
            # height in there. Don't want our stuff to repack it in.
            inp = CoinbaseInput(txn_json['block_height'],
                                bytes.fromhex(i['coinbase']), i['sequence'], 1)

        inputs.append(inp)

    outputs = []
    for o in txn_json['outputs']:
        scr = Script(bytes.fromhex(o['script_hex']))
        scr._disassemble()
        out = TransactionOutput(o['value'], scr)
        outputs.append(out)

    txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs,
                      txn_json['lock_time'])

    return txn
Example #19
0
def test_is_p2sh():
    s = Script("OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUAL")
    assert s.is_p2sh()
    assert not s.is_multisig_redeem()
    assert not s.is_p2pkh_sig()

    s = Script.build_p2sh(bytes.fromhex("68bf827a2fa3b31e53215e5dd19260d21fdf053e"))
    assert s.is_p2sh()

    s = Script("OP_ADD OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY")
    assert not s.is_p2sh()
    assert not s.is_multisig_redeem()
def test_op_max():
    s = Script("OP_1 OP_2 OP_MAX")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [2]

    s = Script("OP_2 OP_2 OP_MAX")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [2]
def test_op_checklocktimeverify():
    prev_txn_hash = Hash('6eae1e03964799c4e29039db459ea4fad4df57c2b06f730b60032a48fb075620')
    txn_input = TransactionInput(prev_txn_hash, 0, Script(""), 1)

    addr = "1HJiL6AYYmtkbJzC9bxAorznWijwNK5Z8E"
    out_script_pub_key = Script.build_p2pkh(
        utils.address_to_key_hash(addr)[1])
    txn_output = TransactionOutput(9000, out_script_pub_key)

    # Create the txn
    txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                      [txn_input],
                      [txn_output],
                      367987)

    # This is one more (367988) so it should fail
    s = Script("0x749d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid

    # This is negative, so it should fail
    s = Script("0xfff74d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid

    # This is one less (367986) so it should pass
    s = Script("0x729d05 OP_CHECKLOCKTIMEVERIFY")

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.stop

    # Now reformulate the txn so that the input is finalized
    txn_input.sequence_num = 0xffffffff
    si.run_script(s)

    assert not si.valid

    # The last check is if there are mismatching notions of locktime
    txn_input.sequence_num = 1
    txn.lock_time = 500000001
    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=out_script_pub_key)
    si.run_script(s)

    assert not si.valid
def test_op_greaterthanequal():
    s = Script("OP_1 OP_2 OP_GREATERTHANEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_2 OP_1 OP_GREATERTHANEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]
def test_op_numnotequal():
    s = Script("OP_1 OP_2 OP_NUMNOTEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_16 OP_16 OP_NUMNOTEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]
def test_op_numequalverify():
    s = Script("OP_1 OP_2 OP_NUMEQUALVERIFY OP_3")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 0
    assert list(si.stack) == []

    s = Script("OP_16 OP_16 OP_NUMEQUALVERIFY OP_3")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [3]
def test_op_booland():
    s = Script("OP_1 OP_2 OP_BOOLAND")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_1 OP_1 OP_NOT OP_BOOLAND")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]
def test_op_equal():
    s = Script("0x01 0x01 OP_EQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is True

    s = Script("0x01 0x02 OP_EQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is False
def test_op_notif():
    s = Script("OP_1 OP_NOTIF OP_2 OP_3 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [4]

    s = Script("OP_0 OP_NOTIF OP_2 OP_3 OP_ENDIF OP_4")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 3
    assert list(si.stack) == [2, 3, 4]
def test_op_sub():
    s = Script("OP_1 OP_2 OP_SUB")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]

    s = Script("OP_2 OP_1 OP_SUB")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [-1]
def test_disabled_ops():
    for opcode in ScriptInterpreter.DISABLED_OPS:
        si = ScriptInterpreter()
        si.run_script(Script("OP_1 " + opcode + " OP_2"))

        assert not si.valid
        assert list(si.stack) == [1]
def test_op_lessthanequal():
    s = Script("OP_1 OP_2 OP_LESSTHANEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [0]

    s = Script("OP_2 OP_2 OP_LESSTHANEQUAL")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [1]
def test_op_1sub():
    s = Script("OP_3 OP_1SUB")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [2]
def test_op_abs():
    s = Script("OP_3 OP_NEGATE OP_ABS")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [3]
def test_op_add():
    s = Script("OP_1 OP_2 OP_ADD")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert list(si.stack) == [3]
def test_op_1negate():
    s = Script("OP_1NEGATE")

    si = ScriptInterpreter()
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] == -1
Example #35
0
    def set_txn_side_effect_for_hd_discovery(self):
        # For each used account, there are at least 2 calls required:
        # 1 for the first DISCOVERY_INCREMENT payout addresses and 1
        # for the first DISCOVERY_INCREMENT change
        # addresses. Depending on the number of used addresses for the
        # account, this will change.

        effects = []

        n = self._num_used_accounts
        if n == 0:
            n = 1

        for acct_num in range(n):
            for change in [0, 1]:
                num_used = self._num_used_addresses[acct_num][change]
                r = math.ceil((num_used + HDAccount.GAP_LIMIT) /
                              self.address_increment)
                k = 'change_addresses' if change else 'payout_addresses'
                addr_list = self._acct_keys[acct_num][k]

                if change:
                    metadata = dict(block=234790 + r,
                                    block_hash=Hash("000000000000000007d57f03ebe36dbe4f87ab2f340e93b45999ab249b6dc0df"),
                                    confirmations=23890 - r)
                else:
                    metadata = dict(block=None,
                                    block_hash=None,
                                    confirmations=0)

                if r == 0:
                    r = 1
                for i in range(r):
                    start = i * self.address_increment
                    end = (i + 1) * self.address_increment
                    addr_range = range(start, end)

                    out = TransactionOutput(value=100000,
                                            script=Script.build_p2pkh(
                                                address_to_key_hash(
                                                    addr_list[i])[1]))
                    dummy_txn = Transaction(1,
                                            [],
                                            [out],
                                            0)

                    m = MockTxnDict(num_used=num_used,
                                    addr_range=addr_range,
                                    addr_list=addr_list,
                                    used_value=[dict(metadata=metadata,
                                                     transaction=dummy_txn)],
                                    unused_value=[])
                    effects.append(m)

        self.get_transactions.side_effect = effects

        return len(effects)
def test_op_checksig():
    # This is from the same example as in test_signing.py
    txn = Transaction.from_hex("0100000001205607fb482a03600b736fb0c257dfd4faa49e45db3990e2c4994796031eae6e000000001976a914e9f061ff2c9885c7b137de35e416cbd5d3e1087c88acffffffff0128230000000000001976a914f1fd1dc65af03c30fe743ac63cef3a120ffab57d88ac00000000")  # nopep8

    pub_key_hex = "0x04e674caf81eb3bb4a97f2acf81b54dc930d9db6a6805fd46ca74ac3ab212c0bbf62164a11e7edaf31fbf24a878087d925303079f2556664f3b32d125f2138cbef"  # nopep8
    sig_hex = "0x3045022100ed84be709227397fb1bc13b749f235e1f98f07ef8216f15da79e926b99d2bdeb02206ff39819d91bc81fecd74e59a721a38b00725389abb9cbecb42ad1c939fd826201"  # nopep8
    s = Script("%s %s OP_CHECKSIG" % (sig_hex, pub_key_hex))
    prev_script_pub_key = Script.build_p2pkh(utils.address_to_key_hash(
        "1NKxQnbtKDdL6BY1UaKdrzCxQHfn3TQnqZ")[1])

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is True

    s = Script("%s %s OP_CHECKSIGVERIFY" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 0
    assert not si.stop

    # Try it once more with an incorrect sig
    pub_key_hex = "0x04e674caf81eb3bb4a97f2acf81b54dc930d9db6a6805fd46ca74ac3ab212c0bbf62164a11e7edaf31fbf24a878087d925303079f2556664f3b32d125f2138cbef"  # nopep8
    sig_hex = "0x3045022100ed84be709227397fc1bc13b749f235e1f98f07ef8216f15da79e926b99d2bdeb02206ff39819d91bc81fecd74e59a721a38b00725389abb9cbecb42ad1c939fd826201"  # nopep8
    s = Script("%s %s OP_CHECKSIG" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 1
    assert si.stack[0] is False

    s = Script("%s %s OP_CHECKSIGVERIFY" % (sig_hex, pub_key_hex))

    si = ScriptInterpreter(txn=txn,
                           input_index=0,
                           sub_script=prev_script_pub_key)
    si.run_script(s)

    assert len(si.stack) == 0
    assert si.stop
Example #37
0
File: txn.py Project: shayanb/two1
    def __init__(self, height, raw_script, sequence=MAX_INT, block_version=3):
        self.height = height
        if block_version == 1:
            scr = raw_script
        else:
            scr = Script.build_push_int(self.height) + raw_script

        # Coinbase scripts are basically whatever, so we don't
        # try to create a script object from them.

        super().__init__(self.NULL_OUTPOINT,
                         self.MAX_INT,
                         scr,
                         sequence)
Example #38
0
def test_multisig():
    # This test-case taken from:
    # https://gist.github.com/gavinandresen/3966071
    pubkeys = [
        "0491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f86",  # nopep8
        "04865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec6874",  # nopep8
        "048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46213"]  # nopep8

    serialized_pubkeys = [bytes.fromhex(p) for p in pubkeys]

    redeem_script = Script.build_multisig_redeem(2, serialized_pubkeys)

    assert bytes_to_str(bytes(redeem_script)) == "52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae"  # nopep8

    assert redeem_script.is_multisig_redeem()

    # Get the address of the redeem script
    assert redeem_script.address(True).startswith("2")
    address = redeem_script.address()
    assert address == "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
Example #39
0
File: txn.py Project: shayanb/two1
    def from_bytes(b):
        """ Deserializes a byte stream into a TransactionInput.

        Args:
            b (bytes): byte stream starting with the outpoint.

        Returns:
            tuple: First element of the tuple is the TransactionInput
                   object and the second is the remaining byte stream.
        """
        outpoint = b[0:32]
        outpoint_index, b1 = unpack_u32(b[32:])
        script, b1 = Script.from_bytes(b1)
        sequence_num, b1 = unpack_u32(b1)

        return (
            TransactionInput(Hash(outpoint),
                             outpoint_index,
                             script,
                             sequence_num),
            b1
        )
Example #40
0
def txn_from_json(txn_json):
    inputs = []
    for i in txn_json['inputs']:
        if 'output_hash' in i:
            outpoint = Hash(i['output_hash'])
            script = Script(bytes.fromhex(i['script_signature_hex']))
            # Do this to test script de/serialization
            script._disassemble()
            inp = TransactionInput(outpoint,
                                   i['output_index'],
                                   script,
                                   i['sequence'])
        else:
            # Coinbase txn, we pass in a block version of 1 since the
            # coinbase script from api.chain.com already has the
            # height in there. Don't want our stuff to repack it in.
            inp = CoinbaseInput(txn_json['block_height'],
                                bytes.fromhex(i['coinbase']),
                                i['sequence'],
                                1)

        inputs.append(inp)

    outputs = []
    for o in txn_json['outputs']:
        scr = Script(bytes.fromhex(o['script_hex']))
        scr._disassemble()
        out = TransactionOutput(o['value'], scr)
        outputs.append(out)

    txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                      inputs,
                      outputs,
                      txn_json['lock_time'])

    return txn
Example #41
0
    def txn_from_json(txn_json):
        """ Returns a new Transaction from a JSON-serialized transaction

        Args:
            txn_json: JSON with the following format:

        {
        "hash": "0bf0de38c26195919179f...",
        "block_hash": "000000000000000...",
        "block_height": 303404,
        "block_time": "2014-05-30T23:54:55Z",
        "chain_received_at": "2015-08-13T10:52:21.718Z",
        "confirmations": 69389,
        "lock_time": 0,
        "inputs": [
          {
            "transaction_hash": "0bf0de38c2619...",
            "output_hash": "b84a66c46e24fe71f9...",
            "output_index": 0,
            "value": 300000,
            "addresses": [
              "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr"
            ],
            "script_signature": "03046022100de7b67b9...",
            "script_signature_hex": "00493046022100de7b...",
            "sequence": 4294967295
          }
        ],
        "outputs": [
          {
            "transaction_hash": "0bf0de38c261959...",
            "output_index": 0,
            "value": 290000,
            "addresses": [
              "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
            ],
            "script": "OP_DUP OP_HASH160 c629680b8d...",
            "script_hex": "76a914c629680b8d13...",
            "script_type": "pubkeyhash",
            "required_signatures": 1,
            "spent": false,
            "spending_transaction": null
          }
        ],
        "fees": 10000,
        "amount": 290000
        },
        Transaction.DEFAULT_TRANSACTION_VERSION

        Returns:
            two1.bitcoin.Transaction: a deserialized transaction derived
                from the provided json.

        """
        inputs = []
        outputs = []
        addr_keys = set()

        for i in sorted(txn_json["vin"], key=lambda i: i["n"]):
            if 'coinbase' in i:
                inputs.append(CoinbaseInput(height=0,
                                            raw_script=bytes.fromhex(i['coinbase']),
                                            sequence=i['sequence'],
                                            block_version=1))
            else:
                script = Script.from_hex(i["scriptSig"]["hex"])
                inputs.append(TransactionInput(Hash(i["txid"]),
                                               i["vout"],
                                               script,
                                               i["sequence"]))
            if "addr" in i:
                addr_keys.add(i["addr"])

        for o in sorted(txn_json["vout"], key=lambda o: o["n"]):
            script = Script.from_hex(o["scriptPubKey"]["hex"])
            value = int(decimal.Decimal(str(o["value"])) * decimal.Decimal('1e8'))
            outputs.append(TransactionOutput(value, script))

            if "addresses" in o["scriptPubKey"]:
                for a in o["scriptPubKey"]["addresses"]:
                    addr_keys.add(a)

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                          inputs,
                          outputs,
                          txn_json["locktime"])

        assert txn.hash == Hash(txn_json['txid'])

        return txn, addr_keys
Example #42
0
File: txn.py Project: shayanb/two1
    def _do_multisig_script(self, sigs, message, current_script_sig,
                            redeem_script, hash_type):
        # If the current script is empty or None, create it
        sig_script = None
        if current_script_sig is None or not str(current_script_sig):
            sig_bytes = [s['signature'].to_der() + pack_compact_int(hash_type)
                         for s in sigs]

            sig_script = Script.build_multisig_sig(sigs=sig_bytes,
                                                   redeem_script=redeem_script)
        else:
            # Need to extract all the sigs already present
            multisig_params = redeem_script.extract_multisig_redeem_info()
            sig_info = current_script_sig.extract_multisig_sig_info()

            # Do a few quick sanity checks
            if str(sig_info['redeem_script']) != str(redeem_script):
                raise ValueError(
                    "Redeem script in signature script does not match redeem_script!")

            if len(sig_info['signatures']) == multisig_params['n']:
                # Already max number of signatures
                return current_script_sig

            # Go through the signatures and match them up to the public keys
            # in the redeem script
            pub_keys = []
            for pk in multisig_params['public_keys']:
                pub_keys.append(crypto.PublicKey.from_bytes(pk))

            existing_sigs = []
            for s in sig_info['signatures']:
                s1, h = s[:-1], s[-1]  # Last byte is hash_type
                existing_sigs.append(crypto.Signature.from_der(s1))
                if h != hash_type:
                    raise ValueError("hash_type does not match that of the existing signatures.")

            # Match them up
            existing_sig_indices = self._match_sigs_to_pub_keys(existing_sigs,
                                                                pub_keys,
                                                                message)
            sig_indices = {s['index']: s['signature'] for s in sigs}

            # Make sure there are no dups
            all_indices = set(list(existing_sig_indices.keys()) +
                              list(sig_indices.keys()))
            if len(all_indices) < len(existing_sig_indices) + len(sig_indices):
                raise ValueError("At least one signature matches an existing signature.")

            if len(all_indices) > multisig_params['n']:
                raise ValueError("There are too many signatures.")

            all_sigs = []
            for i in sorted(all_indices):
                if i in existing_sig_indices:
                    all_sigs.append(existing_sig_indices[i])
                elif i in sig_indices:
                    all_sigs.append(sig_indices[i])

            all_sigs_bytes = [s.to_der() + pack_compact_int(hash_type)
                              for s in all_sigs]
            sig_script = Script.build_multisig_sig(all_sigs_bytes,
                                                   redeem_script)

        return sig_script
Example #43
0
    def txn_from_json(txn_json):
        """ Returns a new Transaction from a JSON-serialized transaction

        Args:
            txn_json:
                JSON with the following format:

                    {
                    "hash": "0bf0de38c26195919179f...",
                    "block_hash": "000000000000000...",
                    "block_height": 303404,
                    "block_time": "2014-05-30T23:54:55Z",
                    "chain_received_at": "2015-08-13T10:52:21.718Z",
                    "confirmations": 69389,
                    "lock_time": 0,
                    "inputs": [
                      {
                        "transaction_hash": "0bf0de38c2619...",
                        "output_hash": "b84a66c46e24fe71f9...",
                        "output_index": 0,
                        "value": 300000,
                        "addresses": [
                          "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr"
                        ],
                        "script_signature": "03046022100de7b67b9...",
                        "script_signature_hex": "00493046022100de7b...",
                        "sequence": 4294967295
                      }
                    ],
                    "outputs": [
                      {
                        "transaction_hash": "0bf0de38c261959...",
                        "output_index": 0,
                        "value": 290000,
                        "addresses": [
                          "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
                        ],
                        "script": "OP_DUP OP_HASH160 c629680b8d...",
                        "script_hex": "76a914c629680b8d13...",
                        "script_type": "pubkeyhash",
                        "required_signatures": 1,
                        "spent": false,
                        "spending_transaction": null
                      }
                    ],
                    "fees": 10000,
                    "amount": 290000
                    },
                    Transaction.DEFAULT_TRANSACTION_VERSION

        Returns:
            two1.bitcoin.Transaction:
                a deserialized transaction derived
                from the provided json.

        """
        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            if 'coinbase' in i:
                inputs.append(
                    CoinbaseInput(
                        height=txn_json["block_height"] or 0,
                        raw_script=bytes.fromhex(i['coinbase']),
                        sequence=i['sequence'],
                        block_version=1))
            else:
                # Script length etc. are not returned so we need to
                # prepend that.
                script, _ = Script.from_bytes(
                    pack_var_str(bytes.fromhex(i["script_signature_hex"])))
                inputs.append(TransactionInput(Hash(i["output_hash"]),
                                               i["output_index"],
                                               script,
                                               i["sequence"]))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script_hex"])))
            outputs.append(TransactionOutput(i["value"],
                                             script))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                          inputs,
                          outputs,
                          txn_json["lock_time"])

        return txn, addr_keys
Example #44
0
def test_is_p2pkh():
    s = Script("OP_DUP OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG")
    assert s.is_p2pkh()
    assert not s.is_multisig_redeem()
    assert not s.is_p2pkh_sig()

    assert s.address()

    addresses = s.get_addresses()
    assert len(addresses) == 1
    assert addresses[0] == '1AYrhH1SAQqhT8w5NguBSogN63ajS6PxNL'

    s = Script.build_p2pkh(bytes.fromhex("68bf827a2fa3b31e53215e5dd19260d21fdf053e"))
    assert s.is_p2pkh()

    s = Script("OP_ADD OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY")
    assert not s.is_p2pkh()
    assert not s.is_multisig_redeem()