Taproot – Earlybirds Invest https://earlybirdsinvest.com Latest Crypto News Fri, 08 Aug 2025 02:51:20 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.7 https://i0.wp.com/earlybirdsinvest.com/wp-content/uploads/2024/12/cropped-New-Project-2024-12-17T235703.455.png?fit=32%2C32&ssl=1 Taproot – Earlybirds Invest https://earlybirdsinvest.com 32 32 240146708 Create a forwarding script using TapRoot address P2TR https://earlybirdsinvest.com/create-a-forwarding-script-using-taproot-address-p2tr/ https://earlybirdsinvest.com/create-a-forwarding-script-using-taproot-address-p2tr/#respond Fri, 08 Aug 2025 02:51:20 +0000 https://earlybirdsinvest.com/create-a-forwarding-script-using-taproot-address-p2tr/

I’m trying to create a transfer script.

The entire script was provided below

import * as bitcoin from "bitcoinjs-lib";
import * as tinysecp from "tiny-secp256k1";
import axios from "axios";
import ECPairFactory from "ecpair";

const ECPair = ECPairFactory(tinysecp);
bitcoin.initEccLib(tinysecp);

const NETWORK = bitcoin.networks.testnet;
const MEMPOOL_API = "https://mempool.space/testnet/api";

// Helper function to validate UTXO
function validateUtxo(utxo: any): void {
  if (
    !utxo.txid ||
    typeof utxo.vout !== "number" ||
    typeof utxo.value !== "number"
  ) {
    throw new Error("Invalid UTXO structure");
  }
  if (!/^(a-fA-F0-9){64}$/.test(utxo.txid)) {
    throw new Error("Invalid UTXO txid format");
  }
}

export async function sendBTC_P2TR({
  wif,
  recipient,
  amountSats,
}: {
  wif: string;
  recipient: string;
  amountSats: number;
}): Promise<{ success: boolean; message: string; txId?: string }> {
  try {
    console.log("🏁 Starting transaction process...");

    // Input validation
    if (!wif || !recipient || !amountSats) {
      throw new Error("Missing required parameters");
    }
    if (typeof amountSats !== "number" || amountSats <= 0) {
      throw new Error("Invalid amount");
    }
    if (!recipient.startsWith("tb1p")) {
      throw new Error("Recipient must be a Taproot testnet address");
    }

    // Key derivation
    const keyPair = ECPair.fromWIF(wif, NETWORK);
    if (!keyPair.privateKey) throw new Error("No private key derived from WIF");

    const privateKey = keyPair.privateKey;
    const internalPubkey = Buffer.from(
      tinysecp.pointFromScalar(privateKey, true)!.slice(1)
    );

    const p2tr = bitcoin.payments.p2tr({ internalPubkey, network: NETWORK });
    const address = p2tr.address!;
    const scriptPubKey = p2tr.output!;

    console.log("📬 Sender Taproot address:", address);

    // Fetch UTXOs
    const { data: utxos } = await axios.get(
      `${MEMPOOL_API}/address/${address}/utxo`
    );
    if (!utxos.length) return { success: false, message: "No UTXOs found" };

    // Estimate fee
    const { data: fees } = await axios.get(
      `${MEMPOOL_API}/v1/fees/recommended`
    );
    const feeRate = Math.max(fees.hourFee || 1, 2);
    const fee = Math.ceil(feeRate * 110); // Estimated vsize for P2TR

    // Select UTXO
    const utxo = utxos.find((u: any) => u.value >= amountSats + fee);
    if (!utxo)
      return {
        success: false,
        message: `No suitable UTXO found (needed ${amountSats + fee} sats)`,
      };

    // Key tweaking
    const tweak = bitcoin.crypto.taggedHash("TapTweak", internalPubkey);
    let tweakedPrivKey = tinysecp.privateAdd(privateKey, tweak);
    if (!tweakedPrivKey) throw new Error("Failed to tweak private key");

    // Build PSBT
    const psbt = new bitcoin.Psbt({ network: NETWORK });
    psbt.addInput({
      hash: utxo.txid,
      index: utxo.vout,
      witnessUtxo: { script: scriptPubKey, value: utxo.value },
      tapInternalKey: internalPubkey,
    });

    psbt.addOutput({ address: recipient, value: amountSats });
    const change = utxo.value - amountSats - fee;
    if (change > 294) {
      // Dust limit
      psbt.addOutput({ address, value: change });
    }

    // Signing (fixed approach)
    const tx = (psbt as any).__CACHE.__TX as bitcoin.Transaction;
    const hash = tx.hashForWitnessV1(0, (scriptPubKey), (utxo.value), 0x00);
    const signature = Buffer.from(tinysecp.signSchnorr(hash, tweakedPrivKey));

    // Update with proper signature format
    psbt.updateInput(0, {
      tapKeySig: signature,
    });

    // Final verification
    const validator = (pubkey: Buffer, msghash: Buffer, sig: Buffer) => {
      return tinysecp.verifySchnorr(msghash, pubkey, sig);
    };
    psbt.validateSignaturesOfInput(0, validator);

    psbt.finalizeAllInputs();
    const txHex = psbt.extractTransaction().toHex();

    // Broadcast
    const { data: txId } = await axios.post(`${MEMPOOL_API}/tx`, txHex, {
      headers: { "Content-Type": "text/plain" },
    });

    return { success: true, message: "Transaction broadcasted", txId };
  } catch (error: any) {
    console.error("Transaction failed:", error.message);
    return {
      success: false,
      message: error?.response?.data || error?.message || "Unknown error",
    };
  }
}

However, I’m facing an error that I can’t understand why

Transaction failed: Request failed with status code 400
❌ Transaction failed: sendrawtransaction RPC error: {"code":-26,"message":"mandatory-script-verify-flag-failed (Invalid Schnorr signature)"}

]]>
https://earlybirdsinvest.com/create-a-forwarding-script-using-taproot-address-p2tr/feed/ 0 52071
Why isn’t the Taproot Transaction Builder (BuildTaproottx using @cmdcode/tapscript) working as expected? https://earlybirdsinvest.com/why-isnt-the-taproot-transaction-builder-buildtaproottx-using-cmdcode-tapscript-working-as-expected/ https://earlybirdsinvest.com/why-isnt-the-taproot-transaction-builder-buildtaproottx-using-cmdcode-tapscript-working-as-expected/#respond Wed, 06 Aug 2025 23:50:26 +0000 https://earlybirdsinvest.com/why-isnt-the-taproot-transaction-builder-buildtaproottx-using-cmdcode-tapscript-working-as-expected/

I wrote the following function to build and sign a Taproot (P2TR) transaction using @cmdcode/tapscript: My intention is to support spending on both key and script paths.

The problem is that it doesn’t work as expected.

Script-Path spending often fails validation (e.g. block error, invalid witness, or failed script execution).

Can someone review my code and point out what’s wrong with my logic or implementation? I especially appreciate the advice on how to fix performance improvements in script path failures and key path cases.

import { Address, Signer, Tap, Tx } from '@cmdcode/tapscript';

protected buildTaprootTx(
  senderKey: { publicKey: Uint8Array; privateKey: Uint8Array },
  utxos: Array<{ txid: string; vout: number; value: number }>,
  recipient: string,
  amountSat: number,
  feeSat: number,
  mode: 'key' | 'script' | 'both',
  scriptLeaves: Array = (),
  opReturnData?: Uint8Array | string,
  changeAddr?: string
): string {
  // ... (full code as in my gist, see link below)
}

Complete code

question:

  • What am I doing wrong, especially when it comes to script path spending?

  • Is there a better way to configure or optimize features for performance and accuracy?

  • If you find any obvious bugs or misconceptions in how you use TapRoot key/Script Path Logic, please point them out.

Code reviews, suggestions, or references to practical examples are highly appreciated. thank you!

]]>
https://earlybirdsinvest.com/why-isnt-the-taproot-transaction-builder-buildtaproottx-using-cmdcode-tapscript-working-as-expected/feed/ 0 51866
How Taproot Upgrade Improves Bitcoin Privacy and Scalability? https://earlybirdsinvest.com/how-taproot-upgrade-improves-bitcoin-privacy-and-scalability/ https://earlybirdsinvest.com/how-taproot-upgrade-improves-bitcoin-privacy-and-scalability/#respond Fri, 01 Aug 2025 09:56:52 +0000 https://earlybirdsinvest.com/how-taproot-upgrade-improves-bitcoin-privacy-and-scalability/

Bitcoin is the leading cryptocurrency, which introduced the world to the magic of decentralized cash. The primary strengths of Bitcoin are decentralization and its robust security infrastructure. Everything seems right about Bitcoin until you notice the limitations that it has shown as a result of growing adoption. The two biggest limitations of Bitcoin blockchain holding it back include privacy and scalability.

The introduction of Taproot upgrade improves Bitcoin privacy and also addresses the scalability concerns. Bitcoin introduced the Taproot upgrade in 2021 and it has helped in achieving significant improvements by making Bitcoin transactions more flexible, private, and efficient. Let us learn more about the Taproot upgrade and its implications for the future of Bitcoin.

Advance your career with in-demand Bitcoin expertise—enroll in the Certified Bitcoin Professional (CBP)™ Certification today.

Reasons to Introduce the Taproot Upgrade

Before learning about the Taproot upgrade, you must know about the reasons that called for the upgrade. The original design of Bitcoin created a revolutionary impact by showcasing a decentralized electronic cash system. On the other hand, some of the characteristics of Bitcoin required improvement, which became clearly visible as Bitcoin gained more users. The following factors can help you understand the rationale behind introducing the Taproot upgrade on the Bitcoin blockchain. 

  • Reduced Transaction Privacy 

