From 0e270062adc2d05ca06da096083a607c89db7ef4 Mon Sep 17 00:00:00 2001 From: k-matsuzawa <49718559+ko-matsu@users.noreply.github.com> Date: Mon, 27 Sep 2021 09:14:39 +0900 Subject: [PATCH] Update to v0.3.2 (#8) * upgrade: update from cryptogarageinc/v0.3.7 --- .github/workflows/check_pre-merge_master.yml | 2 + Dockerfile | 35 --- Pipfile | 2 +- README.md | 4 +- VERSION | 2 +- cfd/__init__.py | 3 +- cfd/address.py | 45 +++- cfd/block.py | 232 ++++++++++++++++++ cfd/confidential_transaction.py | 99 ++++++-- cfd/hdwallet.py | 18 +- cfd/taproot.py | 122 ++++++---- cfd/transaction.py | 33 ++- cfd/util.py | 19 ++ docker-compose.yml | 28 ++- external/CMakeLists.txt | 2 +- integration_test/Dockerfile | 12 - integration_test/docker-compose.yml | 11 - integration_test/test_entrypoint.sh | 3 + integration_test/tests/test_bitcoin.py | 211 ++++++++++++++++- integration_test/tests/test_elements.py | 48 +++- setup.cfg | 6 +- tests/data/address_test.json | 68 +++++- tests/data/block_test.json | 200 ++++++++++++++++ tests/data/descriptor_test.json | 48 +++- tests/data/elements_address_test.json | 229 ++++++++++++++++++ tests/data/elements_coin_test.json | 233 ++++++++++++++++--- tests/data/elements_test.json | 22 ++ tests/data/elements_transaction_test.json | 33 +++ tests/data/hdwallet_test.json | 6 +- tests/data/psbt_test.json | 218 +++++++++++++++++ tests/data/transaction_test.json | 33 +++ tests/data/utxo/elements_utxo_1.json | 39 ++-- tests/data/utxo/elements_utxo_2.json | 39 ++-- tests/data/utxo/elements_utxo_3.json | 39 ++-- tests/data/utxo/elements_utxo_4.json | 73 ++++++ tests/test_address.py | 146 +++++++----- tests/test_block.py | 78 +++++++ tests/test_confidential_transaction.py | 58 ++++- tests/test_elements.py | 25 +- tests/test_psbt.py | 4 +- tests/test_transaction.py | 3 + tools/build_and_test_for_docker.sh | 83 +++++++ 42 files changed, 2283 insertions(+), 331 deletions(-) delete mode 100644 Dockerfile create mode 100644 cfd/block.py delete mode 100644 integration_test/Dockerfile delete mode 100644 integration_test/docker-compose.yml create mode 100644 tests/data/block_test.json create mode 100644 tests/data/utxo/elements_utxo_4.json create mode 100644 tests/test_block.py create mode 100755 tools/build_and_test_for_docker.sh diff --git a/.github/workflows/check_pre-merge_master.yml b/.github/workflows/check_pre-merge_master.yml index 4a3810c..1b151eb 100644 --- a/.github/workflows/check_pre-merge_master.yml +++ b/.github/workflows/check_pre-merge_master.yml @@ -4,6 +4,7 @@ on: push: branches: - master + - stable_v* paths-ignore: - '.github/workflows/create_release-and-upload.yml' - '.github/workflows/code_scanner.yml' @@ -11,6 +12,7 @@ on: pull_request: branches: - master + - stable_v* env: GITHUB_VERSION: v0.0.10 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index bc068f2..0000000 --- a/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM python:3.9.0-slim-buster as cfdPythonBuilder - -RUN apt-get update && apt-get install -y tzdata -ENV TZ=Asia/Tokyo - -RUN apt-get install -y \ - gpg \ - wget \ - build-essential \ - git \ - && rm -rf /var/lib/apt/lists/* - -ENV GPG_KEY_SERVER hkp://keyserver.ubuntu.com:80 - -ENV CMAKE_VERSION 3.17.2 -ENV CMAKE_TARBALL cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz -ENV CMAKE_URL_BASE https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION} -ENV CMAKE_PGP_KEY C6C265324BBEBDC350B513D02D2CEF1034921684 -RUN wget -qO ${CMAKE_TARBALL} ${CMAKE_URL_BASE}/${CMAKE_TARBALL} \ - && gpg --keyserver ${GPG_KEY_SERVER} --recv-keys ${CMAKE_PGP_KEY} \ - && wget -qO cmake-SHA-256.txt ${CMAKE_URL_BASE}/cmake-${CMAKE_VERSION}-SHA-256.txt \ - && wget -qO cmake-SHA-256.txt.asc ${CMAKE_URL_BASE}/cmake-${CMAKE_VERSION}-SHA-256.txt.asc \ - && gpg --verify cmake-SHA-256.txt.asc \ - && sha256sum --ignore-missing --check cmake-SHA-256.txt \ - && tar -xzvf ${CMAKE_TARBALL} --directory=/opt/ \ - && ln -sfn /opt/cmake-${CMAKE_VERSION}-Linux-x86_64/bin/* /usr/bin \ - && rm -f ${CMAKE_TARBALL} cmake-SHA-256.txt cmake-SHA-256.txt.asc - -RUN pip3 install wheel - -WORKDIR /root - -RUN python3 --version && cmake --version && env - -ENTRYPOINT ["/bin/bash", "-l", "-c"] \ No newline at end of file diff --git a/Pipfile b/Pipfile index 9883d99..ba5d01c 100644 --- a/Pipfile +++ b/Pipfile @@ -14,7 +14,7 @@ report_html = "coverage html" report_xml = "coverage xml" format = "autopep8 --aggressive --aggressive -ir setup.py cfd tests" format_detail = "autopep8 --aggressive --aggressive -ivr setup.py cfd tests" -format_check = "autopep8 -d -r setup.py src" +format_check = "autopep8 -d -r setup.py cfd" lint = "flake8 --show-source setup.py cfd tests" cleanup = "python ./tools/cleanup.py cmake_build" build = "python ./setup.py build" diff --git a/README.md b/README.md index d5444a2..d149716 100644 --- a/README.md +++ b/README.md @@ -133,10 +133,10 @@ pip install --user . ### install from wheel -1. get releases asset. (ex. https://github.com/p2pderivatives/cfd-python/releases/download/v0.3.0/cfd-0.3.0-py3-none-win_amd64.whl ) +1. get releases asset. (ex. https://github.com/p2pderivatives/cfd-python/releases/download/v0.3.2/cfd-0.3.2-py3-none-win_amd64.whl ) 2. install pip ``` - pip install --user cfd-0.3.0-py3-none-win_amd64.whl + pip install --user cfd-0.3.2-py3-none-win_amd64.whl ``` ### uninstall diff --git a/VERSION b/VERSION index a2268e2..9fc80f9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.1 \ No newline at end of file +0.3.2 \ No newline at end of file diff --git a/cfd/__init__.py b/cfd/__init__.py index 782b73a..eb3cd38 100644 --- a/cfd/__init__.py +++ b/cfd/__init__.py @@ -1,7 +1,7 @@ import os import glob -__version__ = '0.1.0' +__version__ = '0.3.0' __all__ = [ os.path.split(os.path.splitext(file)[0])[1] @@ -10,6 +10,7 @@ ] """ 'address', +'block', 'confidential_address', 'confidential_transaction', 'crypto', diff --git a/cfd/address.py b/cfd/address.py index 19cfe60..e7e6165 100644 --- a/cfd/address.py +++ b/cfd/address.py @@ -7,7 +7,7 @@ from .util import get_util, CfdError, JobHandle, to_hex_string from .key import Network, Pubkey, SchnorrPubkey from .script import HashType, Script -from .taproot import TaprootScriptTree +from .taproot import TaprootScriptTree, TapBranch ## @@ -49,7 +49,8 @@ class Address: ## # @var taproot_script_tree # Taproot script tree. - taproot_script_tree: Optional['TaprootScriptTree'] = None + taproot_script_tree: Optional[Union['TaprootScriptTree', + 'TapBranch']] = None ## # @brief constructor. @@ -204,9 +205,11 @@ def p2sh_p2wsh(cls, redeem_script, network=Network.MAINNET) -> 'Address': # @return address object. @classmethod def taproot( - cls, pubkey: Union['SchnorrPubkey', 'TaprootScriptTree'], + cls, pubkey: Union[ + 'SchnorrPubkey', 'TaprootScriptTree'], network=Network.MAINNET, - script_tree: Optional['TaprootScriptTree'] = None) -> 'Address': + script_tree: Optional[Union[ + 'TaprootScriptTree', 'TapBranch']] = None) -> 'Address': if isinstance(pubkey, TaprootScriptTree): pk, _, _, _ = pubkey.get_taproot_data() addr = cls.from_pubkey_hash(pk, HashType.TAPROOT, network) @@ -217,6 +220,11 @@ def taproot( addr = cls.from_pubkey_hash(pk, HashType.TAPROOT, network) addr.taproot_script_tree = script_tree return addr + elif isinstance(script_tree, TapBranch): + pk, _, _, _ = script_tree.get_taproot_data(pubkey) + addr = cls.from_pubkey_hash(pk, HashType.TAPROOT, network) + addr.taproot_script_tree = script_tree + return addr else: return cls.from_pubkey_hash(pubkey, HashType.TAPROOT, network) @@ -426,6 +434,35 @@ def get_pegin_address( return cls.parse(addr), Script(claim_script), Script( tweaked_fedpeg) + ## + # @brief get pegout address. + # @param[in] descriptor output descriptor or xpub + # @param[in] bip32_counter bip32 counter + # @param[in] hash_type script hash type + # @param[in] mainchain_network mainchain network type + # @param[in] elements_network elements network type + # @retval [0] pegout address. + # @retval [1] base descriptor. + @classmethod + def get_pegout_address( + cls, + descriptor: str, + bip32_counter=0, + hash_type: Union['HashType', str] = HashType.P2PKH, + mainchain_network=Network.MAINNET, + elements_network=Network.LIQUID_V1, + ) -> Tuple['Address', str]: + _hash_type = HashType.get(hash_type) + _network = Network.get(mainchain_network) + _elements_network = Network.get(elements_network) + util = get_util() + with util.create_handle() as handle: + addr, base_descriptor = util.call_func( + 'CfdGetPegoutAddress', + handle.get_handle(), _network.value, _elements_network.value, + str(descriptor), int(bip32_counter), _hash_type.value) + return cls.parse(addr), base_descriptor + ## # All import target. diff --git a/cfd/block.py b/cfd/block.py new file mode 100644 index 0000000..7d687db --- /dev/null +++ b/cfd/block.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- +## +# @file block.py +# @brief bitcoin block function implements file. +# @note Copyright 2021 CryptoGarage +from typing import List, Tuple +from .key import Network +from .transaction import BlockHash, Txid, Transaction +from .util import CfdError, CfdErrorCode, ByteData, \ + to_hex_string, get_util, JobHandle + + +## +# @class BlockHeader +# @brief Block header data. +class BlockHeader: + ## + # @var version + # block version. + version: int + ## + # @var prev_block_hash + # previous block hash. + prev_block_hash: BlockHash + ## + # @var merkleroot + # block merkleroot. + merkleroot: BlockHash + ## + # @var time + # block time + time: int + ## + # @var bits + # block flags + bits: int + ## + # @var nonce + # block nonce + nonce: int + + ## + # @brief constructor. + # @param[in] version block version + # @param[in] prev_block_hash previous block hash + # @param[in] merkleroot block merkleroot + # @param[in] time block time + # @param[in] bits block bits + # @param[in] nonce block nonce + def __init__(self, version: int, prev_block_hash, merkleroot, + time: int, bits: int, nonce: int) -> None: + self.version = version + self.prev_block_hash = BlockHash(prev_block_hash) + self.merkleroot = BlockHash(merkleroot) + self.time = time + self.bits = bits + self.nonce = nonce + + +## +# @class Block +# @brief Block +class Block: + ## + # @var hex + # block hex + hex: str + ## + # @var hash + # block hash + hash: BlockHash + ## + # @var network + # network type + network: Network + + ## + # @brief constructor. + # @param[in] data block data + # @param[in] network network type + def __init__(self, data, network=Network.MAINNET): + self.network = Network.get(network) + self.hex = to_hex_string(data) + self.hash = self._get_blockhash() + + ## + # @brief get string. + # @return block hash hex. + def __str__(self) -> str: + return str(self.hash) + + ## + # @brief Get block hash. + # @return block hash + def get_blockhash(self) -> 'BlockHash': + return self.hash + + ## + # @brief Get block data. + # @return block data + def get_data(self) -> 'ByteData': + return ByteData(self.hex) + + ## + # @brief Get block header. + # @return block header + def get_header(self) -> 'BlockHeader': + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + ret = util.call_func( + 'CfdGetBlockHeaderData', handle.get_handle(), + block_handle.get_handle()) + return BlockHeader(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]) + + ## + # @brief Get transaction count in block. + # @return transaction count + def get_tx_count(self) -> int: + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + tx_count = util.call_func( + 'CfdGetTxCountInBlock', handle.get_handle(), + block_handle.get_handle()) + return tx_count + + ## + # @brief Exist transaction in block. + # @param[in] txid txid + # @retval True exist. + # @retval False not exist. + def exist_txid(self, txid) -> bool: + _txid = Txid(txid) + try: + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + util.call_func( + 'CfdExistTxidInBlock', handle.get_handle(), + block_handle.get_handle(), str(_txid)) + return True + except CfdError as err: + if err.error_code == CfdErrorCode.NOT_FOUND.value: + return False + else: + raise err + + ## + # @brief Get txid list. + # @return txid list + def get_txid_list(self) -> List['Txid']: + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + result = [] + tx_count = util.call_func( + 'CfdGetTxCountInBlock', handle.get_handle(), + block_handle.get_handle()) + for index in range(tx_count): + txid = util.call_func( + 'CfdGetTxidFromBlock', handle.get_handle(), + block_handle.get_handle(), index) + result.append(Txid(txid)) + return result + + ## + # @brief Get transaction from block. + # @param[in] txid txid + # @return transaction. + def get_transaction(self, txid) -> 'Transaction': + _txid = Txid(txid) + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + tx_hex = util.call_func( + 'CfdGetTransactionFromBlock', handle.get_handle(), + block_handle.get_handle(), str(_txid)) + return Transaction(tx_hex) + + ## + # @brief Get transaction data from block. + # @param[in] txid txid + # @retval [0] transaction. + # @retval [1] txoutproof. + def get_tx_data(self, txid) -> Tuple['Transaction', 'ByteData']: + _txid = Txid(txid) + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + tx_hex = util.call_func( + 'CfdGetTransactionFromBlock', handle.get_handle(), + block_handle.get_handle(), str(_txid)) + proof = util.call_func( + 'CfdGetTxOutProof', handle.get_handle(), + block_handle.get_handle(), str(_txid)) + return Transaction(tx_hex), ByteData(proof) + + ## + # @brief Get block hash. + # @return block hash + def _get_blockhash(self) -> 'BlockHash': + util = get_util() + with util.create_handle() as handle, self._get_handle( + util, handle, self.network, self.hex) as block_handle: + block_hash = util.call_func( + 'CfdGetBlockHash', handle.get_handle(), + block_handle.get_handle()) + return BlockHash(block_hash) + + ## + # @brief get block handle. + # @param[in] util cfd util object + # @param[in] handle cfd handle + # @param[in] network network type + # @param[in] block block hex + # @return block job handle + @classmethod + def _get_handle(cls, util, handle, network: 'Network', + block: str) -> 'JobHandle': + work_handle = util.call_func( + 'CfdInitializeBlockHandle', handle.get_handle(), + network.value, block) + return JobHandle(handle, work_handle, 'CfdFreeBlockHandle') + + +## +# All import target. +__all__ = [ + 'Block', + 'BlockHeader' +] diff --git a/cfd/confidential_transaction.py b/cfd/confidential_transaction.py index 924c6a4..2a37108 100644 --- a/cfd/confidential_transaction.py +++ b/cfd/confidential_transaction.py @@ -244,10 +244,11 @@ def get_commitment(self, asset_commitment, to_hex_string(blind_factor)) return ConfidentialValue(commitment) - ## # @class ElementsUtxoData # @brief elements utxo class. + + class ElementsUtxoData(UtxoData): ## # @var outpoint @@ -282,9 +283,13 @@ class ElementsUtxoData(UtxoData): # pegin btc transaction size pegin_btc_tx_size: int ## - # @var fedpeg_script - # fedpeg script - fedpeg_script: 'Script' + # @var pegin_txoutproof_size + # pegin txoutproof size + pegin_txoutproof_size: int + ## + # @var claim_script + # claim script + claim_script: 'Script' ## # @var asset_blinder # asset blind factor @@ -307,8 +312,9 @@ class ElementsUtxoData(UtxoData): # @param[in] is_issuance issuance flag # @param[in] is_blind_issuance blinded issuance flag # @param[in] is_pegin pegin flag + # @param[in] claim_script claim script # @param[in] pegin_btc_tx_size pegin btc tx size - # @param[in] fedpeg_script fedpeg script + # @param[in] pegin_txoutproof_size pegin txoutproof size # @param[in] asset_blinder asset blind factor # @param[in] amount_blinder amount blind factor def __init__( @@ -319,7 +325,8 @@ def __init__( value='', asset='', is_issuance: bool = False, is_blind_issuance: bool = False, is_pegin: bool = False, - pegin_btc_tx_size: int = 0, fedpeg_script='', + claim_script='', + pegin_btc_tx_size: int = 0, pegin_txoutproof_size: int = 0, asset_blinder='', amount_blinder=''): super().__init__( outpoint=outpoint, txid=txid, vout=vout, @@ -331,7 +338,8 @@ def __init__( self.is_blind_issuance = is_blind_issuance self.is_pegin = is_pegin self.pegin_btc_tx_size = int(pegin_btc_tx_size) - self.fedpeg_script = Script(fedpeg_script) + self.pegin_txoutproof_size = int(pegin_txoutproof_size) + self.claim_script = Script(claim_script) self.asset_blinder = BlindFactor.create(asset_blinder) self.amount_blinder = BlindFactor.create(amount_blinder) if self.amount == 0: @@ -405,6 +413,32 @@ class UnblindData: # amount blind factor amount_blinder: 'BlindFactor' + ## + # @brief unblind data. + # @param[in] blinding_key blinding key + # @param[in] locking_script locking script + # @param[in] asset_commitment asset commitment + # @param[in] value_commitment value commitment + # @param[in] commitment_nonce commitment nonce + # @param[in] rangeproof rangeproof + # @return unblind data + @classmethod + def unblind(cls, blinding_key, locking_script, asset_commitment, + value_commitment, commitment_nonce, + rangeproof) -> 'UnblindData': + _privkey = to_hex_string(blinding_key) + _script = to_hex_string(locking_script) + _asset = to_hex_string(asset_commitment) + _value = to_hex_string(value_commitment) + _nonce = to_hex_string(commitment_nonce) + _rangeproof = to_hex_string(rangeproof) + util = get_util() + with util.create_handle() as handle: + asset, amount, abf, vbf = util.call_func( + 'CfdUnblindTxOutData', handle.get_handle(), _privkey, + _script, _asset, _value, _nonce, _rangeproof) + return UnblindData(asset, amount, abf, vbf) + ## # @brief constructor. # @param[in] asset asset @@ -1384,6 +1418,42 @@ def get_split_handle(handle, tx_handle) -> 'JobHandle': tx_handle.get_handle()) self._update_tx_all() + ## + # @brief check pegout output. + # @param[in] index txout index + # @retval true pegout output + # @retval false other output + def has_pegout(self, index: int) -> bool: + try: + util = get_util() + with util.create_handle() as handle, self._get_handle( + handle, self.network) as tx_handle: + util.call_func( + 'CfdHasPegoutConfidentialTxOut', handle.get_handle(), + tx_handle.get_handle(), index) + return True + except CfdError as err: + if err.error_code == CfdErrorCode.NOT_FOUND.value: + return False + else: + raise err + + ## + # @brief get pegout address. + # @param[in] index txout index + # @param[in] mainchain_network mainchain network + # @return pegout address + def get_pegout_address(self, index: int, + mainchain_network=Network.MAINNET) -> 'Address': + _network = Network.get(mainchain_network) + util = get_util() + with util.create_handle() as handle, self._get_handle( + handle, self.network) as tx_handle: + addr = util.call_func( + 'CfdGetPegoutMainchainAddress', handle.get_handle(), + tx_handle.get_handle(), index, _network.value) + return AddressUtil.parse(addr) + ## # @brief blind transaction output. # @param[in] utxo_list utxo list @@ -1905,13 +1975,14 @@ def set_opt(handle, tx_handle, key, i_val=0, f_val=0, b_val=False): 'CfdFreeEstimateFeeHandle') as tx_handle: for utxo in utxo_list: util.call_func( - 'CfdAddTxInTemplateForEstimateFee', + 'CfdAddTxInputForEstimateFee', handle.get_handle(), tx_handle.get_handle(), str(utxo.outpoint.txid), utxo.outpoint.vout, str(utxo.descriptor), str(utxo.asset), utxo.is_issuance, utxo.is_blind_issuance, - utxo.is_pegin, int(utxo.pegin_btc_tx_size), - to_hex_string(utxo.fedpeg_script), + utxo.is_pegin, to_hex_string(utxo.claim_script), + int(utxo.pegin_btc_tx_size), + int(utxo.pegin_txoutproof_size), to_hex_string(utxo.scriptsig_template)) set_opt(handle, tx_handle, _FeeOpt.EXPONENT, i_val=exponent) @@ -1988,14 +2059,16 @@ def set_opt(handle, tx_handle, key, i_val=0, f_val=0, b_val=False): 'CfdFreeFundRawTxHandle') as tx_handle: for utxo in txin_utxo_list: util.call_func( - 'CfdAddTxInTemplateForFundRawTx', + 'CfdAddTxInputForFundRawTx', handle.get_handle(), tx_handle.get_handle(), str(utxo.outpoint.txid), utxo.outpoint.vout, utxo.amount, str(utxo.descriptor), str(utxo.asset), utxo.is_issuance, utxo.is_blind_issuance, - utxo.is_pegin, int(utxo.pegin_btc_tx_size), - to_hex_string(utxo.fedpeg_script), + utxo.is_pegin, + to_hex_string(utxo.claim_script), + int(utxo.pegin_btc_tx_size), + int(utxo.pegin_txoutproof_size), to_hex_string(utxo.scriptsig_template)) for utxo in utxo_list: util.call_func( diff --git a/cfd/hdwallet.py b/cfd/hdwallet.py index ba8f3f4..fdd2006 100644 --- a/cfd/hdwallet.py +++ b/cfd/hdwallet.py @@ -139,26 +139,22 @@ def _get_information(self, extkey): _extkey = str(extkey) with self.util.create_handle() as handle: result = self.util.call_func( - 'CfdGetExtkeyInformation', handle.get_handle(), _extkey) + 'CfdGetExtkeyInfo', handle.get_handle(), _extkey) self.version, _fingerprint, _chain_code, self.depth, \ - self.child_number = result + self.child_number, key_type, network_type = result self.fingerprint = ByteData(_fingerprint) self.chain_code = ByteData(_chain_code) self.extkey = _extkey if self.extkey_type == ExtKeyType.EXT_PRIVKEY: - main, test, name = XPRIV_MAINNET_VERSION,\ - XPRIV_TESTNET_VERSION, 'privkey' - else: - main, test, name = XPUB_MAINNET_VERSION,\ - XPUB_TESTNET_VERSION, 'pubkey' - if self.version == main: - self.network = Network.MAINNET - elif self.version == test: - self.network = Network.TESTNET + name = 'privkey' else: + name = 'pubkey' + if self.extkey_type.value != key_type: raise CfdError( error_code=1, message='Error: Invalid ext {}.'.format(name)) + pass + self.network = Network.get(network_type) ## # @brief get extkey information. diff --git a/cfd/taproot.py b/cfd/taproot.py index d8a51b0..4b91694 100644 --- a/cfd/taproot.py +++ b/cfd/taproot.py @@ -97,16 +97,16 @@ def __init__(self, hash: Union['ByteData', str] = '', self.taget_node_str = '' self.tree_str = '' self.leaf_version = leaf_version - if tree_str or self.tapscript or self.hash.hex: - if tree_str: - temp_tree_str = tree_str - elif self.tapscript and self.tapscript.hex: - temp_tree_str = f'tl({self.tapscript.hex})' - elif self.hash.hex: - temp_tree_str = self.hash.hex - else: - temp_tree_str = '' - self._load(temp_tree_str) + + if tree_str: + temp_tree_str = tree_str + elif self.tapscript and self.tapscript.hex: + temp_tree_str = f'tl({self.tapscript.hex})' + elif self.hash.hex: + temp_tree_str = self.hash.hex + else: + temp_tree_str = '' + self._load(temp_tree_str) ## # @brief get string. @@ -233,6 +233,66 @@ def get_branch_hash(self, index: int) -> 'ByteData': tree_handle.get_handle(), index, True) return ByteData(hash) + ## + # @brief get taproot data. + # @param[in] internal_pubkey internal pubkey + # @retval [0] taproot schnorr pubkey. (for address) + # @retval [1] tapleaf hash. (for sighash) + # @retval [2] tapscript. + # @retval [3] control block. (for witness stack) + def get_taproot_data( + self, internal_pubkey: 'SchnorrPubkey', + ) -> Tuple['SchnorrPubkey', 'ByteData', 'Script', 'ByteData']: + return self._get_taproot_data(internal_pubkey, self.tapscript) + + ## + # @brief get taproot data. + # @param[in] internal_pubkey internal pubkey + # @param[in] tapscript tapscript + # @retval [0] taproot schnorr pubkey. (for address) + # @retval [1] tapleaf hash. (for sighash) + # @retval [2] tapscript. + # @retval [3] control block. (for witness stack) + def _get_taproot_data( + self, internal_pubkey: 'SchnorrPubkey', + tapscript: Optional['Script'] = None, + ) -> Tuple['SchnorrPubkey', 'ByteData', 'Script', 'ByteData']: + if not internal_pubkey: + raise CfdError(CfdErrorCode.ILLEGAL_STATE, + 'internal pubkey not found.') + _script = tapscript if isinstance(tapscript, Script) else Script('') + util = get_util() + with util.create_handle() as handle, TapBranch._get_handle( + util, handle) as tree_handle: + util.call_func( + 'CfdSetScriptTreeFromString', handle.get_handle(), + tree_handle.get_handle(), self.tree_str, + to_hex_string(_script), self.leaf_version, + self.taget_node_str) + hash, tapleaf_hash, control_block = util.call_func( + 'CfdGetTaprootScriptTreeHash', handle.get_handle(), + tree_handle.get_handle(), to_hex_string(internal_pubkey)) + return SchnorrPubkey(hash), ByteData(tapleaf_hash), \ + _script, ByteData(control_block) + + ## + # @brief get tweaked privkey. + # @param[in] internal_privkey internal privkey + # @return privkey. + def get_privkey(self, internal_privkey: 'Privkey') -> 'Privkey': + util = get_util() + with util.create_handle() as handle, TapBranch._get_handle( + util, handle) as tree_handle: + tapscript = self.tapscript.hex if self.tapscript else '' + util.call_func( + 'CfdSetScriptTreeFromString', handle.get_handle(), + tree_handle.get_handle(), self.tree_str, + tapscript, self.leaf_version, self.taget_node_str) + tweaked_privkey = util.call_func( + 'CfdGetTaprootTweakedPrivkey', handle.get_handle(), + tree_handle.get_handle(), to_hex_string(internal_privkey)) + return Privkey(hex=tweaked_privkey) + ## # @brief load tree info. # @param[in] tree_str tree string @@ -257,7 +317,7 @@ def _load(self, tree_str: str) -> None: 'CfdSetInitialTapBranchByHash', handle.get_handle(), tree_handle.get_handle(), self.hash.hex) else: - return # do nothing + pass # empty branch self.leaf_version, script, hash = util.call_func( 'CfdGetBaseTapLeaf', handle.get_handle(), tree_handle.get_handle()) @@ -406,14 +466,14 @@ def from_control_block( return result ## - # @brief get script tree from string. + # @brief get script tree from string and key. # @param[in] tree_str tree string. # @param[in] tapscript tapscript # @param[in] target_nodes target tapbranch hash list. # @param[in] internal_pubkey internal pubkey # @return script tree object @classmethod - def from_string( + def from_string_and_key( cls, tree_str: str, tapscript: 'Script', target_nodes: List[Union['ByteData', str]] = [], internal_pubkey: Optional['SchnorrPubkey'] = None, @@ -481,39 +541,9 @@ def get_taproot_data( if not pk: raise CfdError(CfdErrorCode.ILLEGAL_STATE, 'internal pubkey not found.') - util = get_util() - with util.create_handle() as handle, TapBranch._get_handle( - util, handle) as tree_handle: - if not self.tapscript: - raise CfdError(CfdErrorCode.ILLEGAL_STATE, - 'tapscript not found.') - util.call_func( - 'CfdSetScriptTreeFromString', handle.get_handle(), - tree_handle.get_handle(), self.tree_str, - self.tapscript.hex, self.leaf_version, self.taget_node_str) - hash, tapleaf_hash, control_block = util.call_func( - 'CfdGetTaprootScriptTreeHash', handle.get_handle(), - tree_handle.get_handle(), to_hex_string(pk)) - return SchnorrPubkey(hash), ByteData(tapleaf_hash), \ - self.tapscript, ByteData(control_block) - - ## - # @brief get tweaked privkey. - # @param[in] internal_privkey internal privkey - # @return privkey. - def get_privkey(self, internal_privkey: 'Privkey') -> 'Privkey': - util = get_util() - with util.create_handle() as handle, TapBranch._get_handle( - util, handle) as tree_handle: - tapscript = self.tapscript.hex if self.tapscript else '' - util.call_func( - 'CfdSetScriptTreeFromString', handle.get_handle(), - tree_handle.get_handle(), self.tree_str, - tapscript, self.leaf_version, self.taget_node_str) - tweaked_privkey = util.call_func( - 'CfdGetTaprootTweakedPrivkey', handle.get_handle(), - tree_handle.get_handle(), to_hex_string(internal_privkey)) - return Privkey(hex=tweaked_privkey) + if not self.tapscript: + raise CfdError(CfdErrorCode.ILLEGAL_STATE, 'tapscript not found.') + return super()._get_taproot_data(pk, self.tapscript) ## diff --git a/cfd/transaction.py b/cfd/transaction.py index 57379a2..8353456 100644 --- a/cfd/transaction.py +++ b/cfd/transaction.py @@ -42,9 +42,9 @@ def __init__(self, txid): class BlockHash(ReverseByteData): ## # @brief constructor. - # @param[in] txid txid - def __init__(self, txid): - super().__init__(txid) + # @param[in] hash block hash + def __init__(self, hash): + super().__init__(hash) if len(self.hex) != 64: raise CfdError( error_code=1, message='Error: Invalid block hash.') @@ -499,6 +499,25 @@ def get_txout_indexes(self, address='', locking_script='') -> List[int]: raise err return list + ## + # @brief update witness stack. + # @param[in] outpoint outpoint + # @param[in] sequence sequence number + # @return void + def update_sequence( + self, outpoint: 'OutPoint', sequence: int) -> None: + util = get_util() + with util.create_handle() as handle, self._get_handle( + handle, self.network) as tx_handle: + self.hex = util.call_func( + 'CfdUpdateTxInSequence', handle.get_handle(), + tx_handle.get_handle(), str(outpoint.txid), + outpoint.vout, sequence) + self.hex = util.call_func( + 'CfdFinalizeTransaction', handle.get_handle(), + tx_handle.get_handle()) + self._update_txin_internal(handle, tx_handle, outpoint) + ## # @brief update witness stack. # @param[in] outpoint outpoint @@ -1444,11 +1463,11 @@ def estimate_fee(self, utxo_list: List['UtxoData'], fee_rate: float = 20.0, 'CfdFreeEstimateFeeHandle') as tx_handle: for utxo in utxo_list: util.call_func( - 'CfdAddTxInTemplateForEstimateFee', + 'CfdAddTxInputForEstimateFee', handle.get_handle(), tx_handle.get_handle(), str(utxo.outpoint.txid), utxo.outpoint.vout, str(utxo.descriptor), '', False, False, False, - 0, '', to_hex_string(utxo.scriptsig_template)) + '', 0, 0, to_hex_string(utxo.scriptsig_template)) _txout_fee = ctypes.c_int64() _utxo_fee = ctypes.c_int64() @@ -1506,11 +1525,11 @@ def set_opt(handle, tx_handle, key, i_val=0, f_val=0, b_val=False): 'CfdFreeFundRawTxHandle') as tx_handle: for utxo in txin_utxo_list: util.call_func( - 'CfdAddTxInTemplateForFundRawTx', + 'CfdAddTxInputForFundRawTx', handle.get_handle(), tx_handle.get_handle(), str(utxo.outpoint.txid), utxo.outpoint.vout, utxo.amount, str(utxo.descriptor), - '', False, False, False, 0, '', + '', False, False, False, '', 0, 0, to_hex_string(utxo.scriptsig_template)) for utxo in utxo_list: util.call_func( diff --git a/cfd/util.py b/cfd/util.py index 62e7080..406babb 100644 --- a/cfd/util.py +++ b/cfd/util.py @@ -112,6 +112,8 @@ def __init__(self, data) -> None: self.hex = data.hex() elif isinstance(data, list): self.hex = ''.join("%02x" % b for b in data) + elif data is None: + self.hex = '' else: self.hex = str(data).lower() bytes.fromhex(self.hex) # check hex @@ -437,6 +439,15 @@ class CfdUtil: ("CfdFreeAddressesMultisigHandle", c_int, [c_void_p, c_void_p]), # noqa: E501 ("CfdGetAddressFromLockingScript", c_int, [c_void_p, c_char_p, c_int, c_char_p_p]), # noqa: E501 ("CfdGetAddressInfo", c_int, [c_void_p, c_char_p, c_int_p, c_int_p, c_int_p, c_char_p_p, c_char_p_p]), # noqa: E501 + ("CfdInitializeBlockHandle", c_int, [c_void_p, c_int, c_char_p, c_void_p_p]), # noqa: E501 + ("CfdFreeBlockHandle", c_int, [c_void_p, c_void_p]), # noqa: E501 + ("CfdGetBlockHash", c_int, [c_void_p, c_void_p, c_char_p_p]), # noqa: E501 + ("CfdGetBlockHeaderData", c_int, [c_void_p, c_void_p, c_uint32_p, c_char_p_p, c_char_p_p, c_uint32_p, c_uint32_p, c_uint32_p]), # noqa: E501 + ("CfdGetTransactionFromBlock", c_int, [c_void_p, c_void_p, c_char_p, c_char_p_p]), # noqa: E501 + ("CfdGetTxOutProof", c_int, [c_void_p, c_void_p, c_char_p, c_char_p_p]), # noqa: E501 + ("CfdExistTxidInBlock", c_int, [c_void_p, c_void_p, c_char_p]), # noqa: E501 + ("CfdGetTxCountInBlock", c_int, [c_void_p, c_void_p, c_uint32_p]), # noqa: E501 + ("CfdGetTxidFromBlock", c_int, [c_void_p, c_void_p, c_uint32, c_char_p_p]), # noqa: E501 ("CfdInitializeCoinSelection", c_int, [c_void_p, c_uint32, c_uint32, c_char_p, c_int64, c_double, c_double, c_double, c_int64, c_void_p_p]), # noqa: E501 ("CfdAddCoinSelectionUtxo", c_int, [c_void_p, c_void_p, c_int32, c_char_p, c_uint32, c_int64, c_char_p, c_char_p]), # noqa: E501 ("CfdAddCoinSelectionUtxoTemplate", c_int, [c_void_p, c_void_p, c_int32, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_char_p]), # noqa: E501 @@ -449,6 +460,7 @@ class CfdUtil: ("CfdInitializeEstimateFee", c_int, [c_void_p, c_void_p_p, c_bool]), # noqa: E501 ("CfdAddTxInForEstimateFee", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint32, c_char_p]), # noqa: E501 ("CfdAddTxInTemplateForEstimateFee", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint32, c_char_p, c_char_p]), # noqa: E501 + ("CfdAddTxInputForEstimateFee", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_char_p, c_uint32, c_uint32, c_char_p]), # noqa: E501 ("CfdSetOptionEstimateFee", c_int, [c_void_p, c_void_p, c_int, c_int64, c_double, c_bool]), # noqa: E501 ("CfdFinalizeEstimateFee", c_int, [c_void_p, c_void_p, c_char_p, c_char_p, c_int64_p, c_int64_p, c_bool, c_double]), # noqa: E501 ("CfdFreeEstimateFeeHandle", c_int, [c_void_p, c_void_p]), # noqa: E501 @@ -479,6 +491,7 @@ class CfdUtil: ("CfdCreateConfidentialAddress", c_int, [c_void_p, c_char_p, c_char_p, c_char_p_p]), # noqa: E501 ("CfdParseConfidentialAddress", c_int, [c_void_p, c_char_p, c_char_p_p, c_char_p_p, c_int_p]), # noqa: E501 ("CfdGetPeginAddress", c_int, [c_void_p, c_int, c_char_p, c_int, c_char_p, c_char_p, c_char_p_p, c_char_p_p, c_char_p_p]), # noqa: E501 + ("CfdGetPegoutAddress", c_int, [c_void_p, c_int, c_int, c_char_p, c_uint32, c_int, c_char_p_p, c_char_p_p]), # noqa: E501 ("CfdInitializeConfidentialTx", c_int, [c_void_p, c_uint32, c_uint32, c_char_p_p]), # noqa: E501 ("CfdAddConfidentialTxIn", c_int, [c_void_p, c_char_p, c_char_p, c_uint32, c_uint32, c_char_p_p]), # noqa: E501 ("CfdAddConfidentialTxOut", c_int, [c_void_p, c_char_p, c_char_p, c_int64, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p_p]), # noqa: E501 @@ -496,6 +509,8 @@ class CfdUtil: ("CfdGetConfidentialTxInIndex", c_int, [c_void_p, c_char_p, c_char_p, c_uint32, c_uint32_p]), # noqa: E501 ("CfdGetConfidentialTxOutIndex", c_int, [c_void_p, c_char_p, c_char_p, c_char_p, c_uint32_p]), # noqa: E501 ("CfdGetConfidentialTxInfoByHandle", c_int, [c_void_p, c_void_p, c_char_p_p, c_char_p_p, c_char_p_p, c_uint32_p, c_uint32_p, c_uint32_p, c_uint32_p, c_uint32_p]), # noqa: E501 + ("CfdHasPegoutConfidentialTxOut", c_int, [c_void_p, c_void_p, c_uint32]), # noqa: E501 + ("CfdGetPegoutMainchainAddress", c_int, [c_void_p, c_void_p, c_uint32, c_int, c_char_p_p]), # noqa: E501 ("CfdGetTxInIssuanceInfoByHandle", c_int, [c_void_p, c_void_p, c_uint32, c_char_p_p, c_char_p_p, c_int64_p, c_char_p_p, c_int64_p, c_char_p_p, c_char_p_p, c_char_p_p]), # noqa: E501 ("CfdGetConfidentialTxOutSimpleByHandle", c_int, [c_void_p, c_void_p, c_uint32, c_char_p_p, c_int64_p, c_char_p_p, c_char_p_p, c_char_p_p]), # noqa: E501 ("CfdGetConfidentialTxOutByHandle", c_int, [c_void_p, c_void_p, c_uint32, c_char_p_p, c_int64_p, c_char_p_p, c_char_p_p, c_char_p_p, c_char_p_p, c_char_p_p]), # noqa: E501 @@ -527,6 +542,7 @@ class CfdUtil: ("CfdSetReissueAsset", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p_p]), # noqa: E501 ("CfdAddTxPeginInput", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]), # noqa: E501 ("CfdAddTxPegoutOutput", c_int, [c_void_p, c_void_p, c_char_p, c_int64, c_int, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_uint32, c_char_p, c_char_p_p]), # noqa: E501 + ("CfdUnblindTxOutData", c_int, [c_void_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p_p, c_int64_p, c_char_p_p, c_char_p_p]), # noqa: E501 ("CfdCalculateEcSignature", c_int, [c_void_p, c_char_p, c_char_p, c_char_p, c_int, c_bool, c_char_p_p]), # noqa: E501 ("CfdVerifyEcSignature", c_int, [c_void_p, c_char_p, c_char_p, c_char_p]), # noqa: E501 ("CfdSignEcdsaAdaptor", c_int, [c_void_p, c_char_p, c_char_p, c_char_p, c_char_p_p, c_char_p_p]), # noqa: E501 @@ -575,6 +591,7 @@ class CfdUtil: ("CfdGetPubkeyFromExtkey", c_int, [c_void_p, c_char_p, c_int, c_char_p_p]), # noqa: E501 ("CfdGetParentExtkeyPathData", c_int, [c_void_p, c_char_p, c_char_p, c_int, c_char_p_p, c_char_p_p]), # noqa: E501 ("CfdGetExtkeyInformation", c_int, [c_void_p, c_char_p, c_char_p_p, c_char_p_p, c_char_p_p, c_uint32_p, c_uint32_p]), # noqa: E501 + ("CfdGetExtkeyInfo", c_int, [c_void_p, c_char_p, c_char_p_p, c_char_p_p, c_char_p_p, c_uint32_p, c_uint32_p, c_int_p, c_int_p]), # noqa: E501 ("CfdInitializeMnemonicWordList", c_int, [c_void_p, c_char_p, c_void_p_p, c_uint32_p]), # noqa: E501 ("CfdGetMnemonicWord", c_int, [c_void_p, c_void_p, c_uint32, c_char_p_p]), # noqa: E501 ("CfdFreeMnemonicWordList", c_int, [c_void_p, c_void_p]), # noqa: E501 @@ -666,6 +683,7 @@ class CfdUtil: ("CfdUpdateWitnessStack", c_int, [c_void_p, c_void_p, c_int, c_char_p, c_uint32, c_uint32, c_char_p]), # noqa: E501 ("CfdClearWitnessStack", c_int, [c_void_p, c_void_p, c_char_p, c_uint32]), # noqa: E501 ("CfdUpdateTxInScriptSig", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_char_p]), # noqa: E501 + ("CfdUpdateTxInSequence", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_uint32]), # noqa: E501 ("CfdSetTransactionUtxoData", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_bool]), # noqa: E501 ("CfdCreateSighashByHandle", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int, c_bool, c_char_p, c_char_p, c_char_p, c_uint32, c_char_p, c_char_p_p]), # noqa: E501 ("CfdAddSignWithPrivkeyByHandle", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_char_p, c_int, c_bool, c_bool, c_char_p, c_char_p]), # noqa: E501 @@ -717,6 +735,7 @@ class CfdUtil: ("CfdInitializeFundRawTx", c_int, [c_void_p, c_int, c_uint32, c_char_p, c_void_p_p]), # noqa: E501 ("CfdAddTxInForFundRawTx", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint32, c_char_p]), # noqa: E501 ("CfdAddTxInTemplateForFundRawTx", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint32, c_char_p, c_char_p]), # noqa: E501 + ("CfdAddTxInputForFundRawTx", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_bool, c_bool, c_bool, c_char_p, c_uint32, c_uint32, c_char_p]), # noqa: E501 ("CfdAddUtxoForFundRawTx", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p]), # noqa: E501 ("CfdAddUtxoTemplateForFundRawTx", c_int, [c_void_p, c_void_p, c_char_p, c_uint32, c_int64, c_char_p, c_char_p, c_char_p]), # noqa: E501 ("CfdAddTargetAmountForFundRawTx", c_int, [c_void_p, c_void_p, c_uint32, c_int64, c_char_p, c_char_p]), # noqa: E501 diff --git a/docker-compose.yml b/docker-compose.yml index 7d79456..a0b4c68 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,11 +2,7 @@ version: '3.5' services: cfd-py-build: - container_name: 'cfd-python-builder' - build: - context: . - dockerfile: Dockerfile - target: cfdPythonBuilder + image: ghcr.io/cryptogarageinc/elements-testing:v0.1.0 environment: CFD_SRC: /private/cfd-python CFD_WORK: /private/work/cfd-python @@ -14,4 +10,24 @@ services: volumes: - /private/work - .:/private/cfd-python - entrypoint: /private/cfd-python/tools/build_for_docker.sh + working_dir: /private/cfd-python + command: /bin/bash -c "./tools/build_for_docker.sh" + + cfd-py-integration-test: + image: ghcr.io/ko-matsu/elements-testing:v0.0.5 + volumes: + - ./integration_test:/root/integration_test + working_dir: /root/integration_test + entrypoint: /bin/bash -c "./test_entrypoint.sh" + + cfd-py-test: + image: ghcr.io/cryptogarageinc/elements-testing:v0.1.0 + environment: + CFD_SRC: /private/cfd-python + CFD_WORK: /private/work/cfd-python + working_dir: /private/cfd-python + volumes: + - /private/work + - .:/private/cfd-python + working_dir: /private/cfd-python + command: /bin/bash -c "./tools/build_and_test_for_docker.sh" diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index d239ebd..3e9169f 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -43,7 +43,7 @@ if(CFD_TARGET_VERSION) set(CFD_TARGET_TAG ${CFD_TARGET_VERSION}) message(STATUS "[external project local] cfd target=${CFD_TARGET_VERSION}") else() -set(CFD_TARGET_TAG v0.3.1) +set(CFD_TARGET_TAG v0.3.2) endif() if(CFD_TARGET_URL) set(CFD_TARGET_REP ${CFD_TARGET_URL}) diff --git a/integration_test/Dockerfile b/integration_test/Dockerfile deleted file mode 100644 index 917c15b..0000000 --- a/integration_test/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM cryptogarageinc/elements-testing:v0.18.1.7 - -ENV PATH /usr/local/bin:$PATH -ENV LANG C.UTF-8 - -RUN apt update && apt install -y \ - python3 \ - python3-dev \ - python3-pip \ - && rm -rf /var/lib/apt/lists/* - -RUN bitcoin-cli --version && elements-cli --version diff --git a/integration_test/docker-compose.yml b/integration_test/docker-compose.yml deleted file mode 100644 index d2b3143..0000000 --- a/integration_test/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: '3.5' - -services: - cfd-python-test: - build: - context: . - dockerfile: Dockerfile - volumes: - - ./test_entrypoint.sh:/root/test_entrypoint.sh - - .:/root/integration_test - entrypoint: "sh -c \"/root/test_entrypoint.sh\"" \ No newline at end of file diff --git a/integration_test/test_entrypoint.sh b/integration_test/test_entrypoint.sh index a90e8a9..4651830 100755 --- a/integration_test/test_entrypoint.sh +++ b/integration_test/test_entrypoint.sh @@ -40,6 +40,9 @@ do done echo "start elements node" +# load or create wallet +bitcoin-cli --regtest -datadir=${WORKDIR_PATH}/bitcoind_datadir createwallet wallet + set -e python3 --version diff --git a/integration_test/tests/test_bitcoin.py b/integration_test/tests/test_bitcoin.py index 1ec35e8..537ca3c 100644 --- a/integration_test/tests/test_bitcoin.py +++ b/integration_test/tests/test_bitcoin.py @@ -1,15 +1,15 @@ -from cfd.taproot import TaprootScriptTree import unittest from helper import RpcWrapper, get_utxo -from cfd.address import AddressUtil, Address +from cfd.address import AddressUtil from cfd.key import SchnorrUtil, SigHashType, SchnorrPubkey, SignParameter from cfd.hdwallet import HDWallet from cfd.script import HashType, Script -from cfd.descriptor import parse_descriptor, Descriptor +from cfd.descriptor import parse_descriptor from cfd.psbt import Psbt, PsbtAppendInputData, PsbtAppendOutputData +from cfd.taproot import TaprootScriptTree, TapBranch from cfd.transaction import OutPoint, Transaction, TxIn, TxOut, UtxoData from decimal import Decimal -from typing import List, Union +from typing import List import logging import time @@ -721,6 +721,208 @@ def test_taproot_tapscript(test_obj: 'TestBitcoin'): print('UTXO: {}'.format(utxos)) +def test_taproot_single_key(test_obj: 'TestBitcoin'): + btc_rpc = test_obj.conn.get_rpc() + main_addr = test_obj.addr_dic['main'] + main_pk, _ = SchnorrPubkey.from_pubkey(str(main_addr.pubkey)) + pkh_addr = test_obj.addr_dic['p2pkh'] + spk1, _ = SchnorrPubkey.from_pubkey(str(pkh_addr.pubkey)) + wpkh_addr = test_obj.addr_dic['p2wpkh'] + spk2, _ = SchnorrPubkey.from_pubkey(str(wpkh_addr.pubkey)) + main_path = str(test_obj.path_dic[str(main_addr)]) + main_sk = test_obj.hdwallet.get_privkey(path=main_path).privkey + pkh_path = str(test_obj.path_dic[str(pkh_addr)]) + sk1 = test_obj.hdwallet.get_privkey(path=pkh_path).privkey + wpkh_path = str(test_obj.path_dic[str(wpkh_addr)]) + sk2 = test_obj.hdwallet.get_privkey(path=wpkh_path).privkey + + branch = TapBranch() + tr_addr1 = AddressUtil.taproot( + main_pk, script_tree=branch, network=NETWORK) + tr_sk1 = branch.get_privkey(main_sk) + tr_addr2 = AddressUtil.taproot(spk1, script_tree=branch, network=NETWORK) + tr_sk2 = branch.get_privkey(sk1) + tr_addr3 = AddressUtil.taproot(spk2, script_tree=branch, network=NETWORK) + tr_sk3 = branch.get_privkey(sk2) + + txouts = [ + TxOut(100000, str(tr_addr1)), + TxOut(150000, str(tr_addr2)), + TxOut(200000, str(tr_addr3)), + ] + tx = Transaction.create(2, 0, [], txouts) + # fundrawtransaction + fee_addr = str(test_obj.addr_dic['fee']) + fee_desc = test_obj.desc_dic[fee_addr] + fee_sk = test_obj.hdwallet.get_privkey(path=FEE_PATH).privkey + utxos = get_utxo(btc_rpc, [fee_addr]) + utxo_list = convert_bitcoin_utxos(test_obj, utxos) + tx.fund_raw_transaction([], utxo_list, fee_addr, + target_amount=0, effective_fee_rate=2.0, + knapsack_min_change=0) + # add sign + for txin in tx.txin_list: + utxo = search_utxos(test_obj, utxo_list, txin.outpoint) + tx.sign_with_privkey(txin.outpoint, fee_desc.data.hash_type, fee_sk, + amount=utxo.amount, + sighashtype=SigHashType.ALL) + # broadcast + print(Transaction.parse_to_json(str(tx), network=NETWORK)) + btc_rpc.sendrawtransaction(str(tx)) + # generate block + btc_rpc.generatetoaddress(2, fee_addr) + time.sleep(2) + + txid = tx.txid + utxo1 = UtxoData(txid=txid, vout=0, amount=txouts[0].amount, + descriptor=f'raw({str(tr_addr1.locking_script)})') + utxo2 = UtxoData(txid=txid, vout=1, amount=txouts[1].amount, + descriptor=f'raw({str(tr_addr2.locking_script)})') + utxo3 = UtxoData(txid=txid, vout=2, amount=txouts[2].amount, + descriptor=f'raw({str(tr_addr3.locking_script)})') + + # send taproot singleKey1 + txin_list = [] + txin_utxo_list = [] + txin_list.append(TxIn(txid=txid, vout=0)) + txin_utxo_list.append(utxo1) + txouts2 = [ + TxOut(txouts[0].amount, str(test_obj.addr_dic['main'])), + ] + tx2 = Transaction.create(2, 0, txin_list, txouts2) + main_addr = test_obj.addr_dic['main'] + utxos = get_utxo(btc_rpc, [fee_addr]) + utxo_list = convert_bitcoin_utxos(test_obj, utxos) + tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, + target_amount=0, effective_fee_rate=2.0, + knapsack_min_change=0) + # add sign + join_utxo_list: List['UtxoData'] = [] + join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list + for txin in tx2.txin_list: + for utxo in utxo_list: + if utxo.outpoint == txin.outpoint: + join_utxo_list.append(utxo) + for index, txin in enumerate(tx2.txin_list): + utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) + if index == 0: + sighash = tx2.get_sighash( + txin.outpoint, HashType.TAPROOT, pubkey=tr_addr1.pubkey, + sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) + sig = SchnorrUtil.sign(sighash, tr_sk1) + sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) + tx2.add_taproot_sign(txin.outpoint, sign_param) + else: + path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) + sk = test_obj.hdwallet.get_privkey(path=path).privkey + hash_type = utxo.descriptor.data.hash_type + tx2.sign_with_privkey(txin.outpoint, hash_type, + sk, amount=utxo.amount, + sighashtype=SigHashType.ALL, + utxos=join_utxo_list) + # broadcast + print(Transaction.parse_to_json(str(tx2), network=NETWORK)) + btc_rpc.sendrawtransaction(str(tx2)) + # generate block + btc_rpc.generatetoaddress(2, fee_addr) + time.sleep(2) + + # send taproot singleKey2 + txin_list = [] + txin_utxo_list = [] + txin_list.append(TxIn(txid=txid, vout=1)) + txin_utxo_list.append(utxo2) + txouts2 = [ + TxOut(txouts[1].amount, str(test_obj.addr_dic['main'])), + ] + tx2 = Transaction.create(2, 0, txin_list, txouts2) + main_addr = test_obj.addr_dic['main'] + utxos = get_utxo(btc_rpc, [fee_addr]) + utxo_list = convert_bitcoin_utxos(test_obj, utxos) + tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, + target_amount=0, effective_fee_rate=2.0, + knapsack_min_change=0) + # add sign + join_utxo_list = [] + join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list + for txin in tx2.txin_list: + for utxo in utxo_list: + if utxo.outpoint == txin.outpoint: + join_utxo_list.append(utxo) + for index, txin in enumerate(tx2.txin_list): + utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) + if index == 0: + sighash = tx2.get_sighash( + txin.outpoint, HashType.TAPROOT, pubkey=tr_addr2.pubkey, + sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) + sig = SchnorrUtil.sign(sighash, tr_sk2) + sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) + tx2.add_taproot_sign(txin.outpoint, sign_param) + else: + path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) + sk = test_obj.hdwallet.get_privkey(path=path).privkey + hash_type = utxo.descriptor.data.hash_type + tx2.sign_with_privkey(txin.outpoint, hash_type, + sk, amount=utxo.amount, + sighashtype=SigHashType.ALL, + utxos=join_utxo_list) + # broadcast + print(Transaction.parse_to_json(str(tx2), network=NETWORK)) + btc_rpc.sendrawtransaction(str(tx2)) + # generate block + btc_rpc.generatetoaddress(2, fee_addr) + time.sleep(2) + + # send taproot singleKey3 + txin_list = [] + txin_utxo_list = [] + txin_list.append(TxIn(txid=txid, vout=2)) + txin_utxo_list.append(utxo3) + txouts2 = [ + TxOut(txouts[2].amount, str(test_obj.addr_dic['main'])), + ] + tx2 = Transaction.create(2, 0, txin_list, txouts2) + main_addr = test_obj.addr_dic['main'] + utxos = get_utxo(btc_rpc, [fee_addr]) + utxo_list = convert_bitcoin_utxos(test_obj, utxos) + tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, + target_amount=0, effective_fee_rate=2.0, + knapsack_min_change=0) + # add sign + join_utxo_list = [] + join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list + for txin in tx2.txin_list: + for utxo in utxo_list: + if utxo.outpoint == txin.outpoint: + join_utxo_list.append(utxo) + for index, txin in enumerate(tx2.txin_list): + utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) + if index == 0: + sighash = tx2.get_sighash( + txin.outpoint, HashType.TAPROOT, pubkey=tr_addr3.pubkey, + sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) + sig = SchnorrUtil.sign(sighash, tr_sk3) + sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) + tx2.add_taproot_sign(txin.outpoint, sign_param) + else: + path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) + sk = test_obj.hdwallet.get_privkey(path=path).privkey + hash_type = utxo.descriptor.data.hash_type + tx2.sign_with_privkey(txin.outpoint, hash_type, + sk, amount=utxo.amount, + sighashtype=SigHashType.ALL, + utxos=join_utxo_list) + # broadcast + print(Transaction.parse_to_json(str(tx2), network=NETWORK)) + btc_rpc.sendrawtransaction(str(tx2)) + # generate block + btc_rpc.generatetoaddress(2, fee_addr) + time.sleep(2) + + utxos = get_utxo(btc_rpc, [str(main_addr)]) + print('UTXO: {}'.format(utxos)) + + class TestBitcoin(unittest.TestCase): hdwallet: 'HDWallet' # addr_dic: dict[str, 'Address'] @@ -753,6 +955,7 @@ def test_bitcoin(self): test_psbt(self) test_taproot_schnorr(self) test_taproot_tapscript(self) + test_taproot_single_key(self) if __name__ == "__main__": diff --git a/integration_test/tests/test_elements.py b/integration_test/tests/test_elements.py index 1dddf2a..2ea20c7 100644 --- a/integration_test/tests/test_elements.py +++ b/integration_test/tests/test_elements.py @@ -2,6 +2,7 @@ from helper import RpcWrapper, get_utxo from cfd.address import AddressUtil from cfd.key import SigHashType, Network +from cfd.block import Block from cfd.hdwallet import HDWallet from cfd.script import HashType from cfd.descriptor import parse_descriptor @@ -272,13 +273,14 @@ def get_elements_config(test_obj): test_obj.sidechaininfo['pegin_confirmation_depth'] -def create_pegin_tx(test_obj, btc_tx, pegin_address, +def create_pegin_tx(test_obj, btc_tx: 'Transaction', pegin_address, txout_proof, claim_script) -> str: - btc_tx_obj = Transaction.from_hex(btc_tx) + btc_tx_obj = btc_tx btc_txid = btc_tx_obj.txid btc_txout_index = btc_tx_obj.get_txout_index(address=pegin_address) btc_amount = btc_tx_obj.txout_list[btc_txout_index].amount - btc_size = len(btc_tx) / 2 + btc_size = len(str(btc_tx)) / 2 + txoutproof_size = len(str(txout_proof)) / 2 # add txout tx = ConfidentialTransaction.create(2, 0) @@ -307,9 +309,13 @@ def create_pegin_tx(test_obj, btc_tx, pegin_address, descriptor='wpkh({})'.format('02' * 33), # dummy asset=test_obj.pegged_asset, is_pegin=True, pegin_btc_tx_size=int(btc_size), - fedpeg_script=test_obj.fedpegscript) + pegin_txoutproof_size=int(txoutproof_size), + claim_script=claim_script) utxo_list = [pegin_utxo] - calc_fee, _, _ = tx.estimate_fee(utxo_list, test_obj.pegged_asset) + minimum_bits = 52 + calc_fee, _, _ = tx.estimate_fee( + utxo_list, test_obj.pegged_asset, fee_rate=0.1, + minimum_bits=minimum_bits) # update fee tx.update_txout_fee_amount(calc_fee) @@ -319,17 +325,19 @@ def create_pegin_tx(test_obj, btc_tx, pegin_address, # blind print('before blind tx=', str(tx)) - tx.blind_txout(utxo_list) + tx.blind_txout(utxo_list, minimum_bits=minimum_bits) return str(tx) -def update_pegin_tx(test_obj, pegin_tx, btc_tx, pegin_address) -> str: +def update_pegin_tx(test_obj, pegin_tx, btc_tx, pegin_address, + claim_script, txout_proof) -> str: pegin_tx2 = pegin_tx btc_tx_obj = Transaction.from_hex(btc_tx) btc_txid = btc_tx_obj.txid btc_txout_index = btc_tx_obj.get_txout_index(address=pegin_address) btc_amount = btc_tx_obj.txout_list[btc_txout_index].amount btc_size = len(btc_tx) / 2 + txoutproof_size = len(txout_proof) / 2 # decode tx = ConfidentialTransaction.from_hex(pegin_tx) @@ -371,7 +379,8 @@ def update_pegin_tx(test_obj, pegin_tx, btc_tx, pegin_address) -> str: descriptor='wpkh({})'.format('02' * 33), # dummy asset=test_obj.pegged_asset, is_pegin=True, pegin_btc_tx_size=int(btc_size), - fedpeg_script=test_obj.fedpegscript) + pegin_txoutproof_size=int(txoutproof_size), + claim_script=claim_script) utxo_list = [pegin_utxo] if utxo_amount > 0: for txin in tx.txin_list: @@ -431,6 +440,7 @@ def test_pegin(test_obj): for i in range(3): try: + blk_cnt = btc_rpc.getblockcount() + 1 # send bitcoin utxos = get_utxo(btc_rpc, []) amount = 0 @@ -444,18 +454,32 @@ def test_pegin(test_obj): # generate bitcoin 100 block addr = str(test_obj.addr_dic['btc']) btc_rpc.generatetoaddress(101, addr) + max_blk_cnt = btc_rpc.getblockcount() + + txout_proof = None + for i in range(max_blk_cnt - blk_cnt): + blk_hash = btc_rpc.getblockhash(blk_cnt + i) + block_hex = btc_rpc.getblock(blk_hash, 0) + block = Block(block_hex) + if block.exist_txid(txid): + tx_data, txout_proof = block.get_tx_data(txid) + print(f'pegin block: {str(block)}') + break + + if txout_proof is None: + raise Exception('txoutproof is empty.') # pegin transaction for fee address - tx_data = btc_rpc.gettransaction(txid)['hex'] + # tx_data = btc_rpc.gettransaction(txid)['hex'] tx = Transaction(tx_data) vout = tx.get_txout_index(pegin_address) pegged_amount = tx.txout_list[vout].amount - txout_proof = btc_rpc.gettxoutproof([txid]) + # txout_proof = btc_rpc.gettxoutproof([txid]) # pegin_tx = elm_rpc.createrawpegin( # tx_data, txout_proof, claim_script)['hex'] # pegin_tx = update_pegin_tx( - # test_obj, pegin_tx, tx_data, pegin_address) - pegin_tx = create_pegin_tx(test_obj, tx_data, pegin_address, + # test_obj, pegin_tx, tx_data, pegin_address, txout_proof) + pegin_tx = create_pegin_tx(test_obj, tx, pegin_address, txout_proof, claim_script) ct = ConfidentialTransaction(pegin_tx) ct.sign_with_privkey( diff --git a/setup.cfg b/setup.cfg index a760311..670acaf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,7 +4,7 @@ version = file:VERSION description = Crypto Finance Development Kit for Python author = Crypto Garage license = MIT -license-file = LICENSE +license_file = LICENSE url = https://github.com/p2pderivatives/cfd-python classifiers = Development Status :: 5 - Production/Stable @@ -23,8 +23,8 @@ keywords = Bitcoin, cfd, libwally, secp256k1 project_urls = Source Code = https://github.com/p2pderivatives/cfd-python Bug Tracker = https://github.com/p2pderivatives/cfd-python/issues -requires-dist = setuptools -long-description = file:README.md +requires_dist = setuptools +long_description = file:README.md long_description_content_type = text/markdown; charset=UTF-8 [options] diff --git a/tests/data/address_test.json b/tests/data/address_test.json index edd1e36..faef9ca 100644 --- a/tests/data/address_test.json +++ b/tests/data/address_test.json @@ -2357,7 +2357,7 @@ { "case": "get privkey. network(testnet)", "request": { - "network": "mainnet", + "network": "testnet", "isElements": false, "internalPubkey": "1777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb", "internalPrivkey": "305e293b010d29bf3c888b617763a438fee9054c8cab66eb12ad078f819d9f27", @@ -2378,7 +2378,7 @@ "topBranchHash": "09659d67a7a6fb82c1e382fd8f99f6bb43cbd80883845c6df7029f9589fc7af3", "tweakedPubkey": "3dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", "tweakedPrivkey": "a7d17bee0b6313cf864a1ac6f203aafd74a40703ffc050f66517e4f83ff41a03", - "address": "bc1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqw77n40", + "address": "tb1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqekgu0q", "lockingScript": "51203dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", "controlBlock": "c01777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6ddc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54", "tapscript": "201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac", @@ -2389,6 +2389,34 @@ "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,tl(201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac)},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}" } }, + { + "case": "get privkey by hash only tree.", + "request": { + "network": "mainnet", + "isElements": false, + "internalPubkey": "1777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb", + "internalPrivkey": "305e293b010d29bf3c888b617763a438fee9054c8cab66eb12ad078f819d9f27", + "tree": [ + { + "branchHash": "dfc43ba9fc5f8a9e1b6d6a50600c704bb9e41b741d9ed6de6559a53d2f38e513" + }, + { + "branchHash": "4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d" + }, + { + "branchHash": "dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54" + } + ] + }, + "expect": { + "topBranchHash": "09659d67a7a6fb82c1e382fd8f99f6bb43cbd80883845c6df7029f9589fc7af3", + "tweakedPubkey": "3dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", + "tweakedPrivkey": "a7d17bee0b6313cf864a1ac6f203aafd74a40703ffc050f66517e4f83ff41a03", + "address": "bc1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqw77n40", + "lockingScript": "51203dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", + "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,dfc43ba9fc5f8a9e1b6d6a50600c704bb9e41b741d9ed6de6559a53d2f38e513},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}" + } + }, { "case": "child branch.", "request": { @@ -2540,7 +2568,7 @@ { "case": "get privkey. network(testnet)", "request": { - "network": "mainnet", + "network": "testnet", "isElements": false, "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,tl(201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac)},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}", "tapscript": "201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac", @@ -2552,7 +2580,7 @@ "topBranchHash": "09659d67a7a6fb82c1e382fd8f99f6bb43cbd80883845c6df7029f9589fc7af3", "tweakedPubkey": "3dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", "tweakedPrivkey": "a7d17bee0b6313cf864a1ac6f203aafd74a40703ffc050f66517e4f83ff41a03", - "address": "bc1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqw77n40", + "address": "tb1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqekgu0q", "lockingScript": "51203dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", "controlBlock": "c01777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6ddc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54", "tapscript": "201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac", @@ -2563,6 +2591,24 @@ "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,tl(201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac)},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}" } }, + { + "case": "get privkey on hash only tree. network(mainnet)", + "request": { + "network": "mainnet", + "isElements": false, + "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,dfc43ba9fc5f8a9e1b6d6a50600c704bb9e41b741d9ed6de6559a53d2f38e513},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}", + "internalPubkey": "1777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb", + "internalPrivkey": "305e293b010d29bf3c888b617763a438fee9054c8cab66eb12ad078f819d9f27" + }, + "expect": { + "topBranchHash": "09659d67a7a6fb82c1e382fd8f99f6bb43cbd80883845c6df7029f9589fc7af3", + "tweakedPubkey": "3dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", + "tweakedPrivkey": "a7d17bee0b6313cf864a1ac6f203aafd74a40703ffc050f66517e4f83ff41a03", + "address": "bc1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqw77n40", + "lockingScript": "51203dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", + "treeString": "{{4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d,dfc43ba9fc5f8a9e1b6d6a50600c704bb9e41b741d9ed6de6559a53d2f38e513},dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54}" + } + }, { "case": "child branch.", "request": { @@ -2766,6 +2812,18 @@ "nodes": [], "treeString": "tl(2057bf643684f6c5c75e1cdf45990036502a0d897394013210858cdabcbb95a05aad205bec1a08fa3443176edd0a08e2a64642f45e57543b62bffe43ec350edc33dc22ac)" } + }, + { + "case": "by tapbranch only hash", + "request": { + "treeString": "{{4691fbb1196f4675241c8958a7ab6378a63aa0cc008ed03d216fd038357f52fd,a85b2107f791b26a84e7586c28cec7cb61202ed3d01944d832500f363782d675},e47f58011f27e9046b8195d0ab6a2acbc68ce281437a8d5132dadf389b2a5ebb}", + "index": 1 + }, + "expect": { + "topBranchHash": "e47f58011f27e9046b8195d0ab6a2acbc68ce281437a8d5132dadf389b2a5ebb", + "nodes": [], + "treeString": "e47f58011f27e9046b8195d0ab6a2acbc68ce281437a8d5132dadf389b2a5ebb" + } } ] }, @@ -2931,7 +2989,7 @@ } }, { - "case": "hash only branch", + "case": "hash branch", "request": { "treeString": "{{tl(20ac52f50b28cdd4d3bcb7f0d5cb533f232e4c4ef12fbf3e718420b84d4e3c3440ac),tl(51)},e47f58011f27e9046b8195d0ab6a2acbc68ce281437a8d5132dadf389b2a5ebb}" }, diff --git a/tests/data/block_test.json b/tests/data/block_test.json new file mode 100644 index 0000000..05254ae --- /dev/null +++ b/tests/data/block_test.json @@ -0,0 +1,200 @@ +[ + { + "name": "Block.GetBlockInfo", + "cases": [ + { + "case": "coinbase", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false + }, + "expect": { + "blockHash": "53fd7b794cf751a148b2be637df6c7daf663f1be509cb35294bd69400fdc694e", + "tx": [ + "c5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe" + ], + "version": 805306368, + "versionHex": "30000000", + "previousblockhash": "2dae5f1ec784d5812cd1f56dd57f6bed8a5c004a0ded66164d81ad9b94587995", + "merkleroot": "c5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe", + "time": 1613123137, + "bits": 545259519, + "nonce": 0 + } + }, + { + "case": "many transaction", + "request": { + "block": "00000020d987e1f7cc030f4272beda5a081f8f8969f044ef72a3b2c2e544afc8230b9642d8b5de43b746fa65aaab7cfa0b521b41e4eb0d7c0e2fb834380259df581daf03157eb360ffff7f200100000015020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050277020101ffffffff02246aa01200000000160014aef2e2877c45ada6b9eaef2bdb9131630ae12dca0000000000000000266a24aa21a9ed2af9d1c54b61988d37ce9bcde367fba7f3c5910cecaf8be1b6b443e937e39cec0120000000000000000000000000000000000000000000000000000000000000000000000000020000000001013d067178968e8e7469a61a82c365508ee3615bed93ed421ddefe19da412171080000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014a9b62806472c7b70c9f753bf41573e1506534dc40247304402205de2d7b0acf8e6027fcb1e197745ca8d23c1a4a7f4dc449762265e2aab2022f202204d35e5866f31595616b44f77e218fbddbfed702b830eb4c2aac087c5c1ad0648012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019421ca1de8781f070262511333197ab44f1629dbb704bd923f48bae4fa67a9f90000000000feffffff0213373f250000000016001455d6fbae5d95d2b03e5210abbe5a15ddbdb62c47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402206f590ce48f6f7a93821c116c3a4a9659d9739d8a9bc62fcae12e34cf0e4b26500220361867ad6dcd30af0bec09a9571a8888452d2812275201f4878de296a78e8627012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e4212da7a883762b80efdf512263fd8d412771515b8b81cf992c01314fc93210000000000feffffff0213373f2500000000160014563423d5881cddbb72a1d6fea1af5c56bbea6a3fa0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220185d48c45b2e83f56249bfda4e2f0e1a211165c3c1175bd358cc7e4024e4764202201835811415ee2e5efbf42445b0113f54ae87b99e77e59252a69960759fdd8cf7012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d46302000002000000000101f0d8cef892eb52f81ac0e86bce4df8eeb9d0c1336cb62a069626c173e65321f80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014e53cad733f173a80f1402d16123321535454048e0247304402207bbea0204f17fb98370ada2158666b4554d1354409efbd326835413041cd24410220323a16ee7b50f298446db61cd197cc44dd27fd90d45adb1a4fd780574300be7b012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101106a9ee2f6bbc4e58cbff2b1c99a53cdddec1a153f8a699350c00969500097210000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014f0321c988998afdb2b8788ce862402110792be8c0247304402207f6e3931036bb80b127b3d25ecf92bf5507cf057ec5af7c3a70b37e0c74575eb02205da9e647d92c86b2e17533050edd95e7eb887981e6145ade05728e0447a357bf012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101ea826992d745371bd6d762692369b94b2ac047df92d8b83cf9f46f6c9dbb13450000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014008e9141e1a0fd29384d41585598d2d1dc90ad380247304402202aeae79aa171eb28d21ee22fff4b58794d77e1ceda4c0bdd02fe87b4b6260c17022067184229e67f0ac2729e30206700fb50f0691e248690b6b103788552ebfb8b37012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001011723ce44d3f606a6fbd3de7e5204ad22f6b48154e19e0e37fdb547c84e57bdfe0000000000feffffff0213373f2500000000160014b30e6003f0a61a3c594678af24bfe170894c15cca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402202876093a9dec94f9ce1fb3b7c487a8cf38b09a9f3e438c2a1e56d2ff8e2287df02204bba8b7936cccad0302d4f0e39da4b27779a2e8a5ba5a506fe00907544224633012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001016de1c5853fd550cb2fdd67f25b32496bb182404e2f127b5e82e48c587622eabc0000000000feffffff0213373f250000000016001496864cef7241cc0c24e8914f4ec75e34da0a70a6a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402207dde78431c3e5ede2a90af0b3e3d32fadb5712e5ec04e3fac2dc6137d747187902202fc5603f63ce4498ad9062ed35b37ca5fc9a19fc90a9ef40ddec55b30820862c012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001013e22c22ad4afedfac4642f54ebc1fb93f94f3af1c7cedd78fb17242975e00e650000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001485fe6084fcec5323e4647ccb6781f2975ce78a690247304402202d4676c01c0f5f39d98f3e0435101c283baff3f2168bb20fccc99ef514abc77c02205703439a4ca4c289f9ab36e31ba88b81d5503ad705a30b036b628e505ef2b07f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e637219b2c53a395f6b61b85ff720e7380161b31473556d470878ccc9077fe80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014d9a72d531686342f1f81a447f9643d22ec7bd0ab02473044022010df9caa2ae04bf2b04cce039d859e8fe9f04add799ce02ce4f5848a48eebb9802204e11ae33d32a7c99af8dcc85797b5dc0b7a864c5f9848be41604740fac2bdb89012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010124c74f712076cb581a3ee4ae502e094487139ca3da724edb9c0acfd905bd8d340000000000feffffff0213373f250000000016001465eab055d88f1ac853fe1f790740ce24c8623e4ea0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022053373da5b4b0583d7ef8e743b0fad5688d5a81c82dd33fb6a614a0cf7234431a0220192e5802c1bf8d2e05bca416e3e42b1fb7947169333c40a33bfda2bf1170237d012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010145df9bc5da442ff71110c0872dc58939138aba50f2e12bdf13ef7e75ab2f893c0000000000feffffff0213373f250000000016001427880ac035c111a8e8f71e4ae6a5bb4df79518c4a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402200a13fd5ae3a2dd9bb210316fea853cc8ad9ada202a58c91f53c61a0741b63833022012a15e4bb30938b31da9606d03e2692e12ce87afe816df19ca20934dfadb7641012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010140b280318583b4e346fab2a2a126201799ddaffa169d3ac375b9434b3937a0750000000000feffffff0213373f2500000000160014e11569e65a6a7bbe75ca0322070eb0745201b99ca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220655e813dcd37ee11f44d82eddc1540225866e3cc730b768c6c5f9b80cd1c447502200e538e03ed2a3c4f5da9396e884890556e42bf5d25ae49eb1b6c8a0101096fb0012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001012fb0c024a0ae79e6217dc8889c6af40853b2b230a0e9f79d765c8b5525e0e2320000000000feffffff0213373f25000000001600147f44238db9775e0e738fb949724a7ffb66f4ac47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022032778f2c844abedb675ef947bdc7a11271800b5a11c98be5c0c9fdc6b2037f7302206acf28de27d327dc5a9d93998edad27f7509aa8479a1a2be1cb28f0eee28bf6a012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101892c26005096da187a5de107320c08a02e458be0184af915edbacaf5ad898c160000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001460524bb60b4dc68abe9ba195376d572dd6cc20fa0247304402206b43d3fcceff2ee92380f6e112b99907b94df56c9ed2ab7df4fa750fd5010ed70220526807188cb56ff1944e19db3910b06d944c8772a76fd91b83cca791c740da14012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010128877cbe42170fca382e506d745a333a1e1eed9ed5c3597cf904cd441f7fef050000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001462bf5d506758c4075c1484ed199c12b1d070dcc9024730440220514defa364f4cf78355fb64a79f0be487a0515f2c383cca2c7572b862f389b8b022040fb39e0cef457968c22c7a778b3225bf6d95e661c6bfaeea40dc6c9ae7fd9d5012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019b34c725b2b7de36389cec07b79109d482dab48e1641c2ba143fe1e0ab80f86d0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001437586a889710f537d70d511e41f45ade16ae96b80247304402205e1560130977bf5584e1938c34daa77e3dd0393eff6cfb18fa3d485a622a9f1d02200d55678c7c274442b0aa99d0a047094051b125ff74e8582be20d52dbb1825889012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001017883189114213697b8adc8069c8bafc80d9972c9fc1949a478c57bde58daacbb0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600144b69012485912f125d6121323d1b2c55e24b3a8f0247304402203bf784686661951078c64dce1410677127d92015d018a1233a9be6351f26ad2302203b6287e552aed0abcf8740cc464d5843dbd3712e58b33dfa2be6947ba88e7b8f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010180143a2ecddd4d3b32eb7c1e6378a054a2a02b278811a5ffbddf4db4e17f0ad70000000000feffffff0213373f2500000000160014fe956a004e01b6cbe82bf6a351f9370a60917abba0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220769b4f0bc75725b686fcc131af5b31722eeb0e7835bdeb812e16982183045d66022070a2f04e7619e75a9abd62170a1dbffceb11e398119c559bdb66cf49d91d7b43012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101f33b3ce193ef8a4450c6b4db2184538c0e5c5c5406e549478d8afe10b3d7e1760000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600147235fdc337715c994998751dbfb0f3a38e87594e02473044022071323b810bed75c508337a442268503d70ac598f8db2fd0af57fb7ff6b913450022075157811bc930b2a7e2dc2cf5d6b075ca99e3e81bef2992111e43b8aebe9a0ac012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d434020000", + "isElements": false + }, + "expect": { + "blockHash": "0ae1754425645e84cf354366150db602bd1ca38a5b64b6d7949ffc7f5480ab41", + "tx": [ + "7f5fb624f5cdce391362aa6befea307c4e778e008e799b40ca7119046f26ab31", + "b4bcb584d0ee9c1e687c69ad0497b2686f7d47529affc0f1df8210b2a074c40c", + "7af0cb6d0a0ded748790daa5e20b079e30cc82d90a267cad982328ed11409c17", + "8d0b1863957eaa5b9c82a07c4e8b78801e496a8af4ed11450186fb1e7bdbfa29", + "b42e9550b5129b34152950843ca09b0674a51ef4d273688366b216db7da16442", + "d4ebf5a67e891b059c6aa67dd06c0ac3e129bf959919e2077c6519d6d460b347", + "5edd72b9fef5225167c11862063c8cd955e648e01470b9784693d3868eaadf49", + "d6f11f1fa8efb17911c1918ec1f2964d20b6bd5ddcefc60acc751094344f2b5e", + "cb3f209415bd73c709740fa0742ba960679cf22e86f691d11eb08e4a85cef95f", + "f4be3e47478145959d2d0978bf1900db2521be4d4f2964b277c35b754133bc7d", + "9c9a3d9783dd9ac6c14c0ee487fa94f2e53053a7c96d10c37f0289edcdeb2b7e", + "a5ab7f31660deb709d4ab2a70f4ce16a7cb02a16b03e843a39aba43115d3217f", + "dc11069c2643ff09717a290e7dc0e38863316ec68b24fbb7d47d4e670f74777f", + "4b244572aaec7a7b92431f7371b42547aca705b7ede430081be6374e8a672282", + "4ae603bfb1689c29b1e5feb2cbd2f1ebb950df3ed4b25b6ad98f2f56da8cac93", + "18b54774739e59b7bb0ec6a7196000c0f8fe42b441502636bdb5adde40f9e8a8", + "587b9d5224a54fb3427cd99dc276b8acab4d4322c1b5681408d74a2927cd62ac", + "98bdb3d84051b02a8bb147bb34d2e34c5b32339aebcccff696429c04538a45df", + "695eddd38e01b5f67f93d3dcbdca033e1d8fd3feaefbdbcc2a2bd1326a6b7be4", + "2bc841beb4de23e39e9674f96afc7a8b3c6db60c6d3c645c06a747eeb5135ae8", + "be37763a766b5aa48d31a44a2c34ff1355e55e7f0efae58de9594d4eae3ca8ed" + ], + "version": 536870912, + "versionHex": "20000000", + "previousblockhash": "42960b23c8af44e5c2b2a372ef44f069898f1f085adabe72420f03ccf7e187d9", + "merkleroot": "03af1d58df59023834b82f0e7c0debe4411b520bfa7cabaa65fa46b743deb5d8", + "time": 1622375957, + "bits": 545259519, + "nonce": 1 + } + }, + { + "case": "Error(invalid hex format)", + "request": { + "block": "00000030957958949bad814", + "isElements": false + }, + "error": { + "code": 1, + "type": "illegal_argument", + "message": "hex to byte convert error.", + "python": "Error: Invalid hex value." + } + } + ] + }, + { + "name": "Block.GetTxDataFromBlock", + "cases": [ + { + "case": "coinbase", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false, + "txid": "c5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe" + }, + "expect": { + "tx": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "txoutproof": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f20000000000100000001fe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec50101" + } + }, + { + "case": "get single tx", + "request": { + "block": "00000020d987e1f7cc030f4272beda5a081f8f8969f044ef72a3b2c2e544afc8230b9642d8b5de43b746fa65aaab7cfa0b521b41e4eb0d7c0e2fb834380259df581daf03157eb360ffff7f200100000015020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050277020101ffffffff02246aa01200000000160014aef2e2877c45ada6b9eaef2bdb9131630ae12dca0000000000000000266a24aa21a9ed2af9d1c54b61988d37ce9bcde367fba7f3c5910cecaf8be1b6b443e937e39cec0120000000000000000000000000000000000000000000000000000000000000000000000000020000000001013d067178968e8e7469a61a82c365508ee3615bed93ed421ddefe19da412171080000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014a9b62806472c7b70c9f753bf41573e1506534dc40247304402205de2d7b0acf8e6027fcb1e197745ca8d23c1a4a7f4dc449762265e2aab2022f202204d35e5866f31595616b44f77e218fbddbfed702b830eb4c2aac087c5c1ad0648012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019421ca1de8781f070262511333197ab44f1629dbb704bd923f48bae4fa67a9f90000000000feffffff0213373f250000000016001455d6fbae5d95d2b03e5210abbe5a15ddbdb62c47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402206f590ce48f6f7a93821c116c3a4a9659d9739d8a9bc62fcae12e34cf0e4b26500220361867ad6dcd30af0bec09a9571a8888452d2812275201f4878de296a78e8627012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e4212da7a883762b80efdf512263fd8d412771515b8b81cf992c01314fc93210000000000feffffff0213373f2500000000160014563423d5881cddbb72a1d6fea1af5c56bbea6a3fa0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220185d48c45b2e83f56249bfda4e2f0e1a211165c3c1175bd358cc7e4024e4764202201835811415ee2e5efbf42445b0113f54ae87b99e77e59252a69960759fdd8cf7012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d46302000002000000000101f0d8cef892eb52f81ac0e86bce4df8eeb9d0c1336cb62a069626c173e65321f80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014e53cad733f173a80f1402d16123321535454048e0247304402207bbea0204f17fb98370ada2158666b4554d1354409efbd326835413041cd24410220323a16ee7b50f298446db61cd197cc44dd27fd90d45adb1a4fd780574300be7b012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101106a9ee2f6bbc4e58cbff2b1c99a53cdddec1a153f8a699350c00969500097210000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014f0321c988998afdb2b8788ce862402110792be8c0247304402207f6e3931036bb80b127b3d25ecf92bf5507cf057ec5af7c3a70b37e0c74575eb02205da9e647d92c86b2e17533050edd95e7eb887981e6145ade05728e0447a357bf012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101ea826992d745371bd6d762692369b94b2ac047df92d8b83cf9f46f6c9dbb13450000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014008e9141e1a0fd29384d41585598d2d1dc90ad380247304402202aeae79aa171eb28d21ee22fff4b58794d77e1ceda4c0bdd02fe87b4b6260c17022067184229e67f0ac2729e30206700fb50f0691e248690b6b103788552ebfb8b37012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001011723ce44d3f606a6fbd3de7e5204ad22f6b48154e19e0e37fdb547c84e57bdfe0000000000feffffff0213373f2500000000160014b30e6003f0a61a3c594678af24bfe170894c15cca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402202876093a9dec94f9ce1fb3b7c487a8cf38b09a9f3e438c2a1e56d2ff8e2287df02204bba8b7936cccad0302d4f0e39da4b27779a2e8a5ba5a506fe00907544224633012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001016de1c5853fd550cb2fdd67f25b32496bb182404e2f127b5e82e48c587622eabc0000000000feffffff0213373f250000000016001496864cef7241cc0c24e8914f4ec75e34da0a70a6a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402207dde78431c3e5ede2a90af0b3e3d32fadb5712e5ec04e3fac2dc6137d747187902202fc5603f63ce4498ad9062ed35b37ca5fc9a19fc90a9ef40ddec55b30820862c012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001013e22c22ad4afedfac4642f54ebc1fb93f94f3af1c7cedd78fb17242975e00e650000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001485fe6084fcec5323e4647ccb6781f2975ce78a690247304402202d4676c01c0f5f39d98f3e0435101c283baff3f2168bb20fccc99ef514abc77c02205703439a4ca4c289f9ab36e31ba88b81d5503ad705a30b036b628e505ef2b07f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e637219b2c53a395f6b61b85ff720e7380161b31473556d470878ccc9077fe80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014d9a72d531686342f1f81a447f9643d22ec7bd0ab02473044022010df9caa2ae04bf2b04cce039d859e8fe9f04add799ce02ce4f5848a48eebb9802204e11ae33d32a7c99af8dcc85797b5dc0b7a864c5f9848be41604740fac2bdb89012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010124c74f712076cb581a3ee4ae502e094487139ca3da724edb9c0acfd905bd8d340000000000feffffff0213373f250000000016001465eab055d88f1ac853fe1f790740ce24c8623e4ea0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022053373da5b4b0583d7ef8e743b0fad5688d5a81c82dd33fb6a614a0cf7234431a0220192e5802c1bf8d2e05bca416e3e42b1fb7947169333c40a33bfda2bf1170237d012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010145df9bc5da442ff71110c0872dc58939138aba50f2e12bdf13ef7e75ab2f893c0000000000feffffff0213373f250000000016001427880ac035c111a8e8f71e4ae6a5bb4df79518c4a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402200a13fd5ae3a2dd9bb210316fea853cc8ad9ada202a58c91f53c61a0741b63833022012a15e4bb30938b31da9606d03e2692e12ce87afe816df19ca20934dfadb7641012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010140b280318583b4e346fab2a2a126201799ddaffa169d3ac375b9434b3937a0750000000000feffffff0213373f2500000000160014e11569e65a6a7bbe75ca0322070eb0745201b99ca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220655e813dcd37ee11f44d82eddc1540225866e3cc730b768c6c5f9b80cd1c447502200e538e03ed2a3c4f5da9396e884890556e42bf5d25ae49eb1b6c8a0101096fb0012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001012fb0c024a0ae79e6217dc8889c6af40853b2b230a0e9f79d765c8b5525e0e2320000000000feffffff0213373f25000000001600147f44238db9775e0e738fb949724a7ffb66f4ac47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022032778f2c844abedb675ef947bdc7a11271800b5a11c98be5c0c9fdc6b2037f7302206acf28de27d327dc5a9d93998edad27f7509aa8479a1a2be1cb28f0eee28bf6a012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101892c26005096da187a5de107320c08a02e458be0184af915edbacaf5ad898c160000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001460524bb60b4dc68abe9ba195376d572dd6cc20fa0247304402206b43d3fcceff2ee92380f6e112b99907b94df56c9ed2ab7df4fa750fd5010ed70220526807188cb56ff1944e19db3910b06d944c8772a76fd91b83cca791c740da14012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010128877cbe42170fca382e506d745a333a1e1eed9ed5c3597cf904cd441f7fef050000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001462bf5d506758c4075c1484ed199c12b1d070dcc9024730440220514defa364f4cf78355fb64a79f0be487a0515f2c383cca2c7572b862f389b8b022040fb39e0cef457968c22c7a778b3225bf6d95e661c6bfaeea40dc6c9ae7fd9d5012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019b34c725b2b7de36389cec07b79109d482dab48e1641c2ba143fe1e0ab80f86d0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001437586a889710f537d70d511e41f45ade16ae96b80247304402205e1560130977bf5584e1938c34daa77e3dd0393eff6cfb18fa3d485a622a9f1d02200d55678c7c274442b0aa99d0a047094051b125ff74e8582be20d52dbb1825889012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001017883189114213697b8adc8069c8bafc80d9972c9fc1949a478c57bde58daacbb0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600144b69012485912f125d6121323d1b2c55e24b3a8f0247304402203bf784686661951078c64dce1410677127d92015d018a1233a9be6351f26ad2302203b6287e552aed0abcf8740cc464d5843dbd3712e58b33dfa2be6947ba88e7b8f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010180143a2ecddd4d3b32eb7c1e6378a054a2a02b278811a5ffbddf4db4e17f0ad70000000000feffffff0213373f2500000000160014fe956a004e01b6cbe82bf6a351f9370a60917abba0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220769b4f0bc75725b686fcc131af5b31722eeb0e7835bdeb812e16982183045d66022070a2f04e7619e75a9abd62170a1dbffceb11e398119c559bdb66cf49d91d7b43012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101f33b3ce193ef8a4450c6b4db2184538c0e5c5c5406e549478d8afe10b3d7e1760000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600147235fdc337715c994998751dbfb0f3a38e87594e02473044022071323b810bed75c508337a442268503d70ac598f8db2fd0af57fb7ff6b913450022075157811bc930b2a7e2dc2cf5d6b075ca99e3e81bef2992111e43b8aebe9a0ac012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d434020000", + "isElements": false, + "txid": "cb3f209415bd73c709740fa0742ba960679cf22e86f691d11eb08e4a85cef95f" + }, + "expect": { + "tx": "020000000001016de1c5853fd550cb2fdd67f25b32496bb182404e2f127b5e82e48c587622eabc0000000000feffffff0213373f250000000016001496864cef7241cc0c24e8914f4ec75e34da0a70a6a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402207dde78431c3e5ede2a90af0b3e3d32fadb5712e5ec04e3fac2dc6137d747187902202fc5603f63ce4498ad9062ed35b37ca5fc9a19fc90a9ef40ddec55b30820862c012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000", + "txoutproof": "00000020d987e1f7cc030f4272beda5a081f8f8969f044ef72a3b2c2e544afc8230b9642d8b5de43b746fa65aaab7cfa0b521b41e4eb0d7c0e2fb834380259df581daf03157eb360ffff7f20010000001500000006774b1a7f9e060f94a1c7bd9d8109e233014e4e74a09a5b85a42add1837c18de15ff9ce854a8eb01ed191f6862ef29c6760a92b74a00f7409c773bd1594203fcb7dbc3341755bc377b264294f4dbe2125db0019bf78092d9d95458147473ebef40b484381159b8168441d718d2855f98b076d7f319e08fc129fc6684a10364d6cab62141fa7cf9455e1db2b83d9746dcb4151f71cbde29b8074d9c280cf2329858c705d27704a43f47e3a3066b9253a3d7380cb20874e67178450d2ab376f06ee027b00" + } + }, + { + "case": "Error(unknown txid)", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false, + "txid": "d5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe" + }, + "error": { + "code": 1, + "type": "illegal_argument", + "message": "target txid not found." + } + } + ] + }, + { + "name": "Block.ExistTxid", + "cases": [ + { + "case": "coinbase", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false, + "txid": "c5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe" + }, + "expect": { + "exist": true + }, + "exclude": [ + "js" + ] + }, + { + "case": "many tx", + "request": { + "block": "00000020d987e1f7cc030f4272beda5a081f8f8969f044ef72a3b2c2e544afc8230b9642d8b5de43b746fa65aaab7cfa0b521b41e4eb0d7c0e2fb834380259df581daf03157eb360ffff7f200100000015020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050277020101ffffffff02246aa01200000000160014aef2e2877c45ada6b9eaef2bdb9131630ae12dca0000000000000000266a24aa21a9ed2af9d1c54b61988d37ce9bcde367fba7f3c5910cecaf8be1b6b443e937e39cec0120000000000000000000000000000000000000000000000000000000000000000000000000020000000001013d067178968e8e7469a61a82c365508ee3615bed93ed421ddefe19da412171080000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014a9b62806472c7b70c9f753bf41573e1506534dc40247304402205de2d7b0acf8e6027fcb1e197745ca8d23c1a4a7f4dc449762265e2aab2022f202204d35e5866f31595616b44f77e218fbddbfed702b830eb4c2aac087c5c1ad0648012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019421ca1de8781f070262511333197ab44f1629dbb704bd923f48bae4fa67a9f90000000000feffffff0213373f250000000016001455d6fbae5d95d2b03e5210abbe5a15ddbdb62c47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402206f590ce48f6f7a93821c116c3a4a9659d9739d8a9bc62fcae12e34cf0e4b26500220361867ad6dcd30af0bec09a9571a8888452d2812275201f4878de296a78e8627012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e4212da7a883762b80efdf512263fd8d412771515b8b81cf992c01314fc93210000000000feffffff0213373f2500000000160014563423d5881cddbb72a1d6fea1af5c56bbea6a3fa0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220185d48c45b2e83f56249bfda4e2f0e1a211165c3c1175bd358cc7e4024e4764202201835811415ee2e5efbf42445b0113f54ae87b99e77e59252a69960759fdd8cf7012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d46302000002000000000101f0d8cef892eb52f81ac0e86bce4df8eeb9d0c1336cb62a069626c173e65321f80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014e53cad733f173a80f1402d16123321535454048e0247304402207bbea0204f17fb98370ada2158666b4554d1354409efbd326835413041cd24410220323a16ee7b50f298446db61cd197cc44dd27fd90d45adb1a4fd780574300be7b012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101106a9ee2f6bbc4e58cbff2b1c99a53cdddec1a153f8a699350c00969500097210000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014f0321c988998afdb2b8788ce862402110792be8c0247304402207f6e3931036bb80b127b3d25ecf92bf5507cf057ec5af7c3a70b37e0c74575eb02205da9e647d92c86b2e17533050edd95e7eb887981e6145ade05728e0447a357bf012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101ea826992d745371bd6d762692369b94b2ac047df92d8b83cf9f46f6c9dbb13450000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014008e9141e1a0fd29384d41585598d2d1dc90ad380247304402202aeae79aa171eb28d21ee22fff4b58794d77e1ceda4c0bdd02fe87b4b6260c17022067184229e67f0ac2729e30206700fb50f0691e248690b6b103788552ebfb8b37012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001011723ce44d3f606a6fbd3de7e5204ad22f6b48154e19e0e37fdb547c84e57bdfe0000000000feffffff0213373f2500000000160014b30e6003f0a61a3c594678af24bfe170894c15cca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402202876093a9dec94f9ce1fb3b7c487a8cf38b09a9f3e438c2a1e56d2ff8e2287df02204bba8b7936cccad0302d4f0e39da4b27779a2e8a5ba5a506fe00907544224633012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001016de1c5853fd550cb2fdd67f25b32496bb182404e2f127b5e82e48c587622eabc0000000000feffffff0213373f250000000016001496864cef7241cc0c24e8914f4ec75e34da0a70a6a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402207dde78431c3e5ede2a90af0b3e3d32fadb5712e5ec04e3fac2dc6137d747187902202fc5603f63ce4498ad9062ed35b37ca5fc9a19fc90a9ef40ddec55b30820862c012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001013e22c22ad4afedfac4642f54ebc1fb93f94f3af1c7cedd78fb17242975e00e650000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001485fe6084fcec5323e4647ccb6781f2975ce78a690247304402202d4676c01c0f5f39d98f3e0435101c283baff3f2168bb20fccc99ef514abc77c02205703439a4ca4c289f9ab36e31ba88b81d5503ad705a30b036b628e505ef2b07f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e637219b2c53a395f6b61b85ff720e7380161b31473556d470878ccc9077fe80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014d9a72d531686342f1f81a447f9643d22ec7bd0ab02473044022010df9caa2ae04bf2b04cce039d859e8fe9f04add799ce02ce4f5848a48eebb9802204e11ae33d32a7c99af8dcc85797b5dc0b7a864c5f9848be41604740fac2bdb89012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010124c74f712076cb581a3ee4ae502e094487139ca3da724edb9c0acfd905bd8d340000000000feffffff0213373f250000000016001465eab055d88f1ac853fe1f790740ce24c8623e4ea0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022053373da5b4b0583d7ef8e743b0fad5688d5a81c82dd33fb6a614a0cf7234431a0220192e5802c1bf8d2e05bca416e3e42b1fb7947169333c40a33bfda2bf1170237d012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010145df9bc5da442ff71110c0872dc58939138aba50f2e12bdf13ef7e75ab2f893c0000000000feffffff0213373f250000000016001427880ac035c111a8e8f71e4ae6a5bb4df79518c4a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402200a13fd5ae3a2dd9bb210316fea853cc8ad9ada202a58c91f53c61a0741b63833022012a15e4bb30938b31da9606d03e2692e12ce87afe816df19ca20934dfadb7641012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010140b280318583b4e346fab2a2a126201799ddaffa169d3ac375b9434b3937a0750000000000feffffff0213373f2500000000160014e11569e65a6a7bbe75ca0322070eb0745201b99ca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220655e813dcd37ee11f44d82eddc1540225866e3cc730b768c6c5f9b80cd1c447502200e538e03ed2a3c4f5da9396e884890556e42bf5d25ae49eb1b6c8a0101096fb0012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001012fb0c024a0ae79e6217dc8889c6af40853b2b230a0e9f79d765c8b5525e0e2320000000000feffffff0213373f25000000001600147f44238db9775e0e738fb949724a7ffb66f4ac47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022032778f2c844abedb675ef947bdc7a11271800b5a11c98be5c0c9fdc6b2037f7302206acf28de27d327dc5a9d93998edad27f7509aa8479a1a2be1cb28f0eee28bf6a012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101892c26005096da187a5de107320c08a02e458be0184af915edbacaf5ad898c160000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001460524bb60b4dc68abe9ba195376d572dd6cc20fa0247304402206b43d3fcceff2ee92380f6e112b99907b94df56c9ed2ab7df4fa750fd5010ed70220526807188cb56ff1944e19db3910b06d944c8772a76fd91b83cca791c740da14012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010128877cbe42170fca382e506d745a333a1e1eed9ed5c3597cf904cd441f7fef050000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001462bf5d506758c4075c1484ed199c12b1d070dcc9024730440220514defa364f4cf78355fb64a79f0be487a0515f2c383cca2c7572b862f389b8b022040fb39e0cef457968c22c7a778b3225bf6d95e661c6bfaeea40dc6c9ae7fd9d5012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019b34c725b2b7de36389cec07b79109d482dab48e1641c2ba143fe1e0ab80f86d0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001437586a889710f537d70d511e41f45ade16ae96b80247304402205e1560130977bf5584e1938c34daa77e3dd0393eff6cfb18fa3d485a622a9f1d02200d55678c7c274442b0aa99d0a047094051b125ff74e8582be20d52dbb1825889012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001017883189114213697b8adc8069c8bafc80d9972c9fc1949a478c57bde58daacbb0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600144b69012485912f125d6121323d1b2c55e24b3a8f0247304402203bf784686661951078c64dce1410677127d92015d018a1233a9be6351f26ad2302203b6287e552aed0abcf8740cc464d5843dbd3712e58b33dfa2be6947ba88e7b8f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010180143a2ecddd4d3b32eb7c1e6378a054a2a02b278811a5ffbddf4db4e17f0ad70000000000feffffff0213373f2500000000160014fe956a004e01b6cbe82bf6a351f9370a60917abba0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220769b4f0bc75725b686fcc131af5b31722eeb0e7835bdeb812e16982183045d66022070a2f04e7619e75a9abd62170a1dbffceb11e398119c559bdb66cf49d91d7b43012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101f33b3ce193ef8a4450c6b4db2184538c0e5c5c5406e549478d8afe10b3d7e1760000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600147235fdc337715c994998751dbfb0f3a38e87594e02473044022071323b810bed75c508337a442268503d70ac598f8db2fd0af57fb7ff6b913450022075157811bc930b2a7e2dc2cf5d6b075ca99e3e81bef2992111e43b8aebe9a0ac012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d434020000", + "isElements": false, + "txid": "cb3f209415bd73c709740fa0742ba960679cf22e86f691d11eb08e4a85cef95f" + }, + "expect": { + "exist": true + }, + "exclude": [ + "js" + ] + }, + { + "case": "txid not found", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false, + "txid": "d5ce9417846b075c82da9368ed6bf40b59721662b64e4dd506fbdc50911f39fe" + }, + "expect": { + "exist": false + }, + "exclude": [ + "js" + ] + } + ] + }, + { + "name": "Block.GetTxCount", + "cases": [ + { + "case": "coinbase", + "request": { + "block": "00000030957958949bad814d1666ed0d4a005c8aed6b7fd56df5d12c81d584c71e5fae2dfe391f9150dcfb06d54d4eb6621672590bf46bed6893da825c076b841794cec5414e2660ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502d5000101ffffffff0200f9029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "isElements": false + }, + "expect": { + "count": 1 + }, + "exclude": [ + "js" + ] + }, + { + "case": "many tx", + "request": { + "block": "00000020d987e1f7cc030f4272beda5a081f8f8969f044ef72a3b2c2e544afc8230b9642d8b5de43b746fa65aaab7cfa0b521b41e4eb0d7c0e2fb834380259df581daf03157eb360ffff7f200100000015020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050277020101ffffffff02246aa01200000000160014aef2e2877c45ada6b9eaef2bdb9131630ae12dca0000000000000000266a24aa21a9ed2af9d1c54b61988d37ce9bcde367fba7f3c5910cecaf8be1b6b443e937e39cec0120000000000000000000000000000000000000000000000000000000000000000000000000020000000001013d067178968e8e7469a61a82c365508ee3615bed93ed421ddefe19da412171080000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014a9b62806472c7b70c9f753bf41573e1506534dc40247304402205de2d7b0acf8e6027fcb1e197745ca8d23c1a4a7f4dc449762265e2aab2022f202204d35e5866f31595616b44f77e218fbddbfed702b830eb4c2aac087c5c1ad0648012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019421ca1de8781f070262511333197ab44f1629dbb704bd923f48bae4fa67a9f90000000000feffffff0213373f250000000016001455d6fbae5d95d2b03e5210abbe5a15ddbdb62c47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402206f590ce48f6f7a93821c116c3a4a9659d9739d8a9bc62fcae12e34cf0e4b26500220361867ad6dcd30af0bec09a9571a8888452d2812275201f4878de296a78e8627012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e4212da7a883762b80efdf512263fd8d412771515b8b81cf992c01314fc93210000000000feffffff0213373f2500000000160014563423d5881cddbb72a1d6fea1af5c56bbea6a3fa0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220185d48c45b2e83f56249bfda4e2f0e1a211165c3c1175bd358cc7e4024e4764202201835811415ee2e5efbf42445b0113f54ae87b99e77e59252a69960759fdd8cf7012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d46302000002000000000101f0d8cef892eb52f81ac0e86bce4df8eeb9d0c1336cb62a069626c173e65321f80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014e53cad733f173a80f1402d16123321535454048e0247304402207bbea0204f17fb98370ada2158666b4554d1354409efbd326835413041cd24410220323a16ee7b50f298446db61cd197cc44dd27fd90d45adb1a4fd780574300be7b012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101106a9ee2f6bbc4e58cbff2b1c99a53cdddec1a153f8a699350c00969500097210000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014f0321c988998afdb2b8788ce862402110792be8c0247304402207f6e3931036bb80b127b3d25ecf92bf5507cf057ec5af7c3a70b37e0c74575eb02205da9e647d92c86b2e17533050edd95e7eb887981e6145ade05728e0447a357bf012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101ea826992d745371bd6d762692369b94b2ac047df92d8b83cf9f46f6c9dbb13450000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014008e9141e1a0fd29384d41585598d2d1dc90ad380247304402202aeae79aa171eb28d21ee22fff4b58794d77e1ceda4c0bdd02fe87b4b6260c17022067184229e67f0ac2729e30206700fb50f0691e248690b6b103788552ebfb8b37012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001011723ce44d3f606a6fbd3de7e5204ad22f6b48154e19e0e37fdb547c84e57bdfe0000000000feffffff0213373f2500000000160014b30e6003f0a61a3c594678af24bfe170894c15cca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402202876093a9dec94f9ce1fb3b7c487a8cf38b09a9f3e438c2a1e56d2ff8e2287df02204bba8b7936cccad0302d4f0e39da4b27779a2e8a5ba5a506fe00907544224633012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001016de1c5853fd550cb2fdd67f25b32496bb182404e2f127b5e82e48c587622eabc0000000000feffffff0213373f250000000016001496864cef7241cc0c24e8914f4ec75e34da0a70a6a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402207dde78431c3e5ede2a90af0b3e3d32fadb5712e5ec04e3fac2dc6137d747187902202fc5603f63ce4498ad9062ed35b37ca5fc9a19fc90a9ef40ddec55b30820862c012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001013e22c22ad4afedfac4642f54ebc1fb93f94f3af1c7cedd78fb17242975e00e650000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001485fe6084fcec5323e4647ccb6781f2975ce78a690247304402202d4676c01c0f5f39d98f3e0435101c283baff3f2168bb20fccc99ef514abc77c02205703439a4ca4c289f9ab36e31ba88b81d5503ad705a30b036b628e505ef2b07f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001018e637219b2c53a395f6b61b85ff720e7380161b31473556d470878ccc9077fe80000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f2500000000160014d9a72d531686342f1f81a447f9643d22ec7bd0ab02473044022010df9caa2ae04bf2b04cce039d859e8fe9f04add799ce02ce4f5848a48eebb9802204e11ae33d32a7c99af8dcc85797b5dc0b7a864c5f9848be41604740fac2bdb89012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010124c74f712076cb581a3ee4ae502e094487139ca3da724edb9c0acfd905bd8d340000000000feffffff0213373f250000000016001465eab055d88f1ac853fe1f790740ce24c8623e4ea0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022053373da5b4b0583d7ef8e743b0fad5688d5a81c82dd33fb6a614a0cf7234431a0220192e5802c1bf8d2e05bca416e3e42b1fb7947169333c40a33bfda2bf1170237d012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010145df9bc5da442ff71110c0872dc58939138aba50f2e12bdf13ef7e75ab2f893c0000000000feffffff0213373f250000000016001427880ac035c111a8e8f71e4ae6a5bb4df79518c4a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee0247304402200a13fd5ae3a2dd9bb210316fea853cc8ad9ada202a58c91f53c61a0741b63833022012a15e4bb30938b31da9606d03e2692e12ce87afe816df19ca20934dfadb7641012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010140b280318583b4e346fab2a2a126201799ddaffa169d3ac375b9434b3937a0750000000000feffffff0213373f2500000000160014e11569e65a6a7bbe75ca0322070eb0745201b99ca0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220655e813dcd37ee11f44d82eddc1540225866e3cc730b768c6c5f9b80cd1c447502200e538e03ed2a3c4f5da9396e884890556e42bf5d25ae49eb1b6c8a0101096fb0012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001012fb0c024a0ae79e6217dc8889c6af40853b2b230a0e9f79d765c8b5525e0e2320000000000feffffff0213373f25000000001600147f44238db9775e0e738fb949724a7ffb66f4ac47a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee02473044022032778f2c844abedb675ef947bdc7a11271800b5a11c98be5c0c9fdc6b2037f7302206acf28de27d327dc5a9d93998edad27f7509aa8479a1a2be1cb28f0eee28bf6a012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101892c26005096da187a5de107320c08a02e458be0184af915edbacaf5ad898c160000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001460524bb60b4dc68abe9ba195376d572dd6cc20fa0247304402206b43d3fcceff2ee92380f6e112b99907b94df56c9ed2ab7df4fa750fd5010ed70220526807188cb56ff1944e19db3910b06d944c8772a76fd91b83cca791c740da14012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010128877cbe42170fca382e506d745a333a1e1eed9ed5c3597cf904cd441f7fef050000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001462bf5d506758c4075c1484ed199c12b1d070dcc9024730440220514defa364f4cf78355fb64a79f0be487a0515f2c383cca2c7572b862f389b8b022040fb39e0cef457968c22c7a778b3225bf6d95e661c6bfaeea40dc6c9ae7fd9d5012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001019b34c725b2b7de36389cec07b79109d482dab48e1641c2ba143fe1e0ab80f86d0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f250000000016001437586a889710f537d70d511e41f45ade16ae96b80247304402205e1560130977bf5584e1938c34daa77e3dd0393eff6cfb18fa3d485a622a9f1d02200d55678c7c274442b0aa99d0a047094051b125ff74e8582be20d52dbb1825889012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d476020000020000000001017883189114213697b8adc8069c8bafc80d9972c9fc1949a478c57bde58daacbb0000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600144b69012485912f125d6121323d1b2c55e24b3a8f0247304402203bf784686661951078c64dce1410677127d92015d018a1233a9be6351f26ad2302203b6287e552aed0abcf8740cc464d5843dbd3712e58b33dfa2be6947ba88e7b8f012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d4760200000200000000010180143a2ecddd4d3b32eb7c1e6378a054a2a02b278811a5ffbddf4db4e17f0ad70000000000feffffff0213373f2500000000160014fe956a004e01b6cbe82bf6a351f9370a60917abba0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee024730440220769b4f0bc75725b686fcc131af5b31722eeb0e7835bdeb812e16982183045d66022070a2f04e7619e75a9abd62170a1dbffceb11e398119c559bdb66cf49d91d7b43012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d47602000002000000000101f33b3ce193ef8a4450c6b4db2184538c0e5c5c5406e549478d8afe10b3d7e1760000000000feffffff02a0860100000000001600143df45aa3e4c76b1f2f4693675770ba4e3db2acee13373f25000000001600147235fdc337715c994998751dbfb0f3a38e87594e02473044022071323b810bed75c508337a442268503d70ac598f8db2fd0af57fb7ff6b913450022075157811bc930b2a7e2dc2cf5d6b075ca99e3e81bef2992111e43b8aebe9a0ac012102b30fc0ddd4de67700667921a0c73f9e773d473c4827abe8c63b5060725b745d434020000", + "isElements": false + }, + "expect": { + "count": 21 + }, + "exclude": [ + "js" + ] + } + ] + } +] \ No newline at end of file diff --git a/tests/data/descriptor_test.json b/tests/data/descriptor_test.json index 7dcf5c5..49d8591 100644 --- a/tests/data/descriptor_test.json +++ b/tests/data/descriptor_test.json @@ -813,8 +813,8 @@ }, "expect": { "type": "taproot", - "address": "bcrt1paag57xhtzja2dnzh4vex37ejnjj5p3yy2nmlgem3a4e3ud962gdqqctzwn", - "lockingScript": "5120ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a", + "address": "bcrt1pvv8jm84ye0xr7p9h8l2k58rm287nryk73cnw0nvfxyjfqqpn60gssz7u5f", + "lockingScript": "5120630f2d9ea4cbcc3f04b73fd56a1c7b51fd3192de8e26e7cd893124900033d3d1", "hashType": "taproot", "includeMultisig": false, "keys": [ @@ -826,8 +826,8 @@ "scripts": [ { "depth": 0, - "lockingScript": "5120ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a", - "address": "bcrt1paag57xhtzja2dnzh4vex37ejnjj5p3yy2nmlgem3a4e3ud962gdqqctzwn", + "lockingScript": "5120630f2d9ea4cbcc3f04b73fd56a1c7b51fd3192de8e26e7cd893124900033d3d1", + "address": "bcrt1pvv8jm84ye0xr7p9h8l2k58rm287nryk73cnw0nvfxyjfqqpn60gssz7u5f", "hashType": "taproot", "keyType": "schnorrPubkey", "key": "ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a" @@ -845,8 +845,8 @@ }, "expect": { "type": "taproot", - "address": "bc1p33h4j4kre3e9r4yrl35rlgrtyt2w9hw8f94zty9vacmvfgcnlqtq0txdxt", - "lockingScript": "51208c6f5956c3cc7251d483fc683fa06b22d4e2ddc7496a2590acee36c4a313f816", + "address": "bc1p4jueea9m897g4me0ef8eyqg9x5n02jzpwnl0yydvdtrl459r3fyqg8wvnj", + "lockingScript": "5120acb99cf4bb397c8aef2fca4f9201053526f5484174fef211ac6ac7fad0a38a48", "hashType": "taproot", "includeMultisig": false, "keys": [ @@ -858,8 +858,8 @@ "scripts": [ { "depth": 0, - "lockingScript": "51208c6f5956c3cc7251d483fc683fa06b22d4e2ddc7496a2590acee36c4a313f816", - "address": "bc1p33h4j4kre3e9r4yrl35rlgrtyt2w9hw8f94zty9vacmvfgcnlqtq0txdxt", + "lockingScript": "5120acb99cf4bb397c8aef2fca4f9201053526f5484174fef211ac6ac7fad0a38a48", + "address": "bc1p4jueea9m897g4me0ef8eyqg9x5n02jzpwnl0yydvdtrl459r3fyqg8wvnj", "hashType": "taproot", "keyType": "extPubkey", "key": "xpub6EKMC2gSMfKgSwn7V9VZn7x1MvoeeVzSmmtSJ4z2L2d6R4WxvdQMouokypZHVp4fgKycrrQnGr6WJ5ED5jG9Q9FiA1q5gKYUc8u6JHJhdo8" @@ -932,6 +932,38 @@ ] } }, + { + "case": "taproot hash only tapbranch (uncheck)", + "request": { + "isElements": false, + "descriptor": "tr(ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a,{1717a480c2e3a474eed8dba83f684731243cff8ef384521936cf3a730dd0a286,{1717a480c2e3a474eed8dba83f684731243cff8ef384521936cf3a730dd0a286,80039cda864c4f2f1c87f161b0038e57fb7a4a59ff37517048696b85cdaaf911}})", + "network": "regtest" + }, + "expect": { + "type": "taproot", + "address": "bcrt1pfuqf4j7ceyzmu3rsmude93ctu948r565hf2ucrn9z7zn7a7hjegskj3rsv", + "lockingScript": "51204f009acbd8c905be4470df1b92c70be16a71d354ba55cc0e6517853f77d79651", + "hashType": "taproot", + "includeMultisig": false, + "treeString": "{1717a480c2e3a474eed8dba83f684731243cff8ef384521936cf3a730dd0a286,{1717a480c2e3a474eed8dba83f684731243cff8ef384521936cf3a730dd0a286,80039cda864c4f2f1c87f161b0038e57fb7a4a59ff37517048696b85cdaaf911}}", + "keys": [ + { + "keyType": "schnorrPubkey", + "key": "ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a" + } + ], + "scripts": [ + { + "depth": 0, + "lockingScript": "51204f009acbd8c905be4470df1b92c70be16a71d354ba55cc0e6517853f77d79651", + "address": "bcrt1pfuqf4j7ceyzmu3rsmude93ctu948r565hf2ucrn9z7zn7a7hjegskj3rsv", + "hashType": "taproot", + "keyType": "schnorrPubkey", + "key": "ef514f1aeb14baa6cc57ab3268fb329ca540c48454f7f46771ed731e34ba521a" + } + ] + } + }, { "case": "Elements pkh liquidv1", "request": { diff --git a/tests/data/elements_address_test.json b/tests/data/elements_address_test.json index 77ddab0..64356f3 100644 --- a/tests/data/elements_address_test.json +++ b/tests/data/elements_address_test.json @@ -629,5 +629,234 @@ } } ] + }, + { + "name": "PegoutAddress.Create", + "cases": [ + { + "case": "extkey - p2pkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "n3Na7mek1zAStRxvt7RPrNCpZhDErMPkGw", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "descriptor - p2pkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "n3Na7mek1zAStRxvt7RPrNCpZhDErMPkGw", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "deriveDescriptor - p2pkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y/0/*)", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "n3Na7mek1zAStRxvt7RPrNCpZhDErMPkGw", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "extkey - p2pkh - mainnet", + "request": { + "network": "mainnet", + "elementsNetwork": "liquidv1", + "descriptor": "xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "1MMxsm4QG8NRHqaFZaUTFQQ9c9dEHUPWnD", + "baseDescriptor": "pkh(xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2)" + } + }, + { + "case": "descriptor - p2pkh - mainnet", + "request": { + "network": "mainnet", + "elementsNetwork": "liquidv1", + "descriptor": "pkh(xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2)", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "1MMxsm4QG8NRHqaFZaUTFQQ9c9dEHUPWnD", + "baseDescriptor": "pkh(xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2)" + } + }, + { + "case": "deriveDescriptor - p2pkh - mainnet", + "request": { + "network": "mainnet", + "elementsNetwork": "liquidv1", + "descriptor": "pkh(xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2/0/*)", + "bip32Counter": 0, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "1MMxsm4QG8NRHqaFZaUTFQQ9c9dEHUPWnD", + "baseDescriptor": "pkh(xpub67v4wfueMiZVkc7UbutFgPiptQw4kkNs89ooNMrwht8xEjnZZim1rNZHhEdrLejB99fiBdnWNNAB8hmUK7tCo5Ua6UtHzwVLj2Bzpch7vB2)" + } + }, + { + "case": "extkey - p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y", + "bip32Counter": 0, + "hashType": "p2wpkh" + }, + "expect": { + "mainchainAddress": "bcrt1qa77w63m523kq82z4fn3d5f7qxqxfm4pmdthkdf", + "baseDescriptor": "wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "descriptor - p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)", + "bip32Counter": 0, + "hashType": "p2wpkh" + }, + "expect": { + "mainchainAddress": "bcrt1qa77w63m523kq82z4fn3d5f7qxqxfm4pmdthkdf", + "baseDescriptor": "wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "deriveDescriptor - p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y/0/*)", + "bip32Counter": 0, + "hashType": "p2wpkh" + }, + "expect": { + "mainchainAddress": "bcrt1qa77w63m523kq82z4fn3d5f7qxqxfm4pmdthkdf", + "baseDescriptor": "wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "extkey - p2sh-p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y", + "bip32Counter": 0, + "hashType": "p2sh-p2wpkh" + }, + "expect": { + "mainchainAddress": "2N8UxQ5u9YXYFn6Ukj5KGXCMDUZTixKTXHo", + "baseDescriptor": "sh(wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y))" + } + }, + { + "case": "descriptor - p2sh-p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "sh(wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y))", + "bip32Counter": 0, + "hashType": "p2sh-p2wpkh" + }, + "expect": { + "mainchainAddress": "2N8UxQ5u9YXYFn6Ukj5KGXCMDUZTixKTXHo", + "baseDescriptor": "sh(wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y))" + } + }, + { + "case": "deriveDescriptor - p2sh-p2wpkh - regtest", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "sh(wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y/0/*))", + "bip32Counter": 0, + "hashType": "p2sh-p2wpkh" + }, + "expect": { + "mainchainAddress": "2N8UxQ5u9YXYFn6Ukj5KGXCMDUZTixKTXHo", + "baseDescriptor": "sh(wpkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y))" + } + }, + { + "case": "extkey - p2pkh - regtest - count 1", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y", + "bip32Counter": 1, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "mjii5Qey7jLxtvsV5f6BaFeVaqfeqcKXzL", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "descriptor - p2pkh - regtest - count 1", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)", + "bip32Counter": 1, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "mjii5Qey7jLxtvsV5f6BaFeVaqfeqcKXzL", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "deriveDescriptor - p2pkh - regtest - count 1", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y/0/*)", + "bip32Counter": 1, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "mjii5Qey7jLxtvsV5f6BaFeVaqfeqcKXzL", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + }, + { + "case": "deriveDescriptor - p2pkh - regtest - count max", + "request": { + "network": "regtest", + "elementsNetwork": "elementsregtest", + "descriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y/0/*)", + "bip32Counter": 2147483647, + "hashType": "p2pkh" + }, + "expect": { + "mainchainAddress": "mfkLVoxUp9K2Q1KeRr3Ewnn414jLSCTGmn", + "baseDescriptor": "pkh(tpubDASgDECJvTMzUgS7GkSCxQAAWPveW7BeTPSvbi1wpUe1Mq1v743FRw1i7vTavjAb3D3Y8geCTYw2ezgiVS7SFXDXS6NpZmvr6XPjPvg632y)" + } + } + ] } ] \ No newline at end of file diff --git a/tests/data/elements_coin_test.json b/tests/data/elements_coin_test.json index ae8cc2c..aee54c1 100644 --- a/tests/data/elements_coin_test.json +++ b/tests/data/elements_coin_test.json @@ -62,7 +62,7 @@ "amount": 78125000 } ], - "feeAmount": 3320, + "feeAmount": 3340, "utxoFeeAmount": 1840 } }, @@ -103,7 +103,7 @@ "amount": 234375000 } ], - "feeAmount": 5140, + "feeAmount": 5180, "utxoFeeAmount": 3680 } }, @@ -144,7 +144,7 @@ "amount": 100001090 } ], - "feeAmount": 1864, + "feeAmount": 1868, "utxoFeeAmount": 368 } }, @@ -181,7 +181,7 @@ "amount": 155062500 } ], - "feeAmount": 1682, + "feeAmount": 1684, "utxoFeeAmount": 184 } }, @@ -226,7 +226,7 @@ "amount": 115063590 } ], - "feeAmount": 1773, + "feeAmount": 1776, "utxoFeeAmount": 276 } }, @@ -275,7 +275,7 @@ "amount": 26918400 } ], - "feeAmount": 5140, + "feeAmount": 5180, "utxoFeeAmount": 3680 } }, @@ -332,7 +332,7 @@ "amount": 347180050 } ], - "feeAmount": 2228, + "feeAmount": 2236, "utxoFeeAmount": 736 } }, @@ -397,7 +397,7 @@ "amount": 37654200 } ], - "feeAmount": 2228, + "feeAmount": 2236, "utxoFeeAmount": 736 } }, @@ -494,8 +494,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "a10ecbe1be7a5f883d5d45d966e30dbc1beff5f21c55cec76cc21a2229116a9f", "blindFactor": "ae0f46d1940f297c2dc3bbd82bf8ef6931a2431fbb05b3d3bc5df41af86ae808", "keyData": { @@ -514,8 +515,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "0b8954757234fd3ec9cf0dd6ef0a89d825ec56a9532e7da4b6cb90c51be3bbd8", "blindFactor": "62e36e1f0fa4916b031648a6b6903083069fa587572a88b729250cde528cfd3b", "keyData": { @@ -536,6 +538,80 @@ "txoutFeeAmount": 549, "utxoFeeAmount": 206 } + }, + { + "case": "unblind pegin", + "request": { + "selectUtxos": [ + { + "txid": "3b34ca92580075265d9548332041796ee7f55f63801835d3a4177f88601bfb41", + "vout": 0, + "amount": 24232, + "asset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", + "redeemScript": "", + "descriptor": "wpkh(03f942716865bb9b62678d99aa34de4632249d066d99de2b5a2e542e54908450d6)", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": true, + "claimScript": "0014aab2ed7ac90f976a17ddb850c4a0c4e62db49b07", + "peginBtcTxSize": 83, + "peginTxOutProofSize": 473, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + } + ], + "feeRate": 0.1, + "tx": "02000000000141fb1b60887f17a4d3351880635ff5e76e7941203348955d2675005892ca343b0000004000ffffffff02016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f010000000000005e7f001600149aa483fc0fd0b1806f25e57903e4cbefb19c20a1016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f010000000000000029000000000000", + "isBlind": false, + "feeAsset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d" + }, + "expect": { + "feeAmount": 36, + "txoutFeeAmount": 13, + "utxoFeeAmount": 24 + } + }, + { + "case": "unblind pegin on tx", + "request": { + "selectUtxos": [ + { + "txid": "3b34ca92580075265d9548332041796ee7f55f63801835d3a4177f88601bfb41", + "vout": 0, + "amount": 24232, + "asset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", + "redeemScript": "", + "descriptor": "wpkh(03f942716865bb9b62678d99aa34de4632249d066d99de2b5a2e542e54908450d6)", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": false, + "claimScript": "", + "peginBtcTxSize": 0, + "peginTxOutProofSize": 0, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + } + ], + "feeRate": 0.1, + "tx": "02000000010141fb1b60887f17a4d3351880635ff5e76e7941203348955d2675005892ca343b0000004000ffffffff02016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f010000000000005e7f001600149aa483fc0fd0b1806f25e57903e4cbefb19c20a1016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f01000000000000002900000000000000000247304402204c761ad9b55f2fd502d09551656c34f5e118220c286072c7408fe1b2d9eb033202201cb5fbbd90038d82fd21b686a23fa26ac20574da7f28a2afff5e958547ab72ef012102026e4a89b56f6f89de4f0c00d084eacb9dc310e387433049b55d7737fa2e04a70608a85e000000000000206d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000160014aab2ed7ac90f976a17ddb850c4a0c4e62db49b0753020000000123edd3be8309747693f42e5b6a0a0c57899fca7d6fb5a8d9c4f52fbf7398f03d00000000000000008001a85e00000000000017a914fdfbf873904e8276428aa892576acd028775fbda8700000000fdd9010400c0209ac0009d7289eb8e52ef1883501b35ec6ee8a5bfc83a09000000000000000000e157506b8e9b09bed1b9a9d6045fa26735547d696d9ce230c7f2003d09704594f558e160ce981317486c10c46e0600000c7eab9226e14b446023e58c32f677298a3a60448556b3b6dcf189ea680035de47fcd1a47ece1bda2de728f1ea7ca166338ddd0ab1ee2797c7cd2c9c5d5d07b055ed58f3b21f1324c98e1c09a8f4dd3a3f5b3a7ca8efc48fcbcb41cbf5476c40e9e3abc1c5d78e4b59dde0cfabf3c47d68f2f83893b19c0079b6902525c41e146ad09cb3859268063fd6e6b123036e6c65a975698553d701e04f0801752a4c454ff689b184b1c48c3fdfc33a7e25c2d96f8b9dfcbbb6b970f7da7ecbccd6f3d33141fb1b60887f17a4d3351880635ff5e76e7941203348955d2675005892ca343b04b0b4b9206faf789f1c0659f100a69eea88bfdc66a2b2382fe628fb159304ffd3f7ef70acc4e0438b1fb380da205c7ae0746dfbb451bb2110a9a25e224455719c6c22fa85161cb1df6fc4a870b337d2de35c7cc478c6658147ea8e1d64e7152d172e425e8e3ffd1cfae750d09193292f6e170a1fbfd65d8d43ecc3c5e0932fddf4b338fb84ae565a87fb78bc9d4d5d32ab8bf1fba7880c08c3a8a3a7e3aa22803bdd60200000000", + "isBlind": false, + "feeAsset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d" + }, + "expect": { + "feeAmount": 36, + "txoutFeeAmount": 13, + "utxoFeeAmount": 24 + } } ] }, @@ -553,12 +629,12 @@ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" + "reserveAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" + "reserveAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" } ], "feeInfo": { @@ -573,12 +649,12 @@ } }, "expect": { - "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001ff00000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b595f0016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", + "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001f500000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b59690016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", "usedAddresses": [ "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q", "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" ], - "feeAmount": 511 + "feeAmount": 501 } }, { @@ -604,12 +680,12 @@ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" + "reserveAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" + "reserveAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" } ], "feeInfo": { @@ -624,12 +700,12 @@ } }, "expect": { - "hex": "0200000000030f231181a6d8fa2c5f7020948464110fbcc925f94d673d5752ce66d00250a1570100008000ffffffffd8bbe31bc590cbb6a47d2e53a956ec25d8890aefd60dcfc93efd34727554890b0683fe0819a4f9770c8a7cd5824e82975c825e017aff8ba0d6a5eb4959cf9c6f010000000023c34600000bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff07010bad521bafdac767421d45b71b29a349c7b2ca2a06b5d8e3b5898c91df2769ed010000000029b92700001976a9146c22e209d36612e0d9d2a20b814d7d8648cc7a7788ac01cdb0ed311810e61036ac9255674101497850f5eee5e4320be07479c05473cbac010000000023c34600001976a9149bdcb18911fa9faad6632ca43b81739082b0a19588ac0100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa01000000000000037200000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b57ec0016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", + "hex": "0200000000030f231181a6d8fa2c5f7020948464110fbcc925f94d673d5752ce66d00250a1570100008000ffffffffd8bbe31bc590cbb6a47d2e53a956ec25d8890aefd60dcfc93efd34727554890b0683fe0819a4f9770c8a7cd5824e82975c825e017aff8ba0d6a5eb4959cf9c6f010000000023c34600000bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff07010bad521bafdac767421d45b71b29a349c7b2ca2a06b5d8e3b5898c91df2769ed010000000029b92700001976a9146c22e209d36612e0d9d2a20b814d7d8648cc7a7788ac01cdb0ed311810e61036ac9255674101497850f5eee5e4320be07479c05473cbac010000000023c34600001976a9149bdcb18911fa9faad6632ca43b81739082b0a19588ac0100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa01000000000000036800000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b57f60016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", "usedAddresses": [ "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q", "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" ], - "feeAmount": 882 + "feeAmount": 872 } }, { @@ -655,7 +731,7 @@ { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" + "reserveAddress": "ex1q55a7gqgnhdg09w9j6zl7585z8e6kx26lxfq8xd" } ], "feeInfo": { @@ -688,12 +764,12 @@ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ert1q0r4elskfu8xlvvlvkergtzagv2ep8p9t3zeg96" + "reserveAddress": "ert1q0r4elskfu8xlvvlvkergtzagv2ep8p9t3zeg96" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" + "reserveAddress": "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" } ], "feeInfo": { @@ -708,13 +784,16 @@ } }, "expect": { - "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001ff00000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b595f0016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", + "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001f500000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b59690016001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", "usedAddresses": [ "ert1q0r4elskfu8xlvvlvkergtzagv2ep8p9t3zeg96", "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" ], - "feeAmount": 511 - } + "feeAmount": 501 + }, + "exclude": [ + "js" + ] }, { "case": "confidential address", @@ -722,17 +801,17 @@ "utxoFile": "elements_utxo_3", "selectUtxos": [], "tx": "020000000000020100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c00000000", - "network": "liquidv1", + "network": "elementsregtest", "targets": [ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "el1qqdqg9pua7svrx9u5ujj4hp7djnfdy0837g42quyp4g5tj8pgkhj6z78tnlpvncwd7ce7edjxsk96sc4jzwz2ky5z0zegze59c" + "reserveAddress": "el1qqdqg9pua7svrx9u5ujj4hp7djnfdy0837g42quyp4g5tj8pgkhj6z78tnlpvncwd7ce7edjxsk96sc4jzwz2ky5z0zegze59c" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" + "reserveAddress": "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" } ], "feeInfo": { @@ -747,12 +826,100 @@ } }, "expect": { - "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001ff00000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b595f034082879df418331794e4a55b87cd94d2d23cf1f22aa07081aa28b91c28b5e5a116001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", + "hex": "0200000000020bfa8774c5f753ce2f801a8106413b470af94edbff5b4242ed4c5a26d20e72b90000000000ffffffff040b0000000000000000000000000000000000000000000000000000000000000000000000ffffffff050100000000000000000000000000000000000000000000000000000000000000aa010000000000989680001600144352a1a6e86311f22274f7ebb2746de21b09b15d0100000000000000000000000000000000000000000000000000000000000000bb01000000000007a120001600148beaaac4654cf4ebd8e46ca5062b0e7fb3e7470c0100000000000000000000000000000000000000000000000000000000000000aa0100000000000001f500000100000000000000000000000000000000000000000000000000000000000000bb010000000001124c1e00160014a53be40113bb50f2b8b2d0bfea1e823e75632b5f0100000000000000000000000000000000000000000000000000000000000000aa0100000000004b5969034082879df418331794e4a55b87cd94d2d23cf1f22aa07081aa28b91c28b5e5a116001478eb9fc2c9e1cdf633ecb646858ba862b21384ab00000000", "usedAddresses": [ "el1qqdqg9pua7svrx9u5ujj4hp7djnfdy0837g42quyp4g5tj8pgkhj6z78tnlpvncwd7ce7edjxsk96sc4jzwz2ky5z0zegze59c", "ert1q55a7gqgnhdg09w9j6zl7585z8e6kx26lum2leh" ], - "feeAmount": 511 + "feeAmount": 501 + } + }, + { + "case": "example test", + "request": { + "utxoFile": "elements_utxo_4", + "selectUtxos": [], + "tx": "020000000000010125b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a010000000005f5e100036a2e218bb512a3e65c80b59fec57aee428b7512276bcfa366c154dd7262994c817a914363273e2f851bda01e24cda41ba748b8d1f54cfe8700000000", + "network": "elementsregtest", + "targets": [ + { + "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", + "amount": 100000000, + "reserveAddress": "AzpkHG7iBPzGn3wCoKwEUrNMWA8TCLXTvhK6ftgAmaAGWqDKyDipYSFjsBBcGXKj3Y65Kt9UauCEbftj" + } + ], + "feeInfo": { + "feeRate": 1.0, + "longTermFeeRate": 1.0, + "knapsackMinChange": -1, + "dustFeeRate": 3.0, + "feeAsset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", + "isBlindEstimateFee": true, + "exponent": 0, + "minimumBits": 36 + } + }, + "expect": { + "hex": "0200000000027597a9db0a03074238e42936095b26e08193c5b054daf8d76bab761e0230c62b0000000000ffffffffc5c8a53f42d60311e2dd44b77fb61e9a691dc9a01736840d0f1ddc8a9e0c12420100000000ffffffff030125b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a010000000005f5e100036a2e218bb512a3e65c80b59fec57aee428b7512276bcfa366c154dd7262994c817a914363273e2f851bda01e24cda41ba748b8d1f54cfe870125b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a0100000000000007be00000125b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a01000000000bebba420230646d493a7ed8cb0091ad6e8feedcc9cd17a9162e61b7cff7929697792ef64217a91497dfc3937ad66e142925a76489eebc75358bca338700000000", + "usedAddresses": [ + "AzpkHG7iBPzGn3wCoKwEUrNMWA8TCLXTvhK6ftgAmaAGWqDKyDipYSFjsBBcGXKj3Y65Kt9UauCEbftj" + ], + "feeAmount": 1982 + } + }, + { + "case": "fund unblind pegin", + "request": { + "utxos": [], + "selectUtxos": [ + { + "txid": "3b34ca92580075265d9548332041796ee7f55f63801835d3a4177f88601bfb41", + "vout": 0, + "amount": 24232, + "asset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", + "redeemScript": "", + "descriptor": "wpkh(03f942716865bb9b62678d99aa34de4632249d066d99de2b5a2e542e54908450d6)", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": true, + "claimScript": "0014aab2ed7ac90f976a17ddb850c4a0c4e62db49b07", + "peginBtcTxSize": 83, + "peginTxOutProofSize": 473, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + } + ], + "tx": "02000000000141fb1b60887f17a4d3351880635ff5e76e7941203348955d2675005892ca343b0000004000ffffffff0000000000", + "network": "liquidv1", + "targets": [ + { + "asset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", + "amount": 0, + "reserveAddress": "ex1qn2jg8lq06zccqme9u4us8exta7cecg9p4madau" + } + ], + "feeInfo": { + "feeRate": 0.1, + "longTermFeeRate": 0.1, + "knapsackMinChange": -1, + "dustFeeRate": 3.0, + "feeAsset": "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", + "isBlindEstimateFee": false, + "exponent": 0, + "minimumBits": 36 + } + }, + "expect": { + "hex": "02000000000141fb1b60887f17a4d3351880635ff5e76e7941203348955d2675005892ca343b0000004000ffffffff02016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f0100000000000000240000016d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f010000000000005e84001600149aa483fc0fd0b1806f25e57903e4cbefb19c20a100000000", + "usedAddresses": [ + "ex1qn2jg8lq06zccqme9u4us8exta7cecg9p4madau" + ], + "feeAmount": 36 } }, { @@ -766,12 +933,12 @@ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" + "reserveAddress": "ex1q0r4elskfu8xlvvlvkergtzagv2ep8p9ttsns6q" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "ert1q0r4elskfu8xlvvlvkergtzagv2ep8p9t3zeg96" + "reserveAddress": "ert1q0r4elskfu8xlvvlvkergtzagv2ep8p9t3zeg96" } ], "feeInfo": { @@ -800,12 +967,12 @@ { "asset": "aa00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "bc1q0r4elskfu8xlvvlvkergtzagv2ep8p9tpewghq" + "reserveAddress": "bc1q0r4elskfu8xlvvlvkergtzagv2ep8p9tpewghq" }, { "asset": "bb00000000000000000000000000000000000000000000000000000000000000", "amount": 0, - "reservedAddress": "bc1q55a7gqgnhdg09w9j6zl7585z8e6kx26lvqaltd" + "reserveAddress": "bc1q55a7gqgnhdg09w9j6zl7585z8e6kx26lvqaltd" } ], "feeInfo": { diff --git a/tests/data/elements_test.json b/tests/data/elements_test.json index 5fb987a..d7e95bb 100644 --- a/tests/data/elements_test.json +++ b/tests/data/elements_test.json @@ -16,5 +16,27 @@ } } ] + }, + { + "name": "Elements.UnblindData", + "cases": [ + { + "case": "normal", + "request": { + "blindingKey": "66e4df5035a64acef16b4aa52ddc8bebd22b22c9eca150774e355abc72909d83", + "lockingScript": "a914001d6db698e75a5a8af771730c4ab258af30546b87", + "assetCommitment": "0bb0852f9c11249a0c8ebb1c1bc3f99c5f643fa3426d4e5c730e702aaf3f2581fc", + "valueCommitment": "091dd6cd19781f14385175b586607221d1f11b3f19f149e707810de78f7c7f6f79", + "commitmentNonce": "0398e7cd1cb3c9c13506f91b946f5586cc8fa45f36dde615f2bdb48c1dfe904270", + "rangeproof": "6033000000000000000121579e0109f21bb7cd0326804abb14059b54fa186892f060384435402393a6589fb54df6ede461ce206af5b13abbe1a564404abf7ab1cc4ed6bd1d93a91728224b21c10a540d76f0ccc047ffa3e06a8abad69687213373d5bcfd4fcf62ecd11c2aff9e1a9d64602cab441e3777d771f88f7e805223a5f192ed3d63b937e93e0e170e6b76e8a05fc5bb46826967d4850dbd2e9128ed615e71149f9aac9304194e968cd8b1ad28a96230b4064795040d16554776ee40b3793bdc9758285df2bc90a5c4be023d206293c071962939160f640ecedbba5a3731aa0aa60afd94f2d9a9d366b4e55ec8c561455ba6a849f8f0df0b19eaf98993655102500a47b76ad320522e4c1f9f829333331017cd0040226f60e426fc00b3844d08e364f6c9f346e3eb7dcf8de6e12a2ac98f11bed6b0c3e06c0bf767e96414ec276a2eb145f64eccb663b46135a19ac17cce785f15b1b2cb7206483329f4c38236ad3cd6cf1646a95ddb94beccb237dc6a854098b139df24f2c8ce7ce7e6d799a434f415ba52ce643bd51619edd786df734b0cee6a5a9ff0442f50a0ca011d8e5b695e6a44016884dbf2f6f681bc3faa5a1a9be514b87ab47183a85bd98b6eff7d5865246b7564a3008cba9b5bcac11e8b3b76dcc38c5915f14a1c7c08a76a31de11d9084cc0553871d0fb9e6ca25b2d191eb292c8f14c1b0cf9c4fedd0a85989a388c675e51003722bae92e356dd680a68f9861fc99be81bdc4f57fa0bf6f63613f80598960aacb8867a94cfbea8d4b776a4771ce1e8b20cf8506cd0524ba85e117085addf4de1d45c2ec6f8e441f74081b792208050ae890a91d5554e37d33ddba2b2c0bbdc2b4a31d0f7eaa1538e5a9fcbd86a87fdf5c6f161c0de5bdc9331b5936b06470c16778077887b3c80a53c5372914d2c3fffd5cb88ee00ffbbbdb10d7ce0fbbca1e725438b7f51a81b611b9f0c4330c3ec3b8d191218fc720c3165305412425f73efacdf44fb0cda9bd1f5290cac09a7f27ca68cb9b485d83c822282cadbfab69ef4f079d1d9e6042033a4a2c8ee9203509f9669f0553ece40d2958d3a733b81232b6ef6c21adc2e2716942588146d6dcadcdc94a13326c6828d04692da1a129e73a3f60cdd30d16b19b29f15a734ddcee491159fedec88a6c986e0243e99b9d2ceed1b9b8c7b3180857f067d8d778f8c0d19ef059f4bf2de3de7f3fc26c86a37cf046fae93cbaaf06e9d95ed73e95957aa69c2680087c6b36d51f93d8e3b9596ab4d793619e70a61edd12c14dc928cc56d1047ea3383b77d8d7527fe43317b21c86a323ed982ed1b766698dcda6c6a91bf50d3f01d7f1d8c20b44441cab3eeb5fac0995298eb7a7a6877bc420119a9acc713e221ddcd2038423c431247dd328372744aea39b9797a9757e46f9d83c5bcce8e2af2baef8416d27a2e5274c21ebdf432f844511081cede5f794ac5e4521d432a6497946d014af706cf431f3437d9d8ad04a3c84cbec65c5596569bdd268a2d7bf0025e6debf4209f7a7a6ae29d9357f84007e72358869caa02ce25813115c98ae6054e9bf48732b55bed6cfe87e7ae05eb435a6eece76046dc2da86d0c33283ff6fb4ffb65e8c943a8c298146c31b48eddc0e0255094c5761d9a8e7b155058efc755579301781355607f369724dd81b58d76977c19a9787ed92760ecce6b2ff0b03093f0936ba6b5872cdf0dcad63f4080f9501a813df248c3484f3445e75f8ca7ab028409bcf63c191b9bd352687397a0cab873dbf6c4fec4cf364cb2e7966f4b6d77e6b9a8477d44d3cf3ef5ecdb1faebd35dff45f39d660accf3bb3fa86cbd021e572eba6014e5c2e48702ab874bde9314c20e9073c20bad928b672249d01d8d8c89b368962a2e9cabca801fb27e59b1a58fd11fcf4d697746e1a7e72a8e32186155dd0f90468e6bb40e39e1d599434e7d504e577f2aee60479a21152c8c64c57f11930611385a605c150cb5c582489dd8e268ba8e1dd4b38fb337f347f3aa953a1d437f69209c2672c755d84957522938f6e69ec39a59725fe786e442a3f39083283dcb6177cde1a4abe38d17c4a45e7b1e78460474bee3eb8ccd4a1d0bd9ac7cc4dcac3dc9263117b0f9e05ff85853d9b28444ee840bd3f674dc2abc53fa5d2db8cd64a1739eec76063ffd93352128135b02377f6ca684b11add9c9434f6060f98c1c0f14ad941c12a4c6ca753afd36f22e353cf7147ab62c7245871a87166b7ca5d5e179953ee4d0328d0c7d69fd4128e06f6e546109732bd7d213e1559b280c0f2304ab874fe87410a77ed8c41378e5530e6ba6eb605f87fc75a4763244433366866ea9227cea868d67dde1287460351f8bc132c398bd4aaeadfe2959394ff96b3cbe1a3265777ea0fe676ecfd71daaf213d93edcc4a83fb9d159f858f61f8c28476430d97fd8879df97bb89914bc8e767a008b952976fb54d44492da79036004c36de129118f8fca1528dae9becd6c1471c9b1690fc00d64af653b1672f0db041ae7a0592a85dff25ca470892f8064b9ed01085a929d7b0ef03775fd5546bdab4ffd494a4af9c35ca0b6d3313c2be2c817522ff79fc54d28baf7707463dfe13423ae368bb1c80e7e2e509617f41c54f57ef67c6a786c28f1578be5a64e36cfb3b63c5e1c07619503619031772505987b515faabf7203b4d4413d6abbf8a6c8f00cd69a24e6c0f9c278b0f166763dbeed28ff447814e2d61c92d31840811f2b4e69323e7a35670b7629dbbe04afc7167ee217fe0f74930cf10ef5c07240c70ff3b36d200c1ce866bf108d5566fbff4860389f532871e2d8075fa28c39c85bd68a95f3a1e23265cbc5ed1657711239a32c4c67245d70eb93082323fcc7f113f912c1e0b818186e044b19dfc22d33c82e2cdfb88ead2f152790f47c1b432bce6d899e9c2dcf03969ab2cafd22e4cf7bbefe10bd2b8fb0078e8b5e006cf898259061efbeaa41aa46bd5cc19d3efe05a8c590bd8212b25f862b635876a9a63cde5fb194358c619fd39ef389b60eb7688513ea4dcf6dacc8cc97456a5131bf8de5b424edff078604456e8b6bce2b1504b8715e301a2957cd79f5f942524af676279645ba9f41f141544b0adac60703027cab8c5d9b51ec8103e2da72c3f7c61803cd94765493506e82921ca469b919cbce716ebe10864655fe6fc7177bba55baf3276007b196c81eb97b1fc7d925eb3c91da45a5ea5c5121f109e73f05937a33ecce115a325914bec1cb5590bc01b57fdba899f5e048ab18fb47c71e8cf351dbcf4140c6961a10ef1c3e322bf760ed222ba83b363977172ea2d7c40e23bcd307e28d69c868af7f1f0ace4965d68ee540ef2ba0b81a698db7239a40cf7845d7bf322e444178921dfcf9c23fbcbfc4d306146ccae6ecb707b7fcc7f43aa92071caba893507117621032d9a2c7ac602f013186b7faaa8596105bfdfe47b6e0e93538f322e7417db403a0288d7a6f635ba1c13f43927061717014c80c88b65840a6ca83d59abce9ef4873e34b936650ab0158d145e89e6aaf2d17fc6a9a8bbf8c01906404aac849189b3865687350764be2872532a2271e05d02f820644a33bf6b64c7bef615d6b8dc27250e58a55039b41c6d97f6d472bed31e76b042d4c79c770c242179acbaa6dc625b4b1e7d6525de8aa4cbc4dfbd5d9562ea60be9eafcda1ca7328c4c9db4064550c5268f9259dfa1a2aa3cffdd02ef19c76d32650da3b22ea83e6c04a063ece816fa9371d7669feb1a9a03eca17a9798eeb1626cb4cc996f2cbc8d8a0c5d78ef3e921a276eb03717a423e5cde35a878bf3961aeb3eacb26332bf7eecb5259074d865478bde6810233217cfd1f91c8c85ffd89285e8579ece30591fac67f863b000d665d4298be4142a0f9991c51ec03b828e7620e71b9eee7753b35328028ba0e73e65191a6516f842c65a423f015f3f8edba667a756f4e479d3f8a6d40a45a6698cf8b6a226649b17192fdc39977d9913eafb917fb9ad25ce26cda7f51e10535d3a29a3fb0fe5fe566f9ab8097d4b6c8f6236c42fde414cf1bdf88f83638d152c3504aa9758778c7107b2b43e3a1b5ade047afe4c527afe7c8bc1ae4559f9f393b6c4c35fbcd5089cb9fc96c43a15c7e052e28073046817b969c0e624bd7c147e3e2de3bc8eac41c160f400568bedeb1549f5b4081e1cbf106eff16c546fd03b552960abc0b64969bcdc85797e14bc73eaa45ca04ddbf228308190eed13503934f60b3b715bc3089241745b1df8439e7f08309fe873ea31ce35a6ccdb634dc9f27ee0cbfff9f4602bcd8f8b10a05f2fd7d46948caad11c09ca71effbe0ee63458874df827d9f652cbf1e55402c2a69b8a483029bf807ad63eb41cc92216d9f171284eb5d7dddb8e5d791d746ec35677a0b0b3eb435f65ecbf8dcd5ae2536eccbd554416e070ce4aaa566e2c5f925e6129617f93e531d17d06a18f1049a16e1e6aff5e46d48e0a6406c5a480c9884690c13ec302b9c03491be7bfe7981663a6716c6bc45ffd45b0c8ec581ec1ad7b1f7f409697bb39b6da1e27cf5355d9b6eca4a306c908083e3a81026ba1be096fdb6d9b7004cc21d439d5c6ce1a45afc951c84c7b26bcf9b4de4aef365ed514edc4a04e6999c1b9fa3f1ee332669228f3cdedd0edec4aa56824f4a64f295835b8830d153b0a0bf3f80c32d11d4b541be45d2c2522503d4bb3440829daf60ff383d71748becce66a78c2dab29fb82a6d7692c0da0326e65b8101a8099f7e2fdb60bdb08ed1e627747492c18b9f2f4653c6a8181cadc56cb684e878acc4583cc2f53ddbb18990291a26a750c422025b29de72d36581ef8fb047e7854cf04b4bba931a7a560d8cb4394a047c44926cee25d0b457e86ffaf4ad4f419df6e6c9d89b8f971310f109eaaa39403a9a5e4dc22ab5ce98afafd4f9b97c4202999ea0b62c20995c4c5b3cd466a99622980fb0478ee471168137cba6266ed7ce5caaaeec8df1921ce3749bcb6a6a488d40bc1f84df8f37847efd4833ec9bc39b5890bcda0ba97acab58ac1e389c752340ad20fbd2d6885f1ce7349376302cb3d5070f30288e55b033c4242f328b9ae4565af08519f052f758b4f6eff1e8fb1ef6d0a96eddc4f6d135cdd930d37ce9e9a0699989e5f54c9104a710070a5458c38af044b6335457d6ffa477fdaa8507b6043d8639e30190613ae5667c6a757522345ee1c1ca73b279255f2cf7b7ddfbdb60fa0e218e0675a9c0fc13d8f043230bae9db8073cd0ae2627c663fdedf7b8fe7341b3817623894874932797320ef582943b8fb5ea96827aef251193bc50dc4400cc7f9bc44d83651c05ff17904367f66d736eede1964f90d7fe7ff086b3849ce32a1554182b1ea8703447a61b2d2d6e2753558f1355a3fd84af25fd89fdf495b641880081d974ca641846c8d4495ce11b79933f1c47a1fef41adc1c7992fb11479ec8d117d06668580cf3558ae681626e50d559bf4147b2b1ec59c4979e19ef851612c3c888d57d512a073c0ff9fa7dfb7e7d9552925baf3e95a83f41a6a5bbd867820e791ae13b0923ebbfca3adeb46323c2c85c3fceb9525b5fc50a078f0b0a9c7820fef73429a617b476e89fa77627fe9816be6ba912da6353092c5953c4ff2911500c4e88f4a0124db5edbdce22cb34235d9c9c9d0e00559eabb222aab6dede02d6b0c46adbf6e9437339e267b26b9f2471e94e41a72a4445ff0a855f72bd04e028f845ec445f13f1d28f173a0494d769b552c85721ac10aed7e8a79b72adf8f5e4f409637a0541579cfa918dd50d3d93d00dabe7dac95675b07ac078fbb31e35e77baa280e6b5b510dfafbc0ee5445524e8a4ddc0c6df98080d74df263bf022566e2791d1fa4a72ebf880852e57b1eac8" + }, + "expect": { + "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", + "blindFactor": "0e396bcbc4c0b74329712b1b5c7f8c9c4f054996da3748b8820563f68a07dedd", + "assetBlindFactor": "6b49938ded88d5c2c335133665158134041769882dd560ca47c14631052a981c", + "amount": 209998999992700 + } + } + ] } ] \ No newline at end of file diff --git a/tests/data/elements_transaction_test.json b/tests/data/elements_transaction_test.json index 21a77c7..b8fe219 100644 --- a/tests/data/elements_transaction_test.json +++ b/tests/data/elements_transaction_test.json @@ -3846,6 +3846,39 @@ } ] }, + { + "name": "ConfidentialTransaction.UpdateTxInSequence", + "cases": [ + { + "case": "normal", + "request": { + "tx": "020000000101319bff5f4311e6255ecf4dd472650a6ef85fde7d11cd10d3e6ba5974174aeb560100008000ffffffff6f1a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f36f2a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f301000000000011223301000000000011224400000000000800110011001100110800110011001100220000", + "isElements": true, + "txid": "56eb4a177459bae6d310cd117dde5ff86e0a6572d44dcf5e25e611435fff9b31", + "vout": 1, + "sequence": 4294967294 + }, + "expect": { + "hex": "020000000101319bff5f4311e6255ecf4dd472650a6ef85fde7d11cd10d3e6ba5974174aeb560100008000feffffff6f1a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f36f2a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f301000000000011223301000000000011224400000000000800110011001100110800110011001100220000" + } + }, + { + "case": "unknown outpoint", + "request": { + "tx": "020000000101319bff5f4311e6255ecf4dd472650a6ef85fde7d11cd10d3e6ba5974174aeb560100008000ffffffff6f1a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f36f2a4b6bd5571b5f08ab79c314dc6483f9b952af2f5ef206cd6f8e68eb1186f301000000000011223301000000000011224400000000000800110011001100110800110011001100220000", + "isElements": true, + "txid": "66eb4a177459bae6d310cd117dde5ff86e0a6572d44dcf5e25e611435fff9b31", + "vout": 1, + "sequence": 4294967294 + }, + "error": { + "code": 1, + "type": "illegal_argument", + "cfd": "Txid is not found." + } + } + ] + }, { "name": "ConfidentialTransaction.UpdatePeginWitnessStack", "cases": [ diff --git a/tests/data/hdwallet_test.json b/tests/data/hdwallet_test.json index 35e57c1..5990a87 100644 --- a/tests/data/hdwallet_test.json +++ b/tests/data/hdwallet_test.json @@ -812,7 +812,8 @@ "depth": 4, "fingerprint": "8806118d", "childNumber": 2, - "chainCode": "a3d58c40ac9c588529edb6cf9576241a6c2c919843bd97c3c26b35538d91a292" + "chainCode": "a3d58c40ac9c588529edb6cf9576241a6c2c919843bd97c3c26b35538d91a292", + "keyType": "extpubkey" } }, { @@ -854,7 +855,8 @@ "depth": 4, "fingerprint": "00378ea0", "childNumber": 2, - "chainCode": "4d3e59df124f789eabee7bbb7348b8dc64ff64093bd304214b1a8b0e75af8faf" + "chainCode": "4d3e59df124f789eabee7bbb7348b8dc64ff64093bd304214b1a8b0e75af8faf", + "keyType": "extprivkey" } }, { diff --git a/tests/data/psbt_test.json b/tests/data/psbt_test.json index fbd9ddc..c2e2773 100644 --- a/tests/data/psbt_test.json +++ b/tests/data/psbt_test.json @@ -3067,6 +3067,224 @@ ], "feeAmount": 1166 } + }, + { + "case": "real value", + "request": { + "psbt": "cHNidP8BADUCAAAAAAEA4fUFAAAAACIAICjJbjePmp/tLuZR4KyR1k37+X+rUh6/bdKp5LhZw0nzAAAAAAABAUdSIQNIfwcMIgDqA8ZKOuQHrYKHeIK3N7VTsVOv0d2hdYRgkyECHvnOgXvotmxfFxWKBhjvhi/wpfLezy5RoVwmU9/ktiBSriICAh75zoF76LZsXxcVigYY74Yv8KXy3s8uUaFcJlPf5LYgDAAAAAABAAAAAQAAACICA0h/BwwiAOoDxko65Aetgod4grc3tVOxU6/R3aF1hGCTDAAAAAAAAAAAAQAAAAA=", + "network": "regtest", + "utxos": [ + { + "outpoint": "5c4bc622f3d8e2d29b7670e7c058f87a1e485e31278c0081ce75f36e91b2ac9a,1", + "txid": "5c4bc622f3d8e2d29b7670e7c058f87a1e485e31278c0081ce75f36e91b2ac9a", + "vout": 1, + "amount": 99899544, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "33475dfc91b775da3eb41d63219252775cb6b41fc9e1d5fd945d5b750304ac7f", + "blockHeight": 316, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698342903, + "version": 0, + "updated": 1620698343420 + }, + "$loki": 22 + }, + { + "outpoint": "5c4bc622f3d8e2d29b7670e7c058f87a1e485e31278c0081ce75f36e91b2ac9a,0", + "txid": "5c4bc622f3d8e2d29b7670e7c058f87a1e485e31278c0081ce75f36e91b2ac9a", + "vout": 0, + "amount": 100000000, + "address": "bcrt1qntzs28qdwx4ygag4fucjjjesm8g2kpt9j3732t", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/0/2)", + "lockingScript": "00149ac5051c0d71aa4475154f31294b30d9d0ab0565", + "blockHash": "33475dfc91b775da3eb41d63219252775cb6b41fc9e1d5fd945d5b750304ac7f", + "blockHeight": 316, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698342903, + "version": 0, + "updated": 1620698343420 + }, + "$loki": 21 + }, + { + "outpoint": "9294bbb95a14e35254ce19982edb308d39f693809b49c4258d289edcbd5a31a3,1", + "txid": "9294bbb95a14e35254ce19982edb308d39f693809b49c4258d289edcbd5a31a3", + "vout": 1, + "amount": 98614, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "21cafe8ef00d3906c3bbfb2a373938a69899fa1297745d7089d4ddaea351324d", + "blockHeight": 315, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698342321, + "version": 0, + "updated": 1620698342376 + }, + "$loki": 20 + }, + { + "outpoint": "8d4a074c3d8e2a062dec6849fdf35fe0dea0b9f655f7e65f925bf6fb77e1ed55,1", + "txid": "8d4a074c3d8e2a062dec6849fdf35fe0dea0b9f655f7e65f925bf6fb77e1ed55", + "vout": 1, + "amount": 4799996830, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "7c558edbc3ba155b5c68f86213f2c9a6e311ee026da318603a877fbd62e8816d", + "blockHeight": 213, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698340239, + "version": 0, + "updated": 1620698340631 + }, + "$loki": 16 + }, + { + "outpoint": "e9debc6911181c544cdf22fa021b755536834a45c36f4af76ba1f9a7e8a7b9f9,1", + "txid": "e9debc6911181c544cdf22fa021b755536834a45c36f4af76ba1f9a7e8a7b9f9", + "vout": 1, + "amount": 4999999544, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "2967ccdcdc65625046a2bf2b5a3ad20f799dd05b0938a7232a2819763f26de2c", + "blockHeight": 112, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698338817, + "version": 0, + "updated": 1620698338852 + }, + "$loki": 14 + }, + { + "outpoint": "472f6ee4e5f40610577c3fe824cbc1cd9686957e38c066148b1c1e62657e9e82,1", + "txid": "472f6ee4e5f40610577c3fe824cbc1cd9686957e38c066148b1c1e62657e9e82", + "vout": 1, + "amount": 4899999690, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "3c2c72d5ee4736f13b482b4c978395c2f09968667d50c19fe0b01772e36ca3f8", + "blockHeight": 111, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698338257, + "version": 0, + "updated": 1620698338346 + }, + "$loki": 13 + }, + { + "outpoint": "13338a243193d072a8e3925a508da49990a583bf5b2764ca180ce51d95aaa4c7,1", + "txid": "13338a243193d072a8e3925a508da49990a583bf5b2764ca180ce51d95aaa4c7", + "vout": 1, + "amount": 5000000000, + "address": "bcrt1qgk023q3rpc8dmsgcvu7d8gj0rrvhc8qftq5rcl", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/0/3)", + "lockingScript": "0014459ea882230e0eddc118673cd3a24f18d97c1c09", + "blockHash": "26cdb3b89b8240360e6200f34a229734375c8a0fdaddeaa337d908a26542435b", + "blockHeight": 109, + "coinbase": false, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 1, + "created": 1620698337189, + "version": 0, + "updated": 1620698337325 + }, + "$loki": 10 + }, + { + "outpoint": "923bdbe3be6eff8ee2541057fd903ef0dbf4f696d3a4d8b7cafd5190c15f1e85,0", + "txid": "923bdbe3be6eff8ee2541057fd903ef0dbf4f696d3a4d8b7cafd5190c15f1e85", + "vout": 0, + "amount": 5000000000, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "0cb25995f6a4bc5a818f2c738057a15900c6f3b3e8598f6b72cc20c46b25440a", + "blockHeight": 2, + "coinbase": true, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 0, + "created": 1620698324468, + "version": 0 + }, + "$loki": 2 + }, + { + "outpoint": "6d44c8080e92c0d7134647505cc57122be84652a2a4a740b1c6954ebdbadcae9,0", + "txid": "6d44c8080e92c0d7134647505cc57122be84652a2a4a740b1c6954ebdbadcae9", + "vout": 0, + "amount": 5000000000, + "address": "bcrt1q4akzjg7phc3n3cmcu6n2r73gr2slgugm7w8z3v", + "descriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/1/1)", + "lockingScript": "0014af6c2923c1be2338e378e6a6a1fa281aa1f4711b", + "blockHash": "7aa1917b5e563f5267bb0e147addfaf97dab6e2f816ca679aeab133a40197576", + "blockHeight": 1, + "coinbase": true, + "spent": false, + "solvable": true, + "extend": {}, + "meta": { + "revision": 0, + "created": 1620698324451, + "version": 0 + }, + "$loki": 1 + } + ], + "reservedDescriptor": "wpkh([00000001/1]tprv8fce2zvfnLAXzh6X1gxH1kfCdECfQoqm1Y6bVNbmwtEpwQqCs5oQ42jJEq7d7Z4Cm26u3FDi83koiAjcqQvyooN1jNhYVPM33o7FxhJH6qU/0/3)", + "feeInfo": { + "feeRate": 2, + "knapsackMinChange": 1 + } + }, + "expect": { + "psbt": "cHNidP8BAKYCAAAAApqsspFu83XOgQCMJzFeSB56+FjA53B2m9Li2PMixktcAAAAAAD/////ozFavdyeKI0lxEmbgJP2OY0w2y6YGc5UUuMUWrm7lJIBAAAAAP////8CAOH1BQAAAAAiACAoyW43j5qf7S7mUeCskdZN+/l/q1Iev23SqeS4WcNJ83h/AQAAAAAAFgAURZ6ogiMODt3BGGc806JPGNl8HAkAAAAAAAEBHwDh9QUAAAAAFgAUmsUFHA1xqkR1FU8xKUsw2dCrBWUiBgNIfwcMIgDqA8ZKOuQHrYKHeIK3N7VTsVOv0d2hdYRgkxAAAAABAQAAAAAAAAACAAAAAAEBHzaBAQAAAAAAFgAUr2wpI8G+IzjjeOamofooGqH0cRsiBgJ5LDdX0nfZlmx9lsKY09JN92BwF8EKR16VimwVcEOyoBAAAAABAQAAAAEAAAABAAAAAAEBR1IhA0h/BwwiAOoDxko65Aetgod4grc3tVOxU6/R3aF1hGCTIQIe+c6Be+i2bF8XFYoGGO+GL/Cl8t7PLlGhXCZT3+S2IFKuIgICHvnOgXvotmxfFxWKBhjvhi/wpfLezy5RoVwmU9/ktiAMAAAAAAEAAAABAAAAIgIDSH8HDCIA6gPGSjrkB62Ch3iCtze1U7FTr9HdoXWEYJMMAAAAAAAAAAABAAAAACICAszyNzrkZUZ0TSh3Y3u1lSNvpyyQT1Qmv3yeJc3F3JVvEAAAAAEBAAAAAAAAAAMAAAAA", + "hex": "70736274ff0100a602000000029aacb2916ef375ce81008c27315e481e7af858c0e770769bd2e2d8f322c64b5c0000000000ffffffffa3315abddc9e288d25c4499b8093f6398d30db2e9819ce5452e3145ab9bb94920100000000ffffffff0200e1f5050000000022002028c96e378f9a9fed2ee651e0ac91d64dfbf97fab521ebf6dd2a9e4b859c349f3787f010000000000160014459ea882230e0eddc118673cd3a24f18d97c1c09000000000001011f00e1f505000000001600149ac5051c0d71aa4475154f31294b30d9d0ab0565220603487f070c2200ea03c64a3ae407ad82877882b737b553b153afd1dda17584609310000000010100000000000000020000000001011f3681010000000000160014af6c2923c1be2338e378e6a6a1fa281aa1f4711b220602792c3757d277d9966c7d96c298d3d24df7607017c10a475e958a6c157043b2a0100000000101000000010000000100000000010147522103487f070c2200ea03c64a3ae407ad82877882b737b553b153afd1dda17584609321021ef9ce817be8b66c5f17158a0618ef862ff0a5f2decf2e51a15c2653dfe4b62052ae2202021ef9ce817be8b66c5f17158a0618ef862ff0a5f2decf2e51a15c2653dfe4b6200c000000000100000001000000220203487f070c2200ea03c64a3ae407ad82877882b737b553b153afd1dda1758460930c00000000000000000100000000220202ccf2373ae46546744d2877637bb595236fa72c904f5426bf7c9e25cdc5dc956f100000000101000000000000000300000000", + "usedAddresses": [ + "bcrt1qgk023q3rpc8dmsgcvu7d8gj0rrvhc8qftq5rcl" + ], + "feeAmount": 446 + } } ] } diff --git a/tests/data/transaction_test.json b/tests/data/transaction_test.json index c2e1089..0f517b9 100644 --- a/tests/data/transaction_test.json +++ b/tests/data/transaction_test.json @@ -4511,6 +4511,39 @@ } ] }, + { + "name": "Transaction.UpdateTxInSequence", + "cases": [ + { + "case": "normal", + "request": { + "tx": "02000000000101ffa8db90b81db256874ff7a98fb7202cdc0b91b5b02d7c3427c4190adc66981f0000000000ffffffff0118f50295000000002251201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb02473044022018b10265080f8c491c43595000461a19212239fea9ee4c6fd26498f358b1760d0220223c1389ac26a2ed5f77ad73240af2fa6eb30ef5d19520026c2f7b7e817592530121023179b32721d07deb06cade59f56dedefdc932e89fde56e998f7a0e93a3e30c4400000000", + "isElements": false, + "txid": "1f9866dc0a19c427347c2db0b5910bdc2c20b78fa9f74f8756b21db890dba8ff", + "vout": 0, + "sequence": 4294967294 + }, + "expect": { + "hex": "02000000000101ffa8db90b81db256874ff7a98fb7202cdc0b91b5b02d7c3427c4190adc66981f0000000000feffffff0118f50295000000002251201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb02473044022018b10265080f8c491c43595000461a19212239fea9ee4c6fd26498f358b1760d0220223c1389ac26a2ed5f77ad73240af2fa6eb30ef5d19520026c2f7b7e817592530121023179b32721d07deb06cade59f56dedefdc932e89fde56e998f7a0e93a3e30c4400000000" + } + }, + { + "case": "unknown outpoint", + "request": { + "tx": "02000000000101ffa8db90b81db256874ff7a98fb7202cdc0b91b5b02d7c3427c4190adc66981f0000000000ffffffff0118f50295000000002251201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb02473044022018b10265080f8c491c43595000461a19212239fea9ee4c6fd26498f358b1760d0220223c1389ac26a2ed5f77ad73240af2fa6eb30ef5d19520026c2f7b7e817592530121023179b32721d07deb06cade59f56dedefdc932e89fde56e998f7a0e93a3e30c4400000000", + "isElements": false, + "txid": "1f9866dc0a19c427347c2db0b5910bdc2c20b78fa9f74f8756b21db890dba8ff", + "vout": 2, + "sequence": 4294967294 + }, + "error": { + "code": 1, + "type": "illegal_argument", + "cfd": "Txid is not found." + } + } + ] + }, { "name": "Transaction.SplitTxOut", "cases": [ diff --git a/tests/data/utxo/elements_utxo_1.json b/tests/data/utxo/elements_utxo_1.json index 60198b5..730ae57 100644 --- a/tests/data/utxo/elements_utxo_1.json +++ b/tests/data/utxo/elements_utxo_1.json @@ -12,8 +12,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -39,8 +40,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -60,8 +62,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -81,8 +84,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -102,8 +106,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -123,8 +128,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -144,8 +150,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -165,8 +172,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -186,8 +194,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -207,8 +216,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -228,8 +238,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -249,8 +260,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -270,8 +282,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { diff --git a/tests/data/utxo/elements_utxo_2.json b/tests/data/utxo/elements_utxo_2.json index f62b868..5a20fdf 100644 --- a/tests/data/utxo/elements_utxo_2.json +++ b/tests/data/utxo/elements_utxo_2.json @@ -12,8 +12,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -39,8 +40,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -60,8 +62,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -81,8 +84,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -102,8 +106,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -123,8 +128,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -144,8 +150,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -165,8 +172,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -186,8 +194,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -207,8 +216,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -228,8 +238,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -249,8 +260,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -270,8 +282,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { diff --git a/tests/data/utxo/elements_utxo_3.json b/tests/data/utxo/elements_utxo_3.json index 2e4893a..9aacc26 100644 --- a/tests/data/utxo/elements_utxo_3.json +++ b/tests/data/utxo/elements_utxo_3.json @@ -12,8 +12,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -39,8 +40,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -60,8 +62,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -81,8 +84,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -102,8 +106,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -123,8 +128,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -144,8 +150,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -165,8 +172,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -186,8 +194,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -207,8 +216,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -228,8 +238,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -249,8 +260,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { @@ -270,8 +282,9 @@ "isIssuance": false, "isBlindIssuance": false, "isPegin": false, + "claimScript": "", "peginBtcTxSize": 0, - "fedpegScript": "", + "peginTxOutProofSize": 0, "assetBlindFactor": "", "blindFactor": "", "keyData": { diff --git a/tests/data/utxo/elements_utxo_4.json b/tests/data/utxo/elements_utxo_4.json new file mode 100644 index 0000000..5347412 --- /dev/null +++ b/tests/data/utxo/elements_utxo_4.json @@ -0,0 +1,73 @@ +[ + { + "base": true, + "memo": "The commitment is calculated from asset, amount and blinders.", + "txid": "", + "vout": 0, + "amount": 0, + "asset": "", + "redeemScript": "", + "descriptor": "", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": false, + "claimScript": "", + "peginBtcTxSize": 0, + "peginTxOutProofSize": 0, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + }, + { + "base": true, + "assetA": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225" + }, + { + "memo": "Elements CoinSelection UTXO.", + "txid": "2bc630021e76ab6bd7f8da54b0c59381e0265b093629e4384207030adba99775", + "vout": 0, + "amount": 150000000, + "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", + "redeemScript": "", + "descriptor": "sh(wpkh([b8f7f84b/0'/0'/4']029b382de02d1753b04f29e743ec988a7585e16f023d7c76fcb468133781465282))#jm9lh5q5", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": false, + "claimScript": "", + "peginBtcTxSize": 0, + "peginTxOutProofSize": 0, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + }, + { + "memo": "Elements CoinSelection UTXO.", + "txid": "42120c9e8adc1d0f0d843617a0c91d699a1eb67fb744dde21103d6423fa5c8c5", + "vout": 1, + "amount": 150000000, + "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", + "redeemScript": "", + "descriptor": "sh(wpkh([b8f7f84b/0'/0'/4']029b382de02d1753b04f29e743ec988a7585e16f023d7c76fcb468133781465282))#jm9lh5q5", + "scriptSigTemplate": "", + "isIssuance": false, + "isBlindIssuance": false, + "isPegin": false, + "claimScript": "", + "peginBtcTxSize": 0, + "peginTxOutProofSize": 0, + "assetBlindFactor": "", + "blindFactor": "", + "keyData": { + "privkey": "", + "blindingKey": "" + } + } +] \ No newline at end of file diff --git a/tests/test_address.py b/tests/test_address.py index b41e2b2..dd5a786 100644 --- a/tests/test_address.py +++ b/tests/test_address.py @@ -1,5 +1,4 @@ from unittest import TestCase -from unittest.main import main from tests.util import load_json_file, exec_test,\ assert_equal, assert_error, assert_match, assert_message from cfd.address import AddressUtil @@ -57,6 +56,7 @@ def test_address_func(obj, name, case, req, exp, error): elif name == 'Address.GetTapScriptTreeInfo': resp = {} nodes = [] + topNode = req['tree'][0] for node in req['tree'][1:]: if 'tapscript' in node: nodes.append(Script(node['tapscript'])) @@ -66,41 +66,38 @@ def test_address_func(obj, name, case, req, exp, error): nodes.append(ByteData(node['branchHash'])) pk = None if 'internalPubkey' not in req else SchnorrPubkey( req['internalPubkey']) - if 'tapscript' in req['tree'][0]: + if 'tapscript' in topNode: tree = TaprootScriptTree.create( - Script(req['tree'][0]['tapscript']), nodes, pk) - if 'internalPubkey' not in req: - tapleaf_hash = tree.get_base_hash() - resp = { - 'tapLeafHash': tapleaf_hash, - 'tapscript': tree.tapscript, - } + Script(topNode['tapscript']), nodes, pk) + tapleaf_hash = tree.get_base_hash() + resp['tapLeafHash'] = tapleaf_hash + resp['tapscript'] = tree.tapscript + elif 'treeString' in topNode: + tree = TapBranch(tree_str=topNode['treeString']) + tree.add_branches(nodes) + else: + tree = TapBranch(ByteData(topNode['branchHash'])) + tree.add_branches(nodes) + if 'internalPubkey' in req: + tap_data = tree.get_taproot_data(pk) + addr = AddressUtil.taproot( + pk, script_tree=tree, network=_network) + resp['tweakedPubkey'] = tap_data[0] + resp['controlBlock'] = tap_data[3] + resp['address'] = addr.address + resp['lockingScript'] = addr.locking_script + if 'internalPrivkey' in req: + tweak_privkey = tree.get_privkey( + Privkey(hex=req['internalPrivkey'])) + resp['tweakedPrivkey'] = tweak_privkey + nodes = [] + for node in tree.branches: + if isinstance(node, TapBranch): + nodes.append(node.get_current_hash()) else: - tap_data = tree.get_taproot_data() - addr = AddressUtil.taproot(tree, network=_network) - resp = { - 'tapLeafHash': tap_data[1], - 'tapscript': tap_data[2], - 'tweakedPubkey': tap_data[0], - 'controlBlock': tap_data[3], - 'address': addr.address, - 'lockingScript': addr.locking_script, - } - if 'internalPrivkey' in req: - tweak_privkey = tree.get_privkey( - Privkey(hex=req['internalPrivkey'])) - resp['tweakedPrivkey'] = tweak_privkey - nodes = [] - for node in tree.branches: - if isinstance(node, TapBranch): - nodes.append(node.get_current_hash()) - else: - nodes.append(str(node)) + nodes.append(str(node)) + if nodes and ('tapscript' in topNode): resp['nodes'] = nodes - elif 'treeString' in node: - tree = TapBranch(tree_str=node['treeString']) - else: - tree = TapBranch(ByteData(node['branchHash'])) resp['topBranchHash'] = tree.get_current_hash() resp['treeString'] = tree.as_str() @@ -126,7 +123,8 @@ def test_address_func(obj, name, case, req, exp, error): nodes.append(node.get_current_hash()) else: nodes.append(str(node)) - resp['nodes'] = nodes + if nodes: + resp['nodes'] = nodes if 'internalPrivkey' in req: tweak_privkey = tree.get_privkey( Privkey(hex=req['internalPrivkey'])) @@ -134,43 +132,46 @@ def test_address_func(obj, name, case, req, exp, error): elif name == 'Address.GetTapScriptTreeFromString': resp = {} + pk = None if 'internalPubkey' not in req else SchnorrPubkey( + req['internalPubkey']) if 'tapscript' in req: nodes = [ByteData(node) for node in req.get('nodes', [])] - pk = None if 'internalPubkey' not in req else SchnorrPubkey( - req['internalPubkey']) - tree = TaprootScriptTree.from_string( + tree = TaprootScriptTree.from_string_and_key( req['treeString'], Script(req['tapscript']), nodes, pk) - if pk is not None: - tap_data = tree.get_taproot_data() - addr = AddressUtil.taproot(tree, network=_network) - resp = { - 'tweakedPubkey': tap_data[0], - 'controlBlock': tap_data[3], - 'address': addr.address, - 'lockingScript': addr.locking_script, - } - if 'internalPrivkey' in req: - tweak_privkey = tree.get_privkey( - Privkey(hex=req['internalPrivkey'])) - resp['tweakedPrivkey'] = tweak_privkey resp['tapLeafHash'] = tree.get_base_hash() resp['tapscript'] = tree.tapscript - nodes = [] - for node in tree.branches: - if isinstance(node, TapBranch): - nodes.append(node.get_current_hash()) - else: - nodes.append(str(node)) - resp['nodes'] = nodes else: tree = TapBranch(tree_str=req['treeString']) + + if pk is not None: + tap_data = tree.get_taproot_data(pk) + addr = AddressUtil.taproot( + pk, script_tree=tree, network=_network) + resp = { + 'tweakedPubkey': tap_data[0], + 'controlBlock': tap_data[3], + 'address': addr.address, + 'lockingScript': addr.locking_script, + } + if 'internalPrivkey' in req: + tweak_privkey = tree.get_privkey( + Privkey(hex=req['internalPrivkey'])) + resp['tweakedPrivkey'] = tweak_privkey + nodes = [] + for node in tree.branches: + if isinstance(node, TapBranch): + nodes.append(node.get_current_hash()) + else: + nodes.append(str(node)) + if nodes and ('tapscript' in req): + resp['nodes'] = nodes resp['topBranchHash'] = tree.get_current_hash() resp['treeString'] = tree.as_str() elif name == 'Address.GetTapBranchInfo': resp = {} nodes = [ByteData(node) for node in req.get('nodes', [])] - tree = TaprootScriptTree.from_string( + tree = TaprootScriptTree.from_string_and_key( req['treeString'], Script(req.get('tapscript', '')), nodes) branch = tree.branches[req.get('index', 0)] resp['tapLeafHash'] = branch.get_base_hash() @@ -180,7 +181,8 @@ def test_address_func(obj, name, case, req, exp, error): nodes.append(node.get_current_hash()) else: nodes.append(str(node)) - resp['nodes'] = nodes + if nodes: + resp['nodes'] = nodes resp['topBranchHash'] = branch.get_current_hash() resp['treeString'] = branch.as_str() @@ -241,6 +243,8 @@ def collect_branch(branch): assert_match(obj, name, case, str(exp[key][index]), str(list_val), f'{key}:{index}') else: + if (key in exp) and (str(val) != exp[key]): + print(f'unmatch: {str(val)}') assert_equal(obj, name, case, exp, val, key) elif isinstance(resp, list): assert_match(obj, name, case, len(exp['addresses']), @@ -293,7 +297,7 @@ def collect_branch(branch): assert_equal(obj, name, case, exp, err.message) -def test_pegin_address_func(obj, name, case, req, exp, error): +def test_pegged_address_func(obj, name, case, req, exp, error): try: resp = None @@ -310,6 +314,18 @@ def test_pegin_address_func(obj, name, case, req, exp, error): 'tweakFedpegscript': ret[2], } + elif name == 'PegoutAddress.Create': + ret = AddressUtil.get_pegout_address( + descriptor=req['descriptor'], + bip32_counter=req.get('bip32Counter', 0), + hash_type=req.get('hashType', 'p2pkh'), + mainchain_network=req.get('network', 'mainnet'), + elements_network=req.get('elementsNetwork', 'liquidv1')) + resp = { + 'mainchainAddress': ret[0], + 'baseDescriptor': ret[1], + } + else: raise Exception('unknown name: ' + name) assert_error(obj, name, case, error) @@ -321,6 +337,11 @@ def test_pegin_address_func(obj, name, case, req, exp, error): str(resp['claimScript']), 'claimScript') assert_equal(obj, name, case, exp, str(resp['tweakFedpegscript']), 'tweakFedpegscript') + elif name == 'PegoutAddress.Create': + assert_equal(obj, name, case, exp, + str(resp['mainchainAddress']), 'mainchainAddress') + assert_equal(obj, name, case, exp, + str(resp['baseDescriptor']), 'baseDescriptor') except CfdError as err: if not error: @@ -354,4 +375,7 @@ def setUp(self): self.test_list = load_json_file('elements_address_test.json') def test_pegin_address(self): - exec_test(self, 'PeginAddress', test_pegin_address_func) + exec_test(self, 'PeginAddress', test_pegged_address_func) + + def test_pegout_address(self): + exec_test(self, 'PegoutAddress', test_pegged_address_func) diff --git a/tests/test_block.py b/tests/test_block.py new file mode 100644 index 0000000..9c9819f --- /dev/null +++ b/tests/test_block.py @@ -0,0 +1,78 @@ +from unittest import TestCase +from tests.util import load_json_file, exec_test,\ + assert_equal, assert_error, assert_match +from cfd.util import CfdError +from cfd.block import Block + + +def test_block_func(obj, name, case, req, exp, error): + try: + block = '' + if req.get('isElements', False): + raise Exception('isElements=True not support. name: ' + name) + else: + block = Block(req['block']) + + if name == 'Block.GetBlockInfo': + hash = block.get_blockhash() + header = block.get_header() + txid_list = block.get_txid_list() + txs = [str(txid) for txid in txid_list] + resp = { + 'blockHash': str(hash), + 'tx': txs, + 'version': header.version, + 'previousblockhash': str(header.prev_block_hash), + 'merkleroot': str(header.merkleroot), + 'time': header.time, + 'bits': header.bits, + 'nonce': header.nonce, + } + elif name == 'Block.GetTxDataFromBlock': + tx, txoutproof = block.get_tx_data(req['txid']) + resp = {'tx': str(tx), 'txoutproof': str(txoutproof)} + elif name == 'Block.ExistTxid': + exist = block.exist_txid(req['txid']) + resp = {'exist': exist} + elif name == 'Block.GetTxCount': + count = block.get_tx_count() + resp = {'count': count} + else: + raise Exception('unknown name: ' + name) + assert_error(obj, name, case, error) + + if name == 'Block.GetBlockInfo': + assert_equal(obj, name, case, exp, resp['blockHash'], 'blockHash') + assert_equal(obj, name, case, exp, resp['version'], 'version') + assert_equal(obj, name, case, exp, + resp['previousblockhash'], 'previousblockhash') + assert_equal(obj, name, case, exp, + resp['merkleroot'], 'merkleroot') + assert_equal(obj, name, case, exp, resp['time'], 'time') + assert_equal(obj, name, case, exp, resp['bits'], 'bits') + assert_equal(obj, name, case, exp, resp['nonce'], 'nonce') + assert_match(obj, name, case, len( + exp['tx']), len(resp['tx']), 'tx.len') + for i in range(len(exp['tx'])): + assert_match(obj, name, case, + exp['tx'][i], resp['tx'][i], f'tx.len.{i}') + elif ('tx' in resp) and isinstance(resp['tx'], str): + assert_equal(obj, name, case, exp, resp['tx'], 'tx') + + assert_equal(obj, name, case, exp, + resp.get('txoutproof', ''), 'txoutproof') + assert_equal(obj, name, case, exp, resp.get('exist', False), 'exist') + assert_equal(obj, name, case, exp, resp.get('count', 0), 'count') + + except CfdError as err: + if not error: + raise err + assert_equal(obj, name, case, exp, err.message) + + +class TestBlock(TestCase): + def setUp(self): + self.test_list = load_json_file('block_test.json') + + def test_block(self): + exec_test(self, 'Block', test_block_func) diff --git a/tests/test_confidential_transaction.py b/tests/test_confidential_transaction.py index 957917f..911a59a 100644 --- a/tests/test_confidential_transaction.py +++ b/tests/test_confidential_transaction.py @@ -100,7 +100,8 @@ def get_tx(): mainchain_genesis_block_hash=block_hash, online_pubkey=pegout['onlinePubkey'], master_online_key=pegout['masterOnlineKey'], - mainchain_output_descriptor=pegout['bitcoinDescriptor'], + mainchain_output_descriptor=pegout.get( + 'bitcoinDescriptor', ''), bip32_counter=pegout['bip32Counter'], whitelist=pegout['whitelist']) btc_addresses.append(addr) @@ -146,6 +147,10 @@ def get_tx(): resp.update_witness_stack( OutPoint(txin['txid'], txin['vout']), witness.get('index', 0), data) + elif name == 'ConfidentialTransaction.UpdateTxInSequence': + resp, _, _ = get_tx() + resp.update_sequence( + OutPoint(req['txid'], req['vout']), req['sequence']) elif name == 'ConfidentialTransaction.UpdatePeginWitnessStack': resp, _, _ = get_tx() txin = req['txin'] @@ -355,10 +360,13 @@ def get_tx(): def test_ct_transaction_func3(obj, name, case, req, exp, error): try: + tx_obj = None if name == 'ConfidentialTransaction.Decode': + tx_hex = req.get('hex', '') resp = ConfidentialTransaction.parse_to_json( - req.get('hex', ''), req.get('network', 'mainnet'), + tx_hex, req.get('network', 'mainnet'), req.get('fullDump', False)) + tx_obj = ConfidentialTransaction(tx_hex) elif name == 'ConfidentialTransaction.CreateSighash': resp = ConfidentialTransaction.from_hex(req['tx']) txin = req['txin'] @@ -409,6 +417,24 @@ def test_ct_transaction_func3(obj, name, case, req, exp, error): exp_json = exp_json.replace(': ', ':') assert_match(obj, name, case, exp_json, resp, 'json') + + # pegout output check + sidechain_network = req.get('network', 'liquidv1') + mainchain_network = Network.REGTEST + if sidechain_network == Network.LIQUID_V1: + mainchain_network = Network.MAINNET + for vout in exp['vout']: + addrs = vout.get('scriptPubKey', {}).get( + 'pegout_addresses', '') + if isinstance(addrs, list): + idx = vout['n'] + exp_addr = addrs[0] + has_pegout = tx_obj.has_pegout(idx) + addr = tx_obj.get_pegout_address(idx, mainchain_network) + assert_match(obj, name, case, True, + has_pegout, f'hasPegout:${idx}') + assert_match(obj, name, case, exp_addr, + str(addr), f'pegoutAddr:${idx}') elif name == 'ConfidentialTransaction.GetWitnessStackNum': assert_equal(obj, name, case, exp, resp, 'count') elif name == 'Transaction.GetTxInIndex': @@ -982,27 +1008,30 @@ def test_elements_tx_func(obj, name, case, req, exp, error): resp = tx.estimate_fee( utxo_list, fee_rate=req.get('feeRate', 0.15), fee_asset=req.get('feeAsset', ''), - is_blind=req.get('isBlind', True), + is_blind=req.get('isBlind', + req.get('isBlindEstimateFee', True)), exponent=req.get('exponent', 0), minimum_bits=req.get('minimumBits', 52)) elif name == 'Elements.FundTransaction': tx = ConfidentialTransaction.from_hex(req['tx']) txin_utxo_list = convert_elements_utxo(req['selectUtxos']) - utxo_list = obj.utxos.get(req['utxoFile'], []) + utxo_list = obj.utxos.get(req.get('utxoFile', ''), []) target_list = convert_target_amount(req['targets']) fee_info = req.get('feeInfo', {}) tx_fee, used_addr_list = tx.fund_raw_transaction( txin_utxo_list, utxo_list, target_list, - fee_asset=fee_info.get('feeAsset', -1), + fee_asset=fee_info.get('feeAsset', ''), effective_fee_rate=fee_info.get('feeRate', 20.0), long_term_fee_rate=fee_info.get('longTermFeeRate', 20.0), dust_fee_rate=fee_info.get('dustFeeRate', 3.0), knapsack_min_change=fee_info.get('knapsackMinChange', -1), - is_blind=req.get('isBlind', True), - exponent=req.get('exponent', 0), - minimum_bits=req.get('minimumBits', 52)) + is_blind=fee_info.get('isBlind', + fee_info.get( + 'isBlindEstimateFee', True)), + exponent=fee_info.get('exponent', 0), + minimum_bits=fee_info.get('minimumBits', 52)) resp = {'hex': str(tx), 'usedAddresses': used_addr_list, 'feeAmount': tx_fee} else: @@ -1031,9 +1060,15 @@ def test_elements_tx_func(obj, name, case, req, exp, error): total_amount_map[str(exp_amount_data.asset)], 'selectedAmounts:{}:amount'.format( exp_amount_data.asset)) + if utxo_fee != 0: + feeAmount = fee_info.get('txFeeAmount', 0) + utxo_fee + assert_equal(obj, name, case, exp, feeAmount, 'feeAmount') elif name == 'Elements.EstimateFee': total_fee, txout_fee, utxo_fee = resp - assert_equal(obj, name, case, exp, total_fee, 'feeAmount') + if (exp['feeAmount'] != total_fee) and ( + exp['feeAmount'] + 1 != total_fee): + assert_equal(obj, name, case, exp, total_fee, 'feeAmount') + # It is not an exact value because it is just an addition. assert_equal(obj, name, case, exp, txout_fee, 'txoutFeeAmount') assert_equal(obj, name, case, exp, utxo_fee, 'utxoFeeAmount') elif name == 'Elements.FundTransaction': @@ -1073,7 +1108,8 @@ def convert_elements_utxo(json_utxo_list): is_blind_issuance=utxo.get('isBlindIssuance', True), is_pegin=utxo.get('isPegin', False), pegin_btc_tx_size=utxo.get('peginBtcTxSize', 0), - fedpeg_script=utxo.get('fedpegScript', ''), + pegin_txoutproof_size=utxo.get('peginTxOutProofSize', 0), + claim_script=utxo.get('claimScript', ''), asset_blinder=utxo.get('assetBlindFactor', ''), amount_blinder=utxo.get('blindFactor', '')) utxo_list.append(data) @@ -1119,6 +1155,8 @@ def setUp(self): get_json_file('utxo/elements_utxo_2.json')) self.utxos['elements_utxo_3'] = convert_elements_utxo( get_json_file('utxo/elements_utxo_3.json')) + self.utxos['elements_utxo_4'] = convert_elements_utxo( + get_json_file('utxo/elements_utxo_4.json')) def test_confidential_transaction(self): exec_test(self, 'ConfidentialTransaction', test_ct_transaction_func) diff --git a/tests/test_elements.py b/tests/test_elements.py index 261710c..075f839 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -2,7 +2,8 @@ from tests.util import load_json_file,\ exec_test, assert_equal, assert_error from cfd.util import CfdError -from cfd.confidential_transaction import ConfidentialAsset, ConfidentialValue +from cfd.confidential_transaction import ConfidentialAsset, \ + ConfidentialValue, UnblindData def test_elements_func(obj, name, case, req, exp, error): @@ -16,6 +17,19 @@ def test_elements_func(obj, name, case, req, exp, error): asset_commitment, req['blindFactor']) resp = {'assetCommitment': str(asset_commitment), 'amountCommitment': str(amount_commitment)} + elif name == 'Elements.UnblindData': + data: UnblindData = UnblindData.unblind( + blinding_key=req['blindingKey'], + locking_script=req['lockingScript'], + asset_commitment=req['assetCommitment'], + value_commitment=req['valueCommitment'], + commitment_nonce=req['commitmentNonce'], + rangeproof=req['rangeproof'], + ) + resp = {'asset': str(data.asset), + 'amount': int(data.value.amount), + 'blindFactor': str(data.amount_blinder), + 'assetBlindFactor': str(data.asset_blinder)} else: raise Exception('unknown name: ' + name) assert_error(obj, name, case, error) @@ -25,6 +39,15 @@ def test_elements_func(obj, name, case, req, exp, error): 'assetCommitment') assert_equal(obj, name, case, exp, resp['amountCommitment'], 'amountCommitment') + elif 'blindFactor' in exp: + assert_equal(obj, name, case, exp, resp['asset'], + 'asset') + assert_equal(obj, name, case, exp, resp['amount'], + 'amount') + assert_equal(obj, name, case, exp, resp['blindFactor'], + 'blindFactor') + assert_equal(obj, name, case, exp, resp['assetBlindFactor'], + 'assetBlindFactor') except CfdError as err: if not error: diff --git a/tests/test_psbt.py b/tests/test_psbt.py index 01a3e6e..c25c775 100644 --- a/tests/test_psbt.py +++ b/tests/test_psbt.py @@ -580,9 +580,9 @@ def test_psbt_func(obj, name, case, req, exp, error): utxos = [] desc = req['reservedDescriptor'] fee_rate = req['feeInfo']['feeRate'] - long_term_fee_rate = req['feeInfo']['longTermFeeRate'] + long_term_fee_rate = req['feeInfo'].get('longTermFeeRate', 20.0) knapsack_min_change = req['feeInfo']['knapsackMinChange'] - dust_fee_rate = req['feeInfo']['dustFeeRate'] + dust_fee_rate = req['feeInfo'].get('dustFeeRate', 3.0) for utxo in req.get('utxos', []): utxos.append( UtxoData( diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 02a825c..2d33c57 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -85,6 +85,9 @@ def test_transaction_func1(obj, name, case, req, exp, error): resp.update_witness_stack( OutPoint(txin['txid'], txin['vout']), witness.get('index', 0), data) + elif name == 'Transaction.UpdateTxInSequence': + resp.update_sequence( + OutPoint(req['txid'], req['vout']), req['sequence']) else: return False assert_error(obj, name, case, error) diff --git a/tools/build_and_test_for_docker.sh b/tools/build_and_test_for_docker.sh new file mode 100755 index 0000000..fb12912 --- /dev/null +++ b/tools/build_and_test_for_docker.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +if [ -n "$CFD_SRC" ]; then +BASEDIR=$CFD_SRC +else +BASEDIR=`git rev-parse --show-toplevel` +fi + +if [ -z "$BASEDIR" ]; then +exit 1 +fi + +cd $BASEDIR + +if [ -n "$CFD_WORK" ]; then +WORKDIR=$CFD_WORK +else +WORKDIR=temp +fi + +echo "BASEDIR=$BASEDIR" +echo "WORKDIR=$WORKDIR" + +if [ -z "$WORKDIR" ]; then +exit 1 +fi + +rm -rf $WORKDIR/* +mkdir $WORKDIR +mkdir $WORKDIR/external +mkdir $WORKDIR/dist + +cp CMakeLists.txt $WORKDIR/ +cp VERSION $WORKDIR/ +cp LICENSE $WORKDIR/ +cp setup.* $WORKDIR/ +cp *.toml $WORKDIR/ +cp *.in $WORKDIR/ +cp *.md $WORKDIR/ +cp -rp cmake $WORKDIR/cmake +cp -rp external/CMakeLists.txt $WORKDIR/external +cp -rp external/template_CMakeLists.txt.in $WORKDIR/external +cp -rp local_resource $WORKDIR/local_resource +cp -rp cfd $WORKDIR/cfd +cp -rp tools $WORKDIR/tools +cp -rp tests $WORKDIR/tests +cp -rp tests $WORKDIR/tests + +cd $WORKDIR +if [ $? -gt 0 ]; then + echo "change directory NG." + exit 1 +fi + +echo "configure start." + +PATH=$PATH:/usr/local/bin + +pip3 install wheel pipenv +if [ $? -gt 0 ]; then + echo "pip3 install NG." + exit 1 +fi + +pipenv install -d +if [ $? -gt 0 ]; then + echo "pipenv install NG." + exit 1 +fi + +# pipenv run build +python3 ./setup.py build +if [ $? -gt 0 ]; then + echo "cmake build NG." + exit 1 +fi + +# pipenv run test +python3 -m unittest discover -v tests +if [ $? -gt 0 ]; then + echo "test NG." + exit 1 +fi