Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501def __init__(self, outpoint=None, scriptSig=b"", nSequence=0):502if outpoint is None:503self.prevout = COutPoint()504else:505self.prevout = outpoint506self.scriptSig = scriptSig507self.nSequence = nSequence509def deserialize(self, f):510self.prevout = COutPoint()511self.prevout.deserialize(f)512self.scriptSig = deser_string(f)513self.nSequence = int.from_bytes(f.read(4), "little")515def serialize(self):516r = b""517r += self.prevout.serialize()518r += ser_string(self.scriptSig)519r += self.nSequence.to_bytes(4, "little")520return r522def __repr__(self):523return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \524% (repr(self.prevout), self.scriptSig.hex(),525self.nSequence)528class CTxOut:529__slots__ = ("nValue", "scriptPubKey")531def __init__(self, nValue=0, scriptPubKey=b""):532self.nValue = nValue533self.scriptPubKey = scriptPubKey535def deserialize(self, f):536self.nValue = int.from_bytes(f.read(8), "little", signed=True)537self.scriptPubKey = deser_string(f)539def serialize(self):540r = b""541r += self.nValue.to_bytes(8, "little", signed=True)542r += ser_string(self.scriptPubKey)543return r545def __repr__(self):546return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \547% (self.nValue // COIN, self.nValue % COIN,548self.scriptPubKey.hex())551class CScriptWitness:552__slots__ = ("stack",)554def __init__(self):555# stack is a vector of strings556self.stack = []558def __repr__(self):559return "CScriptWitness(%s)" % \560(",".join([x.hex() for x in self.stack]))562def is_null(self):563if self.stack:564return False565return True568class CTxInWitness:569__slots__ = ("scriptWitness",)571def __init__(self):572self.scriptWitness = CScriptWitness()574def deserialize(self, f):575self.scriptWitness.stack = deser_string_vector(f)577def serialize(self):578return ser_string_vector(self.scriptWitness.stack)580def __repr__(self):581return repr(self.scriptWitness)583def is_null(self):584return self.scriptWitness.is_null()587class CTxWitness:588__slots__ = ("vtxinwit",)590def __init__(self):591self.vtxinwit = []593def deserialize(self, f):594for i in range(len(self.vtxinwit)):595self.vtxinwit[i].deserialize(f)597def serialize(self):598r = b""599# This is different than the usual vector serialization --600# we omit the length of the vector, which is required to be601# the same length as the transaction's vin vector.602for x in self.vtxinwit:603r += x.serialize()604return r606def __repr__(self):607return "CTxWitness(%s)" % \608(';'.join([repr(x) for x in self.vtxinwit]))610def is_null(self):611for x in self.vtxinwit:612if not x.is_null():613return False614return True617class CTransaction:618__slots__ = ("nLockTime", "version", "vin", "vout", "wit")620def __init__(self, tx=None):621if tx is None:622self.version = 2623self.vin = []624self.vout = []625self.wit = CTxWitness()626self.nLockTime = 0627else:628self.version = tx.version629self.vin = copy.deepcopy(tx.vin)630self.vout = copy.deepcopy(tx.vout)631self.nLockTime = tx.nLockTime632self.wit = copy.deepcopy(tx.wit)634def deserialize(self, f):635self.version = int.from_bytes(f.read(4), "little")636self.vin = deser_vector(f, CTxIn)637flags = 0638if len(self.vin) == 0:639flags = int.from_bytes(f.read(1), "little")640# Not sure why flags can't be zero, but this641# matches the implementation in bitcoind642if (flags != 0):643self.vin = deser_vector(f, CTxIn)644self.vout = deser_vector(f, CTxOut)645else:646self.vout = deser_vector(f, CTxOut)647if flags != 0:648self.wit.vtxinwit = [CTxInWitness() for _ in range(len(self.vin))]649self.wit.deserialize(f)650else:651self.wit = CTxWitness()652self.nLockTime = int.from_bytes(f.read(4), "little")654def serialize_without_witness(self):655r = b""656r += self.version.to_bytes(4, "little")657r += ser_vector(self.vin)658r += ser_vector(self.vout)659r += self.nLockTime.to_bytes(4, "little")660return r662# Only serialize with witness when explicitly called for663def serialize_with_witness(self):664flags = 0665if not self.wit.is_null():666flags |= 1667r = b""668r += self.version.to_bytes(4, "little")669if flags:670dummy = []671r += ser_vector(dummy)672r += flags.to_bytes(1, "little")673r += ser_vector(self.vin)674r += ser_vector(self.vout)675if flags & 1:676if (len(self.wit.vtxinwit) != len(self.vin)):677# vtxinwit must have the same length as vin678self.wit.vtxinwit = self.wit.vtxinwit[:len(self.vin)]679for _ in range(len(self.wit.vtxinwit), len(self.vin)):680self.wit.vtxinwit.append(CTxInWitness())681r += self.wit.serialize()682r += self.nLockTime.to_bytes(4, "little")683return r685# Regular serialization is with witness -- must explicitly686# call serialize_without_witness to exclude witness data.687def serialize(self):688return self.serialize_with_witness()690@property691def wtxid(self):692"""Return wtxid (transaction hash with witness) as little-endian bytes."""693return hash256(self.serialize_with_witness())695@property696def wtxid_hex(self):697"""Return wtxid (transaction hash with witness) as hex string."""698return self.wtxid[::-1].hex()700@property701def wtxid_int(self):702"""Return wtxid (transaction hash with witness) as integer."""703return uint256_from_str(self.wtxid)705@property706def txid(self):707"""Return txid (transaction hash without witness) as little-endian bytes."""708return hash256(self.serialize_without_witness())710@property711def txid_hex(self):712"""Return txid (transaction hash without witness) as hex string."""713return self.txid[::-1].hex()715@property716def txid_int(self):717"""Return txid (transaction hash without witness) as integer."""718return uint256_from_str(self.txid)720def is_valid(self):721for tout in self.vout:722if tout.nValue < 0 or tout.nValue > 21000000 * COIN:723return False724return True726# Calculate the transaction weight using witness and non-witness727# serialization size (does NOT use sigops).728def get_weight(self):729with_witness_size = len(self.serialize_with_witness())730without_witness_size = len(self.serialize_without_witness())731return (WITNESS_SCALE_FACTOR - 1) * without_witness_size + with_witness_size733def get_vsize(self):734return math.ceil(self.get_weight() / WITNESS_SCALE_FACTOR)736def __repr__(self):737return "CTransaction(version=%i vin=%s vout=%s wit=%s nLockTime=%i)" \738% (self.version, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)741class CBlockHeader:742__slots__ = ("hashMerkleRoot", "hashPrevBlock", "nBits", "nNonce",743"nTime", "nVersion")745def __init__(self, header=None):746if header is None:747self.set_null()748else:749self.nVersion = header.nVersion750self.hashPrevBlock = header.hashPrevBlock
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.