One of the most noticeable benefits of Bitcoin transactions is the assurance of anonymity as they are linked to pseudonymous identities. However, analyzing the transactions can reveal patterns that can harm user privacy. Complex transactions like multi-signature transactions and the ones involving smart contracts leave a discernible audit trail on the Bitcoin blockchain. Anyone can differentiate simple payments from more complex agreements, thereby creating risks for user privacy. For example, anyone can identify a multi-signature transaction by checking the number of parties involved in a transaction. 

The arrival of the Bitcoin Taproot BIP upgrade also aims to address the smart contract limitations on Bitcoin blockchain. Bitcoin scripting provides the flexibility to incorporate simple smart contracts on the Bitcoin blockchain. Complex smart contracts on Bitcoin will require verbose scripts that take up significant block space and reduced privacy. The Taproot upgrade aimed to facilitate the creation of sophisticated dApps directly on the Bitcoin blockchain without sacrificing its core traits.

Another notable objective behind introducing the Bitcoin Taproot upgrade revolves around addressing the threat of scalability challenges. The blockchain size limit and transaction processing speed of Bitcoin have always been considered as its limitations. No one would have thought that these issues would ultimately lead to scalability challenges in the long run. With more users adopting Bitcoin and complex transactions, the Bitcoin blockchain experiences network congestion, thereby resulting in higher transaction fees. The scalability issues affect the overall user experience as the transaction fees can be extremely high for smaller transactions.

Enroll now in the Blockchain Scalability and Interoperability Mastery Course to learn the skills needed to develop faster, scalable, robust, and interoperable dApps.

Design of the Taproot Upgrade

The challenges responsible for introducing the Taproot upgrade on Bitcoin don’t qualify as critical flaws. On the contrary, the challenges showed potential areas where Bitcoin can improve to meet the growing requirements of its users. The answers to “What is the Taproot upgrade for Bitcoin?” reveal that the Bitcoin network devised the upgrade to enhance the network without disrupting the fundamental architecture or introducing new risks.

While many people assume that Taproot is a single feature, it represents a combination of three different BIP or Bitcoin Improvement Proposals. The three components work in unison to achieve promising improvement in smart contract functionality, privacy and scalability. The following components of the Taproot upgrade showcase why it plays a pivotal role in addressing the privacy and scalability challenges.

The core component of the Taproot upgrade, Schnorr Signatures, is a BIP 340 improvement proposal that makes transaction verification more efficient. Prior to Taproot, Bitcoin relied on the Elliptic Curve Digital Signature Algorithm to verify transactions. Irrespective of the security benefits of ECDSA, you can notice the following enhancements with Schnorr Signatures.  

  • Improvement in Transaction Privacy

Schnorr Signatures make complex and multi-signature transactions completely indistinguishable from simple transactions that require single signatures, thereby improving transaction privacy. External observers cannot identify complex transactions or the number of parties involved in transactions due to Schnorr Signatures. The effect of the BIP 340 improvement in Taproot ensures that all Bitcoins are fungible and cannot be distinguished from other Bitcoins. 

The advantages of Taproot also draw attention to the facility of signature aggregation with Schnorr Signatures. It is a feature that can make a Taproot Bitcoin wallet more private by allowing the combination of multiple signatures from different parties into one compact signature. Let us think of a scenario where you need multiple people to sign a Bitcoin transaction from a shared wallet. Schnorr Signatures ensures that the three signatures are combined into one signature, thereby enhancing privacy.

  • Batch Verification and Efficient Transactions

Another significant benefit of Schnorr Signatures in the Taproot upgrade is batch verification. Nodes can verify multiple Schnorr signatures, thereby reducing computational burden on nodes, which results in network efficiency and better scalability. On top of it, a single Schnorr Signature takes less block space than multiple ECDSA signatures. Therefore, complex transactions would involve lower transaction fees, which translate into scalability improvements.

  • Merkelized Abstract Syntax Tree or MAST

The Merkelized Abstract Syntax Tree or MAST is another core component of the Taproot upgrade. As the name implies, it draws inspiration from Merkle Trees and serves the benefit of introducing private Bitcoin smart contracts. MAST helps in achieving the following benefits for the Bitcoin blockchain.

  • Privacy for Complex Transactions

MAST serves a major role in ensuring that the Taproot upgrade improves privacy for complex transactions. It reveals only the path followed in a smart contract rather than all the execution paths, thereby boosting privacy. Third parties or external observers have to struggle to know the complete scope of multi-party agreements and various backups. 

The approach to reveal only the necessary details in MAST ensures significant reduction in the amount of data required for complex transactions. You can see how the Taproot upgrade improves scalability by making transaction size smaller. Reduced transaction size ensures that you can fit more transactions in a block, thereby reducing network congestion and improving overall efficiency of Bitcoin.

  • Non-disclosure of Unused Spending Conditions 

The MAST component of the Taproot upgrade also addresses the problem of multiple spending conditions in some smart contracts. With the arrival of MAST, Bitcoin will ensure more privacy by revealing only the condition met before execution. The other conditions which remain unexecuted will stay hidden in a Merkle tree structure.

  • Enhancing Bitcoin Script with Taproot

The third and most crucial component of the Taproot upgrade, Tapscript, serves an updated scripting language for the Bitcoin blockchain. Tapscript works along with Schnorr Signatures and MAST to offer the following advantages.

Tapscript might seem like a technical nightmare for some users. On the other hand, it ensures simplification of various aspects of Bitcoin scripting. Developers can rely on Tapscript for writing complex smart contracts and transaction logic, thereby enabling more secure and efficient smart contract deployments.

  • Preparing Bitcoin for the Future

Tapscript is a Bitcoin Taproot BIP upgrade which contains a set of rules for Bitcoin scripting. Tapscript helps the Bitcoin network in understanding and processing transactions that utilize MAST and Schnorr Signatures. It provides clear guidelines for interaction between the new upgrade components and existing Bitcoin scripting capabilities. Tapscript also prepares Bitcoin for the future by providing a flexible framework to implement upgrades to Bitcoin scripting language in future.

Enroll now in the Bitcoin Technology Course to learn about Bitcoin mining and the information contained in transactions and blocks.

Real Impact of the Taproot Upgrade

The real impact of the Taproot upgrade is yet to be seen as it has not achieved full-scale adoption. However, you can notice that many Bitcoin wallets have been integrating Taproot addresses. The transition of more users to Taproot addresses will spread the word about the privacy and efficiency benefits of the upgrade. 

While the Taproot Bitcoin wallet adoption is still growing, users have pointed out promising improvements in user experience on the Lightning Network. The Lightning Network has become better with integration of Taproot-compatible features that will ensure more efficient and private off-chain transactions.

The most profound impact of the Taproot upgrade on Bitcoin is visible in the rise of new protocols and use cases on the Bitcoin blockchain. If you had said the same thing about Bitcoin 10 years ago, no one would have believed you. With the Taproot upgrade rolling out gradually, the Bitcoin blockchain enabled support for BRC-20 tokens and Bitcoin Ordinals. The innovative developments with Taproot upgrade ensure that Bitcoin will serve as the foundation for new types of applications and digital assets. 

Final Thoughts 

The Taproot upgrade is one of the notable milestones in the evolutionary journey of Bitcoin. A review of answers to “What is the Taproot upgrade for Bitcoin?” reveals that the Taproot upgrade includes three core components. Schnorr Signatures, MAST and Tapscript work in unison to ensure that Bitcoin grows beyond the identity of being only a cryptocurrency. Taproot has reduced transaction size and fees, thereby opening new avenues for improving scalability. On top of it, the Taproot upgrade ensures that external observers can only view relevant details of Bitcoin transactions. Furthermore, Tapscript governs the use of Schnorr Signatures and MAST while establishing the foundation for new use cases and protocols on Bitcoin. If you want to dive deeper into these innovations, consider earning a Bitcoin Certification to strengthen your expertise

Unlock your career with 101 Blockchains' Learning Programs

*Disclaimer: The article should not be taken as, and is not intended to provide any investment advice. Claims made in this article do not constitute investment advice and should not be taken as such. 101 Blockchains shall not be responsible for any loss sustained by any person who relies on this article. Do your own research!

]]>
https://earlybirdsinvest.com/how-taproot-upgrade-improves-bitcoin-privacy-and-scalability/feed/ 0 50842
Unable to get TapRoot address using Bitcoinlib https://earlybirdsinvest.com/unable-to-get-taproot-address-using-bitcoinlib/ https://earlybirdsinvest.com/unable-to-get-taproot-address-using-bitcoinlib/#respond Sat, 19 Jul 2025 00:18:49 +0000 https://earlybirdsinvest.com/unable-to-get-taproot-address-using-bitcoinlib/

I’ve tried several methods to get the Taproot address from the private key using Bitcoinlib, but I’ve continued to get a different address than what you get with a Taproot wallet, such as Unisat or OKX wallet.

Then, after many attempts, I found the command Address.parse And I tried to use it to get all the parameters of the address to replicate it.

Surprisingly, even if you create a class with exactly the same parameters and of course the same private key, the derived addresses will be different.

from bitcoinlib.keys import Key, Address

# keys are for testing purposes
private_key_hex = '25eee8288d42567475d1453843ce57b16b6ba5b6c0661cb2a439fff44c4d455d'
private_key_wif="KxVSwjuqNb6qe3KTLsHG5nYA3WFEqrjyKnGbwgHAreiWsqrwffuh"

k = Key(private_key_wif)
#k.info()
public_key_hex = '02fdf741bc2b1efe52873d748ca438798ad0133b25c388bc50423aed26df8ffbd7'
public_key_hex_uncompressed = '04fdf741bc2b1efe52873d748ca438798ad0133b25c388bc50423aed26df8ffbd7db6b1b700bd2475709f586d7a0105d29b0e4a3017b259e01bc32b220342ab33a'

addr = Address.parse('bc1pfkde37d8chuqa6tgwvp7rwmtl7vvd20ql6g5433xxpdah30t7nushrsrlu')
print(addr.as_dict())

testAddr = Address(
    data = public_key_hex,
    hashed_data = None,
    prefix = 'bc',
    script_type="p2tr",
    compressed = None,
    encoding = 'bech32',
    witness_type="taproot",
    witver = 1,
    depth = None,
    change = None,
    address_index = None,
    network = 'bitcoin',
    network_overrides = None
)
print(testAddr)

I’m not sure if the problem is that it doesn’t have a Bith32M encoding.

If anyone knows how to solve this problem or a workaround, they’ll be really appreciated!

]]>
https://earlybirdsinvest.com/unable-to-get-taproot-address-using-bitcoinlib/feed/ 0 48421
Bitcoin Taproot Mutual Satisfaction Clause https://earlybirdsinvest.com/bitcoin-taproot-mutual-satisfaction-clause/ https://earlybirdsinvest.com/bitcoin-taproot-mutual-satisfaction-clause/#respond Mon, 16 Jun 2025 20:18:20 +0000 https://earlybirdsinvest.com/bitcoin-taproot-mutual-satisfaction-clause/ Bookmaster Bitcoin 3rd Edition, 179 pages.

Enter the image description here

Mast and Scriptless Multisignatures make it easy to design mutual satisfaction clauses. Simply make one of the top leaves of the script tree a scriptless multi-signature between all stakeholders. In Figure 7-7, we have already seen complex contracts between several parties with simple mutual satisfaction clauses. You can further optimize it by switching from scripted multi-signature to scriptless multi-signature.

What are the mutual satisfaction clauses in Figure 7-7? thank you.

]]>
https://earlybirdsinvest.com/bitcoin-taproot-mutual-satisfaction-clause/feed/ 0 42407
Why did Taproot retain a 520-byte push limit? https://earlybirdsinvest.com/why-did-taproot-retain-a-520-byte-push-limit/ https://earlybirdsinvest.com/why-did-taproot-retain-a-520-byte-push-limit/#respond Wed, 23 Apr 2025 18:16:09 +0000 https://earlybirdsinvest.com/why-did-taproot-retain-a-520-byte-push-limit/

It seems that the way you think about it is backwards. You need to claim it is safe remove DOS limit. It must be in the default position to hold it. Especially as other restrictions have been lifted.

For example, if there is no stack element size limit, you can use the following tap script to create a script that uses ~4GB of memory to verify:

<396000 bytes push> OP_3DUP OP_3DUP .. OP_3DUP

At 333 OP_3DUPs This creates a stack with 1000 3.96MB elements and uses about 3.96GB of memory to store them. Of course, there’s more you can do, but the memory explosion is probably the most obvious example.

]]>
https://earlybirdsinvest.com/why-did-taproot-retain-a-520-byte-push-limit/feed/ 0 32431
Taproot Wizards Announces Mint Schedule, Coming March 25 https://earlybirdsinvest.com/taproot-wizards-announces-mint-schedule-coming-march-25/ https://earlybirdsinvest.com/taproot-wizards-announces-mint-schedule-coming-march-25/#respond Thu, 13 Mar 2025 14:17:36 +0000 https://earlybirdsinvest.com/taproot-wizards-announces-mint-schedule-coming-march-25/

Bitcoin-based digital collectible project Taproot Wizards has confirmed its official mint to take place on March 25 with only 2,121 inscriptions available.

Over the past two years, Taproot Wizards has cultivated a community through interactive events and challenges. These activities have contributed to the project’s visibility, particularly after its role in the creation of the first 4MB block on the Bitcoin blockchain.

The minting process will involve whitelisted participants, holders of specific assets, and a Dutch auction for remaining inscriptions. Due to the exclusivity of the collection, prospective buyers are advised to prepare ahead of the final eligibility confirmation date on March 19.

Taproot Wizards Announces Mint Schedule, Coming March 25
Source: Taproot Wizards

What is Taproot Wizards?

Taproot Wizards is a digital collectible project built on Bitcoin Ordinals, a protocol that allows data to be inscribed onto individual satoshis, the smallest unit of Bitcoin. This differs from traditional NFT models on Ethereum, as Ordinals are permanently recorded on Bitcoin’s blockchain.

The project first gained attention in February 2023 by contributing to the creation of the first 4MB block in Bitcoin’s history. Since then, it has engaged a growing community through various themed events, known as “Wizard Quests,” which have encouraged participant involvement through interactive challenges.

The project’s emphasis on community participation and Bitcoin-based collectibles has distinguished it within the broader Ordinals ecosystem.

Taproot Wizards Announces Mint Schedule, Coming March 25
Source: Taproot Wizards

How to participate in the Taproot Wizards mint?

The minting process is structured around three primary methods:

  • Quantum Cats Holders: Owners of both a “dead” and “alive” Quantum Cat NFT can combine them through an on-chain process called “Entangling” to receive a discounted mint price of 0.1 $BTC. This offer is limited to 1,000 spots and must be completed by March 19.
  • Whitelist for Community Members: Individuals who have participated in past Taproot Wizards events may be eligible for a whitelist minting slot at 0.2 $BTC. The final eligibility list will be confirmed on March 19.
  • Dutch Auction: A limited number of Taproot Wizards will be available via a Dutch auction, where prices will start high and gradually decrease. Participants can bid using $BTC or $SOL.

Additionally, holders of the “Golden Cape” NFT can claim a Taproot Wizard at no cost, provided they verify ownership and submit their application before March 19.

The mint will be conducted exclusively through Xverse—a Bitcoin wallet provider. Participants will need to use Xverse on a desktop browser, with support available for Ledger hardware wallets.

]]>
https://earlybirdsinvest.com/taproot-wizards-announces-mint-schedule-coming-march-25/feed/ 0 24905
Unable to generate address after importing Taproot Multisig descriptor https://earlybirdsinvest.com/unable-to-generate-address-after-importing-taproot-multisig-descriptor/ https://earlybirdsinvest.com/unable-to-generate-address-after-importing-taproot-multisig-descriptor/#respond Mon, 10 Feb 2025 22:58:00 +0000 https://earlybirdsinvest.com/unable-to-generate-address-after-importing-taproot-multisig-descriptor/

There are three wallets to use to create a Taproot Multisig wallet. All of my work is based on this https://github.com/bitcoin/bitcoin/blob/master/doc/multisig-tutorial.md. The external and internal Xpubs for each are as follows:

Wallet 1 (External + Internal Xpubs)

