Skip to content

Updated for Zig 0.16.0 and 0.17.0 - #1

Open
samooth wants to merge 14 commits into
opldotdev:mainfrom
samooth:main
Open

samooth wants to merge 14 commits into
opldotdev:mainfrom
samooth:main

Conversation

@samooth

@samooth samooth commented Aug 27, 2026

Copy link
Copy Markdown

Updated for Zig 0.16.0 and 0.17.0

samooth and others added 14 commits August 23, 2026 17:19
…-string API, ArrayList empty init, graceful corpus skips, CI matrix
ScriptIterator yields one ScriptChunk at a time without allocation.
Tracks cursor position and conditional depth internally. Handles
OP_RETURN short-circuit for top-level data scripts.

parseAlloc, countChunks, isPushOnly, and hasCodeSeparator all
refactored to use ScriptIterator internally.
Beef.bytes() always writes V2. V1 serialization is a Transaction concern.
Remove bytesV1() from Beef, write BEEF_V2 directly in writeVersionAndBUMPs.
- Create src/exports.zig with 18 export fn declarations
- BIP39: mnemonic generation + seed derivation
- BIP32: HD key from seed, derive path, extract privkey bytes
- BRC-42/43: Type-42 key derivation, invoice formatting
- Key ops: privkey↔pubkey, pubkey→address, WIF encode/decode
- BSM: sign/verify (legacy compat)
- BRC-77: sign/verify for anyone and targeted recipients
- Create include/bsvz.h C header with extern "C" guards
- Add bsvz_c static library target in build.zig
- All symbols verified in libbsvz_c.a via nm
Implements KeyDeriver struct matching Go wallet.KeyDeriver with
DerivePublicKey, DerivePrivateKey, and RevealSpecificSecret methods.
Supports self, other, and anyone counterparty types.
Replace .{0} ** 32 with @as([32]u8, @Splat(0)) for Zig 0.17+ compat
Replace .{0} ** 31 ++ .{val} with @Memset for proper 32-byte arrays
Also fix variable name in one test
Implements the script-related behavior of the BSV Chronicle upgrade,
verified against bitcoin-sv/bitcoin-sv (master) and the chronicle-spec.

Opcodes:
- Rename OP_NOP4-8 -> OP_SUBSTR/OP_LEFT/OP_RIGHT/OP_LSHIFTNUM/
  OP_RSHIFTNUM (legacy names kept as aliases; fromAsm parses both,
  toAsm emits the new names)
- Add OP_2MUL (0x8d) / OP_2DIV (0x8e), era-gated per the node's
  IsOpcodeDisabled
- OP_VER pushes the tx version (4-byte LE); OP_VERIF/OP_VERNOTIF are
  conditionals comparing a 4-byte stack item for equality with the tx
  version (node interpreter.cpp uses ranges::equal; the spec prose
  claiming >= is wrong - see docs/low-level/chronicle.md)
- SUBSTR/LEFT/RIGHT with the node's exact bounds checks; LSHIFTNUM/
  RSHIFTNUM sign-preserving with trunc-toward-zero right shift and
  max_script_number_length enforcement via new ScriptNum.shiftLeftNum/
  shiftRightNum

Era flags (mirror SCRIPT_CHRONICLE vs SCRIPT_UTXO_AFTER_CHRONICLE):
- chronicle (block era) gates malleability relaxation and the
  SIGHASH_CHRONICLE bit; utxo_after_chronicle (per-input) gates the
  new opcodes; invalid combo rejected
- Defaults are post-Chronicle: max_script_number_length = 32MB;
  postGenesisBsv() now means pre-Chronicle (750KB)

Malleability relaxation (node EnforceNonMalleability):
- chronicle + tx.version > 1 skips low_s (high-S only), minimal_data,
  minimal_if, null_fail, null_dummy, clean_stack, sig_push_only;
  DER/strict encoding never relaxed; null tx keeps enforcing

OTDA:
- SIGHASH_CHRONICLE (0x20); forkid-without-chronicle -> BIP143,
  0x60 hashtypes -> original digest; IllegalChronicle when the bit is
  used with the era flag off; chronicle hashtype masks out of the
  base-type validation
- CHECKSIG/CHECKMULTISIG in unlocking scripts append the scriptPubKey
  to the signed scriptCode under Chronicle
- p2pkh_spend.chronicle_scope (0x61) signs over OTDA

Breaking: exhaustive Opcode switches must handle the renamed variants.
# Conflicts:
#	src/primitives/key_deriver.zig
#	src/script/parser.zig
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants