diff --git a/README.md b/README.md index af81b4a..197465f 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ pip install -r requirements.txt Run the test suite by lauching ``` -./tests.sh +pytest ``` ## Examples diff --git a/blockchain_parser/tests/test_address.py b/blockchain_parser/tests/test_address.py index 779a30b..a7848b2 100644 --- a/blockchain_parser/tests/test_address.py +++ b/blockchain_parser/tests/test_address.py @@ -30,3 +30,16 @@ def test_from_ripemd160(self): ripemd160 = "010966776006953D5567439E5E39F86A0D273BEE" address = Address.from_ripemd160(a2b_hex(ripemd160)) self.assertEqual(address.address, "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM") + + def test_from_bech32(self): + # Example sourced from https://en.bitcoin.it/wiki/Bech32 + bech32 = "751e76e8199196d454941c45d1b3a323f1433bd6" + address = Address.from_bech32(a2b_hex(bech32), segwit_version=0) + self.assertEqual(address.address, "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4") + + def test_from_bech32m(self): + # https://blockstream.info/tx/33e794d097969002ee05d336686fc03c9e15a597c1b9827669460fac98799036?expand + # Second output + bech32m = "a37c3903c8d0db6512e2b40b0dffa05e5a3ab73603ce8c9c4b7771e5412328f9" + address = Address.from_bech32m(a2b_hex(bech32m), segwit_version=1) + self.assertEqual(address.address, "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297") diff --git a/blockchain_parser/tests/test_script.py b/blockchain_parser/tests/test_script.py index 1badaa1..c01f62d 100644 --- a/blockchain_parser/tests/test_script.py +++ b/blockchain_parser/tests/test_script.py @@ -27,6 +27,7 @@ def test_op_return_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertTrue(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_unknown_script(self): case = "40" @@ -40,6 +41,7 @@ def test_unknown_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertTrue(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) case = "" script = Script.from_hex(a2b_hex(case)) @@ -52,6 +54,7 @@ def test_unknown_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertTrue(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_multisig_script(self): case = "514104cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af52ae" @@ -64,6 +67,7 @@ def test_multisig_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_p2sh_script(self): case = "a91428ad3e63dcae36e5010527578e2eef0e9eeaf3e487" @@ -76,6 +80,7 @@ def test_p2sh_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_p2wpkh_script(self): case = "0014c958269b5b6469b6e4b87de1062028ad3bb83cc2" @@ -88,6 +93,7 @@ def test_p2wpkh_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_p2wsh_script(self): case = "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d" @@ -100,6 +106,7 @@ def test_p2wsh_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_pubkeyhash_script(self): case = "76a914e9629ef6f5b82564a9b2ecae6c288c56fb33710888ac" @@ -112,6 +119,7 @@ def test_pubkeyhash_script(self): self.assertTrue(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) def test_pubkey_script(self): script = Script.from_hex(a2b_hex("4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac")) @@ -123,3 +131,18 @@ def test_pubkey_script(self): self.assertFalse(script.is_pubkeyhash()) self.assertFalse(script.is_unknown()) self.assertFalse(script.is_return()) + self.assertFalse(script.is_p2tr()) + + def test_taproot_script(self): + # https://blockstream.info/tx/33e794d097969002ee05d336686fc03c9e15a597c1b9827669460fac98799036?expand + # Second output + script = Script.from_hex(a2b_hex("5120a37c3903c8d0db6512e2b40b0dffa05e5a3ab73603ce8c9c4b7771e5412328f9")) + self.assertFalse(script.is_pubkey()) + self.assertFalse(script.is_multisig()) + self.assertFalse(script.is_p2sh()) + self.assertFalse(script.is_p2wpkh()) + self.assertFalse(script.is_p2wsh()) + self.assertFalse(script.is_pubkeyhash()) + self.assertFalse(script.is_unknown()) + self.assertFalse(script.is_return()) + self.assertTrue(script.is_p2tr()) diff --git a/blockchain_parser/tests/test_taproot.py b/blockchain_parser/tests/test_taproot.py deleted file mode 100644 index 9ebec0b..0000000 --- a/blockchain_parser/tests/test_taproot.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (C) 2015-2016 The bitcoin-blockchain-parser developers -# -# This file is part of bitcoin-blockchain-parser. -# -# It is subject to the license terms in the LICENSE file found in the top-level -# directory of this distribution. -# -# No part of bitcoin-blockchain-parser, including this file, may be copied, -# modified, propagated, or distributed except according to the terms contained -# in the LICENSE file. -# -# The transactions were taken from -# https://bitcoin.stackexchange.com/questions/110995/how -# -can-i-find-samples-for-p2tr-transactions-on-mainnet -# -# 33e7…9036, the first P2TR transaction -# 3777…35c8, the first transaction with both a P2TR scriptpath and a P2TR keypath input -# 83c8…7d82, with multiple P2TR keypath inputs -# 905e…d530, the first scriptpath 2-of-2 multisig spend -# 2eb8…b272, the first use of the new Tapscript opcode OP_CHECKSIGADD -# -# THESE TRANSACTIONS ARE INCLUDED IN BLK02804.DAT - -import os -import sys -sys.path.append('../..') -from blockchain_parser.blockchain import Blockchain - - -FIRST_TAPROOT = "33e794d097969002ee05d336686fc03c9e15a597c1b9827669460fac98799036" -FIRST_TAPROOT_2X_P2TR = "37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8" -MULTIPLE_P2TR_INPUTS = "83c8e0289fecf93b5a284705396f5a652d9886cbd26236b0d647655ad8a37d82" -FIRST_2_OF_2_SPEND = "905ecdf95a84804b192f4dc221cfed4d77959b81ed66013a7e41a6e61e7ed530" -USING_OP_CHECKSIGADD = "2eb8dbaa346d4be4e82fe444c2f0be00654d8cfd8c4a9a61b11aeaab8c00b272" - - -TAPROOTS = [FIRST_TAPROOT, - FIRST_TAPROOT_2X_P2TR, - MULTIPLE_P2TR_INPUTS, - FIRST_2_OF_2_SPEND, - USING_OP_CHECKSIGADD] - - -blockchain = Blockchain(os.path.expanduser('../../blocks')) -for block in blockchain.get_unordered_blocks(): - for tx in block.transactions: - if tx.txid in TAPROOTS: - print("{:<15}{}".format("Tx ID: ", tx.txid)) - for tx_input in tx.inputs: - print("{:<15}{}".format("Input Tx ID: ",tx_input.transaction_hash)) - for tx_output in tx.outputs: - for addr in tx_output.addresses: - print("{:<15}{}".format("Address: ", addr.address)) - print("{:<15}{:,.0f} s".format("Value: ", tx_output.value)) - print("----------------------------------------------------------------") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index c751a70..d5b28b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ python-bitcoinlib==0.11.0 plyvel==1.5.1 ripemd-hash==1.0.1 -coverage==7.4.4 +pytest==8.1.1 diff --git a/tests.sh b/tests.sh deleted file mode 100755 index 4615bcb..0000000 --- a/tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -coverage run --append --include='blockchain_parser/*' --omit='*/tests/*' setup.py test -coverage report -coverage erase