(11776e3b/86h/1h/0h)tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/0/*
(11776e3b/86h/1h/0h)tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/1/*

Wallet 2 (External + Internal Xpubs)

(fe5187e5/86h/1h/0h)tpubDCqr5GVKeptzMG5QKLu1aQKXFXgF6kMy9dYDQ6Nap6emZ3iziMCeVX1pPjEzA7nTmyZS9NP2KjUsGtEs8jNqFcUTpKxAwXPB3yfbee4RthM/0/*
(fe5187e5/86h/1h/0h)tpubDCqr5GVKeptzMG5QKLu1aQKXFXgF6kMy9dYDQ6Nap6emZ3iziMCeVX1pPjEzA7nTmyZS9NP2KjUsGtEs8jNqFcUTpKxAwXPB3yfbee4RthM/1/*

Wallet 3 (External + Internal Xpubs)

(9f5cbc68/86h/1h/0h)tpubDDQbi15GQjXYxhAysxdEC6VsSFacJ6hgDAJ7oQy4wUs9sfwMQWtcLqLx7GUbBfWyVwUYMEEJtWmxFXmpmjQL8X4cRdgAJ7BcaazuCYq4iCp/0/*
(9f5cbc68/86h/1h/0h)tpubDDQbi15GQjXYxhAysxdEC6VsSFacJ6hgDAJ7oQy4wUs9sfwMQWtcLqLx7GUbBfWyVwUYMEEJtWmxFXmpmjQL8X4cRdgAJ7BcaazuCYq4iCp/1/*

Here is my descriptor:

external_desc="tr(tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/1/*,sortedmulti_a(2,tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/0/*,tpubDCqr5GVKeptzMG5QKLu1aQKXFXgF6kMy9dYDQ6Nap6emZ3iziMCeVX1pPjEzA7nTmyZS9NP2KjUsGtEs8jNqFcUTpKxAwXPB3yfbee4RthM/0/*,tpubDDQbi15GQjXYxhAysxdEC6VsSFacJ6hgDAJ7oQy4wUs9sfwMQWtcLqLx7GUbBfWyVwUYMEEJtWmxFXmpmjQL8X4cRdgAJ7BcaazuCYq4iCp/0/*))#546p4cqh"

For the first discussion of tr Uses and uses the internal Xpub of wallet 1 sortedmulti_a To configure 2-3 using an external one. I’ll call getdescriptorinfo Instructions:

 ./build/src/bitcoin-cli -signet getdescriptorinfo $external_desc
{
  "descriptor": "tr(tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/1/*,sortedmulti_a(2,tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/0/*,tpubDCqr5GVKeptzMG5QKLu1aQKXFXgF6kMy9dYDQ6Nap6emZ3iziMCeVX1pPjEzA7nTmyZS9NP2KjUsGtEs8jNqFcUTpKxAwXPB3yfbee4RthM/0/*,tpubDDQbi15GQjXYxhAysxdEC6VsSFacJ6hgDAJ7oQy4wUs9sfwMQWtcLqLx7GUbBfWyVwUYMEEJtWmxFXmpmjQL8X4cRdgAJ7BcaazuCYq4iCp/0/*))#546p4cqh",
  "checksum": "546p4cqh",
  "isrange": true,
  "issolvable": true,
  "hasprivatekeys": false
}

It then uses that descriptor to construct the descriptor that is used to import JSON into your wallet. This is what I used to create the JSON:

external_desc_sum=$(./build/src/bitcoin-cli -signet getdescriptorinfo $external_desc | jq '.descriptor')
multisig_ext_desc="({\"desc\": $external_desc_sum, \"timestamp\": \"now\"})"

After that I call it importdescriptors New blank wallet way:

./build/src/bitcoin-cli -signet -named createwallet wallet_name="multi_tr" disable_private_keys=true blank=true
./build/src/bitcoin-cli -signet -rpcwallet="multi_tr" importdescriptors "$multisig_ext_desc"
./build/src/bitcoin-cli -signet -rpcwallet="multi_tr" getwalletinfo

The following is the response for the import descriptor:

{
  "name": "multi_tr"
}
(
  {
    "success": true,
    "warnings": (
      "Range not given, using default keypool range"
    )
  }
)

The output from Get Wallet Info is as follows:

{
  "walletname": "multi_tr",
  "walletversion": 169900,
  "format": "sqlite",
  "balance": 0.00000000,
  "unconfirmed_balance": 0.00000000,
  "immature_balance": 0.00000000,
  "txcount": 0,
  "keypoolsize": 0,
  "keypoolsize_hd_internal": 0,
  "paytxfee": 0.00000000,
  "private_keys_enabled": false,
  "avoid_reuse": false,
  "scanning": false,
  "descriptors": true,
  "external_signer": false,
  "blank": true,
  "birthtime": 1739107662,
  "lastprocessedblock": {
    "hash": "0000005ba71046c3e13011955cf5a65c09fc7e945030a3d623dbfef8e7b3dce6",
    "height": 234655
  }
}

After seeing this output I was excited and wanted to generate a new address to fund a multi-sig wallet, but I got an error.

./build/src/bitcoin-cli  -signet -rpcwallet="multi_tr" getnewaddress
error code: -4
error message:
Error: This wallet has no available keys

After searching for a replacement I found it deriveaddresses The method worked in my use case and was able to get some addresses.

./build/src/bitcoin-cli  -signet deriveaddresses "tr(tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/1/*,sortedmulti_a(2,tpubDCTp9moNmiVHK9KS6j6HEyU9duvomZrE87wTNQMkcZktDu89f3yJFATEQovpsT8KwUDWhut5YYd3zNsUYuv6sGHLozsub1AHPoyL7uGW2LT/0/*,tpubDCqr5GVKeptzMG5QKLu1aQKXFXgF6kMy9dYDQ6Nap6emZ3iziMCeVX1pPjEzA7nTmyZS9NP2KjUsGtEs8jNqFcUTpKxAwXPB3yfbee4RthM/0/*,tpubDDQbi15GQjXYxhAysxdEC6VsSFacJ6hgDAJ7oQy4wUs9sfwMQWtcLqLx7GUbBfWyVwUYMEEJtWmxFXmpmjQL8X4cRdgAJ7BcaazuCYq4iCp/0/*))#546p4cqh" "(0,2)"
(
  "tb1pg0p5p2vfqn3stjrrz0ga33m4wudcxmsl4qsuv4csnq5lxfnws3zss5xcvh",
  "tb1p4z6n9hlt2rs9arlaxwkcgpp79803rmle6wty946zwce74u4wnmas4r8etx",
  "tb1pk3nj9xt2aempeys63etmw3zfkj8pya0sr2lcl2spf6xqtjev8zfqkfzg5p"
)

My question is:

  • Why the first way generatenewaddress Is it not working?
  • is deriveaddresses What is the recommended method for general use? If so, I think you need to save the range of use to generate a new address each time (as using the same range will generate the same address). So if you use the range (0,0), you must use the next time (1,1).

thank you

]]>
https://earlybirdsinvest.com/unable-to-generate-address-after-importing-taproot-multisig-descriptor/feed/ 0 18699
Mandatory script-verify-flag-failed (invalid schnorr signature) error when creating child inscriptions in Taproot transactions https://earlybirdsinvest.com/mandatory-script-verify-flag-failed-invalid-schnorr-signature-error-when-creating-child-inscriptions-in-taproot-transactions/ https://earlybirdsinvest.com/mandatory-script-verify-flag-failed-invalid-schnorr-signature-error-when-creating-child-inscriptions-in-taproot-transactions/#respond Sun, 09 Feb 2025 10:45:01 +0000 https://earlybirdsinvest.com/mandatory-script-verify-flag-failed-invalid-schnorr-signature-error-when-creating-child-inscriptions-in-taproot-transactions/

I’m trying to create a child inscription in a Taproot transaction, but I’m running into the following error:

sendrawtransaction RPC error: {"code":-26,"message":"mandatory-script-verify-flag-failed (Invalid Schnorr signature)"}

I checked all the data, including transaction structure, signatures, TapRoot scripts, and more, but the error persists.

The input refers to the parent UTXO.

{
  "txid": "02cde20c6db772c9ddced410c52cb2bdcbf476016fa398cfa1ac5207f1ff462f",
  "vout": 0,
  "value": 546,
  "scriptPk": "5120932a0391d2ec13cb8f303ded9297ece089f739b3ced40bc98eebdd277fdb9c9d",
  "address": "tb1pjv4q8ywjasfuhres8hke99lvuzylwwdnem2qhjvwa0wjwl7mnjwsdqu3e0"
}

The output sends 546 Satoshis to the recipient address. The Taproot script for the child’s inscription includes:

Parent inscription data (InscriptionID). Child inscription metadata.

const childOrdinalStacks = (
  publicKey,
  bitcoin.opcodes.OP_CHECKSIG,
  bitcoin.opcodes.OP_FALSE,
  bitcoin.opcodes.OP_IF,
  Buffer.from("ord", "utf8"),
  1, 1,
  Buffer.from("text/plain;charset=utf-8", "utf8"),
  1, 2,
  pointerBuffer1,
  1, 3,
  Buffer.from(parentInscriptionId, "hex"),
  1, 5,
  cbor.encode(childMetadata),
  1, 7,
  Buffer.from("parcel.bitmap", "utf8"),
  bitcoin.opcodes.OP_0,
);

RAW TX Hash

020000000001022f46fff10752aca1cf98a36f0176f4cbbdb22cc510d4ceddc972b76d0ce2cd020000000000ffffffffc14499f6058bc6c6d5eed11c699c80007199690c12bee4a54fd46d5a9f5193e00100000000ffffffff022202000000000000225120932a0391d2ec13cb8f303ded9297ece089f739b3ced40bc98eebdd277fdb9c9d2202000000000000225120932a0391d2ec13cb8f303ded9297ece089f739b3ced40bc98eebdd277fdb9c9d01406fcbc5b6b63cb67c2289a5b4df1f3e1971b26ad4310b644da9a5a8488247f6ae44b50d7be59eecd8c58a268ce74eeb490b31bfda28cfeee6c101a914b54d613e03400058e04b9c6438f33f9a3541fe8d2a5c229794a00eb6c005aaedeb1b4622ca9c0c902d714b550e0b352578c761ac3853a5766078d7cded283f15070ef53b6c1ee8206705021108c86f6f7249e85d233414afa8eeaadaea2bad863b2ccce504126879ac0063036f7264010118746578742f706c61696e3b636861727365743d7574662d3801020222020103202f46fff10752aca1cf98a36f0176f4cbbdb22cc510d4ceddc972b76d0ce2cd02010528a264747970656b54657374204e46542023316b6465736372697074696f6e6954657374205465737401070d70617263656c2e6269746d6170003f68747470733a2f2f617277656176652e6e65742f4933326c517668673341514c583444632d334e48557773434e366e75382d6c78477352634e7765336372346821c06705021108c86f6f7249e85d233414afa8eeaadaea2bad863b2ccce50412687900000000

I’m using Tweaksigner to sign the input.

const signer = tweakSigner(wallet);
psbt.signInput(0, signer);
psbt.signInput(1, wallet.keyPair);


export function tweakSigner(wallet: Wallet, opts: any = {}) {
  let privateKey: any = wallet.keyPair.privateKey;
  if (!privateKey) {
    throw new Error('Private key is required for tweaking signer!');
  }
  if (wallet.keyPair.publicKey(0) === 3) {
    privateKey = ecc.privateNegate(privateKey);
  }
  const tweakedPrivateKey = ecc.privateAdd(privateKey, tapTweakHash(wallet.internalPubkey, opts.tweakHash));
  if (!tweakedPrivateKey) {
    throw new Error('Invalid tweaked private key!');
  }
  return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
    network: wallet.network,
  });
}


function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
  return bitcoin.crypto.taggedHash(
    "TapTweak",
    Buffer.concat(h ? (pubKey, h) : (pubKey))
  );
}

]]>
https://earlybirdsinvest.com/mandatory-script-verify-flag-failed-invalid-schnorr-signature-error-when-creating-child-inscriptions-in-taproot-transactions/feed/ 0 18392