Skip to content

Instantly share code, notes, and snippets.

@remyers
Last active November 13, 2019 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remyers/e2d4ba6a5cd277d6e319a52492425b90 to your computer and use it in GitHub Desktop.
Save remyers/e2d4ba6a5cd277d6e319a52492425b90 to your computer and use it in GitHub Desktop.
Debugging SighatureHash in interpreter.cpp
Add this code at end of add_eltoo_witness
self.log.debug("\nbtcdeb --tx=%s --txin=%s --modify-flags=\"-NULLFAIL\"\n",tx_hex, spend_tx_hex)
or to debug from a transaction:
self.log.debug("btcdeb --tx=%s --txin=%s\n", ToHex(close_tx), ToHex(setup_tx[A]) )
Add code before and in the method after the normal CHashWriter call to serialize the txTo.
template <class T>
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
#include <streams.h>
#include <util/strencodings.h>
std::vector<unsigned char> digest(256,0);
CVectorWriter ss_(0,0, digest, 0);
// Version
ss_ << txTo.nVersion;
// Input prevouts/nSequence (none/all, depending on flags)
ss_ << hashPrevouts;
ss_ << hashSequence;
// The input being signed (replacing the scriptSig with scriptCode + amount)
// The prevout may already be contained in hashPrevout, and the nSequence
// may already be contain in hashSequence.
ss_ << outpoint;
ss_ << script;
ss_ << amount;
ss_ << txTo.vin[nIn].nSequence;
// Outputs (none/one/all, depending on flags)
ss_ << hashOutputs;
// Locktime
ss_ << txTo.nLockTime;
// Sighash type
ss_ << nHashType;
std::string digestString = HexStr(digest);
can compare it to the equivalent method in the testing framework:
# DEBUG DEBUG DEBUG
def Debug_SegwitVersion1SignatureHash(log, script, txTo, inIdx, hashtype, amount):
hashPrevouts = 0
hashSequence = 0
hashOutputs = 0
outpoint = COutPoint()
scriptCode = CScript()
noinput = not not (hashtype & SIGHASH_NOINPUT)
if not (hashtype & SIGHASH_ANYONECANPAY) and not noinput:
serialize_prevouts = bytes()
for i in txTo.vin:
serialize_prevouts += i.prevout.serialize()
hashPrevouts = uint256_from_str(hash256(serialize_prevouts))
if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE and not noinput):
serialize_sequence = bytes()
for i in txTo.vin:
serialize_sequence += struct.pack("<I", i.nSequence)
hashSequence = uint256_from_str(hash256(serialize_sequence))
if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
serialize_outputs = bytes()
for o in txTo.vout:
serialize_outputs += o.serialize()
hashOutputs = uint256_from_str(hash256(serialize_outputs))
elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)):
serialize_outputs = txTo.vout[inIdx].serialize()
hashOutputs = uint256_from_str(hash256(serialize_outputs))
# NOINPUT literally same as 'any prevout' and 'any script'
if (not noinput):
outpoint = txTo.vin[inIdx].prevout
scriptCode = script
ss = bytes()
ss += struct.pack("<i", txTo.nVersion)
log.debug("\ttxTo.nVersion: %s", bytes_to_hex_str(struct.pack("<i", txTo.nVersion)))
ss += ser_uint256(hashPrevouts)
log.debug("\thashPrevouts: %s",bytes_to_hex_str(ser_uint256(hashPrevouts)))
ss += ser_uint256(hashSequence)
log.debug("\thashSequence: %s",bytes_to_hex_str(ser_uint256(hashSequence)))
ss += outpoint.serialize()
log.debug("\toutpoint: %s", bytes_to_hex_str(outpoint.serialize()))
ss += ser_string(scriptCode)
log.debug("\tscriptCode: %s",bytes_to_hex_str(ser_string(scriptCode)))
ss += struct.pack("<q", amount)
log.debug("\tamount: %s (%d)",bytes_to_hex_str(struct.pack("<q", amount)),amount)
ss += struct.pack("<I", txTo.vin[inIdx].nSequence)
log.debug("\ttxTo.vin[inIdx].nSequence: %s (%d)", bytes_to_hex_str(struct.pack("<I", txTo.vin[inIdx].nSequence)), txTo.vin[inIdx].nSequence)
ss += ser_uint256(hashOutputs)
log.debug("\thashOutputs: %s",bytes_to_hex_str(ser_uint256(hashOutputs)))
ss += struct.pack("<i", txTo.nLockTime)
log.debug("\ttxTo.nLockTime: %s (%d)",bytes_to_hex_str(struct.pack("<i", txTo.nLockTime)),txTo.nLockTime)
ss += struct.pack("<I", hashtype)
log.debug("\thashtype: %s",bytes_to_hex_str(struct.pack("<I", hashtype)))
digest = bytes_to_hex_str(ss)
log.debug("digest: %s",digest)
return ss
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment