Sitelet https://github.com/systemslibrarian/crypto-lab-bitcoin-script
Skip to content

About

Browser-based Bitcoin Script demo — step a real P2PKH spend through the stack machine, with valid, wrong-key, forged-signature, and tampered scenarios. Real secp256k1 + HASH160. No backend.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

crypto-lab-bitcoin-script

What It Is

An interactive model of Bitcoin Script — the tiny, stack-based language that defines who is allowed to spend each bitcoin — using real cryptography in the browser. The page composes the audited @noble/secp256k1 and @noble/hashes libraries to build a genuine Pay-to-Public-Key-Hash (P2PKH) spend end to end: a secp256k1 key pair, a HASH160 (SHA-256 → RIPEMD-160) commitment in the locking script, a real legacy SIGHASH_ALL preimage over a concrete one-input/one-output transaction, an ECDSA signature (low-S, DER-encoded) in the unlocking script, and a hand-rolled stack interpreter that executes OP_DUP · OP_HASH160 · OP_EQUALVERIFY · OP_CHECKSIG one step at a time. Nothing is faked: the signature math, the hashes, and the sighash are all the real thing, validated at boot against the textbook privkey = 1 key whose HASH160 is 751e76e8199196d454941c45d1b3a323f1433bd6 (address 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH). Keys are generated per session in memory and never persisted — this is for education only.

When to Use It

  • Connecting digital signatures to how Bitcoin actually works — students who have seen ECDSA in isolation can watch a signature get checked by a script to release funds, closing the gap between "I understand signatures" and "I understand spending conditions".
  • Teaching the stack machine concretely — step through a real P2PKH script and see each opcode push and pop a shared stack, rather than reading the opcodes as abstract names.
  • Showing why bad spends are rejected — flip between a valid spend, a wrong public key, a forged signature, and a tampered transaction, and see exactly where and why each invalid attempt fails.
  • Motivating the move to Taproot — the page frames P2PK → P2PKH → P2TR so the trade-offs (key exposure, size, privacy) are visible.
  • Do NOT treat this as a wallet, a node, or a consensus implementation. It models the single-signature P2PKH path for teaching; it does not validate full transactions, enforce every consensus rule, or handle multisig/timelocks/Taproot key tweaks.

Live Demo

systemslibrarian.github.io/crypto-lab-bitcoin-script

A coin is locked to an owner's pubKeyHash. Pick one of four spend scenarios — Valid spend, Wrong public key, Forged signature, or Tampered transaction — and the page assembles the matching scriptSig (unlock) and scriptPubKey (lock), signs (or mis-signs) a real transaction, and shows the resulting stack program. Then Step ▶ (or Auto-run) walks the execution: the token strip highlights the current opcode while the stack grows and shrinks beside a plain-language description of each step, ending in an ACCEPT or REJECT verdict. Three of the four scenarios reject — and each rejection is the security model working: the wrong key aborts at OP_EQUALVERIFY before the signature is even checked, while the forged signature and the tampered transaction both fail at OP_CHECKSIG. ⟳ New keys regenerates the key pair; the page is dark throughout.

What Can Go Wrong

  • A browser is not a vault: keys generated in a web tab can be exposed by malicious extensions, cross-site scripting, or clipboard sniffers — never put real funds behind a browser-generated key.
  • Script reveals the public key on spend: P2PKH hides the key behind a hash until spending, but once spent the key is public; reusing addresses then erodes privacy and (theoretically) quantum resistance.
  • Signatures only commit to what the sighash covers: the "tampered transaction" scenario shows that changing a signed field breaks the signature — but the flip side is that unsigned fields (e.g. legacy malleability of the scriptSig) historically caused real bugs.
  • Historical foot-guns are real: OP_CHECKMULTISIG's off-by-one stack pop and an early value-overflow bug are reminders that even a deliberately small language is not bug-free.
  • This is not consensus-complete: a real node enforces dozens of additional rules (script size limits, standardness, low-S/strict-DER policy, sequence/locktime semantics) that this teaching model does not.

Real-World Usage

  • P2PKH (OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG) secured the majority of historical Bitcoin transactions and is still widely seen on-chain.
  • secp256k1 ECDSA with DER-encoded signatures and a SIGHASH byte is the exact signature format that appears inside real Bitcoin scriptSig/witness data.
  • The same stack machine scales to richer conditions: multisig (OP_CHECKMULTISIG), timelocks (OP_CHECKLOCKTIMEVERIFY / OP_CHECKSEQUENCEVERIFY), and Lightning Network HTLCs.
  • Taproot (P2TR) replaces this pattern for new outputs with Schnorr signatures and key aggregation, improving privacy and efficiency for the common cooperative case.

How to Run Locally

git clone https://github.com/systemslibrarian/crypto-lab-bitcoin-script
cd crypto-lab-bitcoin-script
npm install
npm run dev

No environment variables, no API keys, no servers — everything runs client-side. The build bundles @noble/secp256k1 and @noble/hashes into a single static JS file deployed straight to GitHub Pages, with no remote services and no telemetry. Additional scripts: npm run build (tsc + production build to dist/), npm run preview (serve the built dist/ locally), and npm test (Vitest: engine known-answers, a jsdom run that drives the real stepper, and an axe-core WCAG 2 A/AA gate).

Related Demos


Part of the Crypto Lab suite.

"So whether you eat or drink or whatever you do, do it all for the glory of God." — 1 Corinthians 10:31

About

Browser-based Bitcoin Script demo — step a real P2PKH spend through the stack machine, with valid, wrong-key, forged-signature, and tampered scenarios. Real secp256k1 + HASH160. No backend.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages