bitcoin TapRoot 地址生成

2023-12-6

bitcoin TapRoot 地址生成

好久没有更新区块链的东西了,最近看brc20,用的都是btc的TapRoot地址。这次我们看看js如何生成TapRoot地址吧。

  • 依赖库
const bitcoin = require('bitcoinjs-lib')
const bip39 = require('bip39');
const ecc = require('tiny-secp256k1');
const { BIP32Factory } = require('bip32');

  • 初始化&部分参数
const network = bitcoin.networks.bitcoin // 主网
const bip32 = BIP32Factory(ecc)
bitcoin.initEccLib(ecc);

  • 大家玩这个好像都是用的BIP86,这里暂不研究,后续需要深入了解的时候再来看。

    回来了,强烈建议为P2TR公钥使用一个新的推导路径(例如由BIP86定义的),如果你在ECDSA和schnorr签名中使用相同的密钥,可能会被攻击。
    所以重点在于换一个推导路径。

const rootKey = bip32.fromSeed(bip39.mnemonicToSeedSync('mnemonic'))
const path = "m/86'/0'/0'/0/0";
const child = rootKey.derivePath(path);

  • 记录一下,之前的各种地址输出
// address: 1......
console.log(bitcoin.payments.p2pkh({ pubkey: child.publicKey, network }).address);
// address: bc1q....
console.log(bitcoin.payments.p2wpkh({ pubkey: child.publicKey }).address);
// address: 3........
console.log(bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wpkh({ pubkey: child.publicKey }), }).address);

  • 生成TapRoot地址

    • 方式一:直接使用bitcoin.payments.p2tr生成地址
    const address = bitcoin.payments.p2tr({ internalPubkey: child.publicKey.slice(1, 33), network }).address
    
    • 方式二:使用bitcoin.address.fromOutputScript生成地址
    function createKeySpendOutput(publicKey) {
        // x-only pubkey (remove 1 byte y parity)
        const myXOnlyPubkey = publicKey.slice(1, 33);
        const commitHash = bitcoin.crypto.taggedHash('TapTweak', myXOnlyPubkey);
        const tweakResult = ecc.xOnlyPointAddTweak(myXOnlyPubkey, commitHash);
        if (tweakResult === null) throw new Error('Invalid Tweak');
        const { xOnlyPubkey: tweaked } = tweakResult;
        // scriptPubkey
        return Buffer.concat([
            // witness v1, PUSH_DATA 32 bytes
            Buffer.from([0x51, 0x20]),
            // x-only tweaked pubkey
            tweaked,
        ]);
    }
    
    const output = createKeySpendOutput(child.publicKey);
    const address = bitcoin.address.fromOutputScript(output, network);
    console.log({address});
    

OK,这样你就得到了一个TapRoot地址,地址是以bc1p开头。

遇到问题了? 可以直接联系我

评论区