I'm having trouble manually recreating the taproot sighash from the example below.
I used btcdeb to pass in an input transaction (with a P2TR output), and a valid tx that spends from it. In the logs it shows the components of the sighash message, but when I concatenate them and hash it with sha256 I'm not getting the same sighash. What am I missing?
Also, what is the epoch
? I've tried with and without this value and neither worked.
$ btcdeb --txin='02000000000101c7eb56c02553b5fe29c16b458960ba21be0ef1fb020972fde15324b1f725f0480000000000fdffffff027c9c181e010000002251204a0cd40b4984a107334966b266bdc8134bcba9f23f039ed9ddc3f99d6c99c03fa048ed0b000000002251204f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa024730440220077e71f9276149475ecb27e68374712f43e0af6f61ca0e0c9a74483c07bd08d902206f0befdcbc047b0a9a59eff49e011f81644ba0e179a6fa4a90bb19f7765d165c012103d31501fa2dd221b0d40eead3961afd65bdfa986f2577327d1400fa82691cc69965000000' --tx='02000000000101d0a3e1a6c730355abefa376f9b5d3ca9325b153475becc8402e3b4a98d393ed20100000000ffffffff0280d1f00800000000160014fc7250a211deddc70ee5a2738de5f07817351cef80f0fa0200000000160014531260aa2a199e228c537dfa42c82bea2c7c1f4d01404d22f94e5d1787eecf712b14b0c8fb57242633616d50ca5b77f31dad9ad43d0a6786b1e5467dc20494a08e5862821834675f91f897f0e568b417430b07ba100b00000000'
btcdeb 0.4.22 -- type `btcdeb -h` for start up options
LOG: sighash signing segwit taproot
notice: btcdeb has gotten quieter; use --verbose if necessary (this message is temporary)
input tx index = 0; tx input vout = 1; value = 200100000
got witness stack of size 1
34 bytes (v0=P2WSH, v1=taproot/tapscript)
valid script
- generating prevout hash from 1 ins
[+] COutPoint(d23e398da9, 1)
note: there is a for-clarity preamble (use --verbose for details)
2 op script loaded. type `help` for usage information
script | stack
-----------------------------------------------------------------+-------------------------------------------------------------------
4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa | 4d22f94e5d1787eecf712b14b0c8fb57242633616d50ca5b77f31dad9ad43d0...
OP_CHECKSIG |
#0000 4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
btcdeb> step
<> PUSH stack 4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
script | stack
-----------------------------------------------------------------+-------------------------------------------------------------------
OP_CHECKSIG | 4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
| 4d22f94e5d1787eecf712b14b0c8fb57242633616d50ca5b77f31dad9ad43d0...
#0001 OP_CHECKSIG
btcdeb> step
EvalChecksig() sigversion=2
GenericTransactionSignatureChecker::CheckSchnorrSignature(64 len sig, 32 len pubkey, sigversion=2)
sig = 4d22f94e5d1787eecf712b14b0c8fb57242633616d50ca5b77f31dad9ad43d0a6786b1e5467dc20494a08e5862821834675f91f897f0e568b417430b07ba100b
pub key = 4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
SignatureHashSchnorr(in_pos=0, hash_type=00)
- taproot sighash
<< epoch
#001 00
<< hash type
#001 00
<< tx_to.nVersion
#004 02000000
<< tx_to.nLockTime
#004 00000000
input type != anyone can pay:
<< cache prevouts single hash
#032 e186179664b38e58723ba1ac8d5915f97023f6afc2f2be94459fe9868cf953eb
<< cache spent amounts single hash
#032 646b3ee05dcdae994f2d99d94a878d1ad40c3f4b536b76a6a730b4e28b29c385
<< cache spent scripts single hash
#032 e00e0a53937928e143c165df361096d6f607d8fe35aa63f4adfe2e73b56cd324
<< cache sequences single hash
#032 ad95131bc0b799c0b1af477fb14fcf26a6a9f76079e48bf090acb7e8367bfd0e
output type == sighash_all
<< cache outputs single hash
#032 5ac2b429009184588bf78341f4692a02303a6a3110c2f1a914f3dba9cea091cb
<< spend type
#001 00
<< in_pos
#004 00000000
- schnorr sighash = 1eaaf5f3228e6aa087cf9620ac86f8bc5458261b074b7cb6d78c20f358d6fc1f
pubkey.VerifySchnorrSignature(sig=4d22f94e5d1787eecf712b14b0c8fb57242633616d50ca5b77f31dad9ad43d0a6786b1e5467dc20494a08e5862821834675f91f897f0e568b417430b07ba100b, sighash=1eaaf5f3228e6aa087cf9620ac86f8bc5458261b074b7cb6d78c20f358d6fc1f):
result: success
And here is my python script to try and create the same sighash:
import hashlib
sig_msg = (
"00" # epoch
+ "00" # hash_type
+ "02000000" # nVersion
+ "00000000" # nLockTime
+ "e186179664b38e58723ba1ac8d5915f97023f6afc2f2be94459fe9868cf953eb" # sha_prevouts
+ "646b3ee05dcdae994f2d99d94a878d1ad40c3f4b536b76a6a730b4e28b29c385" # sha_amounts
+ "e00e0a53937928e143c165df361096d6f607d8fe35aa63f4adfe2e73b56cd324" # sha_scriptpubkeys
+ "ad95131bc0b799c0b1af477fb14fcf26a6a9f76079e48bf090acb7e8367bfd0e" # sha_sequences
+ "5ac2b429009184588bf78341f4692a02303a6a3110c2f1a914f3dba9cea091cb" # sha_outputs
+ "00" # spend_type
+ "00000000" # input_index
)
sig_msg = bytes.fromhex(sig_msg)
hashlib.sha256(sig_msg).digest().hex()
# returns 4c1f7ef4d927d34de60599d334fe26cfb03090c5672e01019bf5da54b9cb5446