DUCAT’SBitcoin Guild
All curriculum
PROTOCOL ENGINEER PATH

Technical Bitcoin

Move from exact transaction and Script bytes through Taproot, block validation, peer messages, privacy, layer two systems and protocol engineering. Every route combines instruction, a worked example, deterministic execution and a transfer task.

Parse, construct, execute, test No external tools required
01

Build the byte-level mental model

A Bitcoin implementation moves between human intent, typed values, canonical bytes, cryptographic commitments and independently validated state. The first workbench makes variable-length boundaries explicit before the larger transaction project.

  1. 01
    Represent values

    Encode signed and unsigned integers, hashes, amounts and vectors without losing leading zeros or byte order.

  2. 02
    Serialize objects

    Construct complete transactions, headers, scripts and network frames from typed fields.

  3. 03
    Commit and authorize

    Recompute identifiers, Merkle roots, signature digests and spending predicates from those bytes.

  4. 04
    Validate state

    Apply local policy, consensus checks and chain context without trusting a peer, miner or explorer.

EXACT MECHANISM WORKBENCH

Encode and parse CompactSize without ambiguity

Cross the fd boundary, decode canonical little-endian payloads, then reject short and unnecessarily long encodings.

Predict the result
Required cases complete: 0/4.
ARBITRARY BYTE WORKBENCH

See the same bits in every representation

One bounded value stays synchronized across hexadecimal, binary, decimal, text, byte order, signedness and bit-level edits. Hash, slice and concatenate the exact bytes without losing leading zeros.

Unsigned big endian7159401693
Unsigned little endian15982355516466659328
Signed big endian7159401693
Leading zero bytes3
Reversed hexddccbbaa01000000
SHA-25687d4882d5b06d22fbcd536d197eef602fc5b6d4bba0b2605ba501bc56591061f
Toggle any bit in the 64-bit value

Slice and concatenate bytes

02

Complete a tested programmer project

Build one raw transaction in TypeScript, Python, and Rust. Save the same typed fields, run each fixed serializer in isolation, and require Bitcoin Core to agree with the resulting bytes and transaction ID.

SAVED RAW TRANSACTION PROJECT

Construct, run, and verify one transaction

Edit typed fields. The selected language serializes them in an isolated process, then Bitcoin Core decodes the exact bytes on a temporary regtest node.

No arbitrary codeNo network, wallet, or real funds
Bitcoin Core 31.1listen=0, dnsseed=0, fixedseeds=0
Unique temporary chainStopped and removed after every run
Bounded runtimesTyped fields only, fixed serializer source

1. Edit the typed transaction

Output 1
Output 2

Project not saved yet.

2. Inspect the runnable source

// Run with Node 22+ after saving as transaction.mjs.
import { createHash } from "node:crypto";

const project = {
  "version": 2,
  "locktime": 0,
  "inputs": [
    {
      "txid": "1111111111111111111111111111111111111111111111111111111111111111",
      "vout": 1,
      "sequence": 4294967293,
      "scriptSigHex": ""
    }
  ],
  "outputs": [
    {
      "value": 50000,
      "scriptPubKeyHex": "00142222222222222222222222222222222222222222"
    },
    {
      "value": 18800,
      "scriptPubKeyHex": "00143333333333333333333333333333333333333333"
    }
  ]
};
const hex = (text) => Buffer.from(text, "hex");
const u32 = (number) => { const out = Buffer.alloc(4); out.writeUInt32LE(number); return out; };
const u64 = (number) => { const out = Buffer.alloc(8); out.writeBigUInt64LE(BigInt(number)); return out; };
const compact = (number) => number < 0xfd ? Buffer.from([number]) : (() => { throw new Error("Bounded example only"); })();
const parts = [u32(project.version), compact(project.inputs.length)];
for (const input of project.inputs) parts.push(Buffer.from(hex(input.txid)).reverse(), u32(input.vout), compact(hex(input.scriptSigHex).length), hex(input.scriptSigHex), u32(input.sequence));
parts.push(compact(project.outputs.length));
for (const output of project.outputs) parts.push(u64(output.value), compact(hex(output.scriptPubKeyHex).length), hex(output.scriptPubKeyHex));
parts.push(u32(project.locktime));
const raw = Buffer.concat(parts);
const txid = Buffer.from(createHash("sha256").update(createHash("sha256").update(raw).digest()).digest()).reverse().toString("hex");
console.log(JSON.stringify({ transactionHex: raw.toString("hex"), txid }, null, 2));
// Expected txid: a71281af068a7276b4b98e5b9c48995c36917019c921b3a12e15a92fb402d267

3. Inspect the locally constructed object

Transaction ID
a71281af068a7276b4b98e5b9c48995c36917019c921b3a12e15a92fb402d267
Serialized bytes
113
Weight
452
Output total
68,800 sats
Complete transaction hex020000000111111111111111111111111111111111111111111111111111111111111111110100000000fdffffff0250c300000000000016001422222222222222222222222222222222222222227049000000000000160014333333333333333333333333333333333333333300000000
03

Construct and decode real objects

Edit the fixtures directly. Each result is generated from the displayed input and malformed boundaries are rejected.

12 LIVE BITCOIN UTILITIES

Use the protocol primitives

Move from raw bytes to a complete transaction, Script trace, PSBT or block header without leaving the Guild.

Bytes

Reverse Bytes

Reverse complete hexadecimal bytes without reversing the characters inside each byte.

Ready to calculate

Change any field, predict what should change, then run the utility.

Safety boundary: This learning surface does not store inputs. Never paste a live seed phrase, private key, wallet backup, or confidential transaction.

04

Continue into protocol engineering

Each route adds real vectors, mutation tests, failure analysis and a transfer task.