比特币Taproot(P2TR)输入签名失败问题求助
比特币Taproot(P2TR)交易签名失败:Invalid Schnorr signature 问题排查
尝试签署一笔花费比特币Taproot(P2TR)输入的交易,但提交至网络时持续遇到错误:mandatory-script-verify-flag-failed (Invalid Schnorr signature)。
地址推导
通过以下Rust代码生成Taproot地址:
let secp = Secp256k1::new(); let secret_key = SecretKey::from_slice( &hex::decode(env::var("BITCOIN_FEES_ACCOUNT_PRIV_KEY").expect("BITCOIN_FEES_ACCOUNT_PRIV_KEY must be set")) .expect("Invalid hex"), ) .expect("Invalid private key"); let keypair = bitcoin::secp256k1::Keypair::from_secret_key(&secp, &secret_key); let (x_only_public_key, _parity) = XOnlyPublicKey::from_keypair(&keypair); let address = bitcoin::Address::p2tr(&secp, x_only_public_key, None, Network::Bitcoin); println!("Taproot address: {}", address);
生成的主网地址为:
bc1pclr7kl28zzvdkfv8xsa6kv4vtqc6q3fetfsgzmgpmhe66f85t73qz62933
已向该地址转入0.001 BTC,对应单输入。
交易创建与签名
按如下方式创建并签署交易:
let mut unsigned_tx = Transaction { version: Version(2), lock_time: LockTime::ZERO, input: vec![TxIn { previous_output: OutPoint { txid: Txid::from_str( "a693543ba39b5709359f5eb309c9322b5733680a8a21d6b52eb9977ec1aec7b6", ) .unwrap(), vout: 0, }, script_sig: ScriptBuf::new(), sequence: Sequence::MAX, witness: Witness::new(), }], output: vec![TxOut { value: Amount::from_sat(98894), script_pubkey: ScriptBuf::from( hex::decode("5120c7c7eb7d471098db2587343bab32ac5831a045395a60816d01ddf3ad24f45fa2") .expect("Invalid hex string"), ), }], }; let sighash_type = TapSighashType::AllPlusAnyoneCanPay; let binding = [unsigned_tx.output[0].clone()]; let prevouts = Prevouts::All(&binding[..]); let mut sighasher = SighashCache::new(&mut unsigned_tx); let sighash = sighasher .taproot_key_spend_signature_hash(0, &prevouts, sighash_type) .expect("Failed to create sighash"); let tweaked: TweakedKeypair = keypair.tap_tweak(&secp, None); let msg = Message::from(sighash); let signature = secp.sign_schnorr(&msg, &tweaked.to_inner()); let taproot_signature = bitcoin::taproot::Signature { signature, sighash_type, }; let witness = Witness::p2tr_key_spend(&taproot_signature); *sighasher.witness_mut(0).unwrap() = witness; let tx = sighasher.into_transaction(); let raw_tx = serialize_hex(&tx); println!("Raw transaction hex: '[\"{}\"]'", raw_tx);
签署后的交易十六进制数据为:
02000000000101b6c7aec17e97b92eb5d6218a0a6833572b32c909b35e9f3509579ba33b5493a60000000000ffffffff014e82010000000000225120c7c7eb7d471098db2587343bab32ac5831a045395a60816d01ddf3ad24f45fa2014122378e554918f9ed96d9cd49c25f9987a224102112d7c1b8ec26abc889104fdb15c18070e202e9dde7a659d66171bf3c35cf0753560f8308c095aa3c037eb4fa8100000000
错误详情
使用bitcoin-cli提交交易:
bitcoin-cli testmempoolaccept '["02000000000101b6c7aec17e97b92eb5d6218a0a6833572b32c909b35e9f3509579ba33b5493a60000000000ffffffff014e82010000000000225120c7c7eb7d471098db2587343bab32ac5831a045395a60816d01ddf3ad24f45fa2014122378e554918f9ed96d9cd49c25f9987a224102112d7c1b8ec26abc889104fdb15c18070e202e9dde7a659d66171bf3c35cf0753560f8308c095aa3c037eb4fa8100000000"]'
返回错误:
{ "txid": "9c7da7c85517749eb6ba931bfaa43bcaef4f39ff91819ec9058e353fbdcd7a56", "wtxid": "e4376ab2fbee06da3fcb669fd7fb74496b14d8c9ef12cba76f12e8ce22e4e65d", "allowed": false, "reject-reason": "mandatory-script-verify-flag-failed (Invalid Schnorr signature)" }
已尝试的排查
- 尝试不调整密钥对直接签名,代码改为:
但仍出现相同错误。let signature = secp.sign_schnorr(&msg, &keypair);
求助问题
签署交易过程中哪里出现了问题?是签名、密钥调整还是交易结构存在错误?
内容的提问来源于stack exchange,提问作者Th0rgal
相关产品推荐
相关产品推荐

