From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Wed, 29 Oct 2025 16:56:06 -0700 Received: from mail-ot1-f60.google.com ([209.85.210.60]) by mail.fairlystable.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1vEG1L-0001YQ-E9 for bitcoindev@gnusha.org; Wed, 29 Oct 2025 16:56:06 -0700 Received: by mail-ot1-f60.google.com with SMTP id 46e09a7af769-7c5311ee244sf134631a34.0 for ; Wed, 29 Oct 2025 16:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20230601; t=1761782153; x=1762386953; darn=gnusha.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-sender:mime-version :subject:message-id:to:from:date:sender:from:to:cc:subject:date :message-id:reply-to; bh=aEZeJXQ6fvxm380Y5P1KWQNDiOhImZbFs4FczT9G1wE=; b=jwd4w2cSqcSZ7ex+QGi9Y2biMpU94ZT9etB0VJ1AoGTbp/mIaIKHU2Ktx3/59qRhQy H2tLtdp9v6B1t46nuLKHb+UonegKNrfszBWMQghhaVkN/ahTRn5WurPoRkEmzUijQ8nI u06pE3HiQ5RhB5mBFg8X/knqZOuLEihs2nwgSL303vJohKxJDeZXSrtMqWGrlSRN9bnJ Pq948hSQMCyRgUpTN3Ww5WI5iWNfaU+7hQwCM9dPKjEFUZ7nu4dh6tsr07q2oCkVbEch MTbiAiKvR5DRMBawtLne0EqBrib1XJL5mghF0b6mNB3VURJnzonMxf/Qk5H8Ir6xk3I5 K5XQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761782153; x=1762386953; darn=gnusha.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-sender:mime-version :subject:message-id:to:from:date:from:to:cc:subject:date:message-id :reply-to; bh=aEZeJXQ6fvxm380Y5P1KWQNDiOhImZbFs4FczT9G1wE=; b=ELxHI8GpFI9QhFtzdN3oUCCsqXN6imAaewnGt7Q8mn274qvvn+SjjyhTirx67keKZX qX8X2tYf6R0PSEDtdEi5y2jp4pJE1xemtoTzEAcDqRU4Rrp5EBUsd+0setOTbhxQgXaD YnJOzhLF7ZRLgRMhnZlMW2K6lqvJ1wjat3FmD+AeVHukGgM1OLzB0wLAG9ZEl0SnVYJY oh+64s9QRdKYG71NKf4HTzDm8D8LxVDC7AE+HHsxz7IH4ms7FM1segwsWVWuiKxrhGTV f+D47tfLZcfolSdVT7Z/BZeKhSPggej+5C7bJiFFv7KcfQYTBpV38S7rwk2658bQRi5q dPEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761782153; x=1762386953; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-sender:mime-version :subject:message-id:to:from:date:x-beenthere:x-gm-message-state :sender:from:to:cc:subject:date:message-id:reply-to; bh=aEZeJXQ6fvxm380Y5P1KWQNDiOhImZbFs4FczT9G1wE=; b=JiHDK4w7Kk74lNxe8Do58//mzj77npHOb2nAfKnZc4BfgdICBu6jStJ9VfYhZILL/c PFL0DcZSW+t+h6y8CYEMaMykVC8s3yn3hBk8YjcXmoVckx+9SlnPJYLOCITHn1CRdXH7 pukrzKSJ3GG/G1NkrPMo7MKleUEFVxd+jLzJ9LySwG7u2ZIzn9rxKr7pmthauWLTkWLO wn09+7qA4YVdT/4W33fwLOgyFVWVpnLR9sKPJy+eI96o6Kx+VIEacMQxwK5Nv/zavg+S cQcEPUqeb0YoSuJjh3Av4FraAAhXNicfkQk3CCNLtNE6mXvj0SJ4N406U7gHzHeHro1Y OyxA== Sender: bitcoindev@googlegroups.com X-Forwarded-Encrypted: i=1; AJvYcCVyRK0pmp1amIutkl/4f9m7ChPALv69UiBRfoFcng0qjpqdxCvG4PCFOFXeQYp2UXMdTLD/Tjsg2U9u@gnusha.org X-Gm-Message-State: AOJu0YwguhUVbRJkr53wsqaWy+UAKCsyhj2NBjXEZofwa2aGPAJcUOPV KxGOIsQyP7jNifOEo1FQyTd9n7JIExwlWVG7aw4goQ3LU1YiZx9KJq7e X-Google-Smtp-Source: AGHT+IG/KMRa3TMPstR9yyg1wDaQtxHQLtbQc42beOvbkNo2QDYax3KunsChqbPrT2ZaQYkR/fsudw== X-Received: by 2002:a05:6808:1521:b0:43f:1d72:592 with SMTP id 5614622812f47-44f7a4580c6mr2263199b6e.23.1761782152828; Wed, 29 Oct 2025 16:55:52 -0700 (PDT) X-BeenThere: bitcoindev@googlegroups.com; h="Ae8XA+ZG+4HanDHjOoyqFjPXywa867tWpETiCOw/YR0rNZRF4Q==" Received: by 2002:a05:6870:a093:b0:363:4ae7:c37f with SMTP id 586e51a60fabf-3d8b946edfcls187277fac.0.-pod-prod-05-us; Wed, 29 Oct 2025 16:55:47 -0700 (PDT) X-Received: by 2002:a05:6808:1907:b0:43b:252e:f793 with SMTP id 5614622812f47-44f7a4da2b6mr2192287b6e.36.1761782147834; Wed, 29 Oct 2025 16:55:47 -0700 (PDT) Received: by 2002:a05:690c:a5c1:b0:74f:1486:e2a9 with SMTP id 00721157ae682-78629398ee3ms7b3; Wed, 29 Oct 2025 16:40:51 -0700 (PDT) X-Received: by 2002:a05:690c:2782:b0:771:9673:134 with SMTP id 00721157ae682-78628e90127mr48991417b3.29.1761781250502; Wed, 29 Oct 2025 16:40:50 -0700 (PDT) Date: Wed, 29 Oct 2025 16:40:50 -0700 (PDT) From: defenwycke To: Bitcoin Development Mailing List Message-Id: Subject: [bitcoindev] segOP potential BIP discussion MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_9706_2146719748.1761781250142" X-Original-Sender: cal.defenwycke@gmail.com Precedence: list Mailing-list: list bitcoindev@googlegroups.com; contact bitcoindev+owners@googlegroups.com List-ID: X-Google-Group-Id: 786775582512 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , X-Spam-Score: -0.5 (/) ------=_Part_9706_2146719748.1761781250142 Content-Type: multipart/alternative; boundary="----=_Part_9707_1698293394.1761781250142" ------=_Part_9707_1698293394.1761781250142 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi all, I attempted to propose a BIP earlier today. I was notified of my incorrect= =20 actions versus core procedures. See attached or below - my proposal for discussion. Regards Defenwycke. --- A proposed discussion of segOP Author: Defenwycke / defenwycke@icloud.com 29.10.2025 segOP (Segregated OP_RETURN) A proposed extension to Bitcoin transactions. It introduces a=20 dedicated, structured, full-fee data lane for on-chain data, without=20 disrupting existing transaction rules. Think of it like this - segOP is to= =20 arbitrary data what SegWit was to signatures =E2=80=94 a clean, isolated,= =20 forward-compatible path that preserves old-node harmony while restoring fee= =20 fairness. Abstract: segOP defines a new segregated data section for Bitcoin transactions,= =20 cryptographically committed via OP_SUCCESS184. It standardizes on-chain=20 metadata storage by enforcing full fees, structured TLV encoding, and a 100= =20 KB cap, while remaining backward-compatible with legacy nodes. It is not: - A replacement for OP_RETURN - An off-chain mechanism - A hard fork It is: - A soft-fork-safe, future-proof, SegWit-style data section - Full-fee (4 weight units per byte) - Structured (TLV + Merkle-root verified) - Limited to 100 KB per transaction What issues could segOP rectify?: 1. Ordinals abuse witness discount. segOP will apply full fee rate for= =20 large data. 2. No structured metadata lane. segOP introduces TLV-encoded +=20 Merkle-verified section. 3. Witness discount abused for megabytes. segOP Enforces 100 KB cap. 4. OP_RETURN unstructured & limited. segOP =3D structured + verifiable. 5. Spam cheap storage. segOP deters spam with fees. In short - segOP restores fairness =E2=80=94 data pays its real weight = cost,=20 preserving block space for financial use. Where segOP lives: Transaction Layout (Post-segOP) Transaction =E2=94=9C=E2=94=80=E2=94=80 nVersion =E2=94=9C=E2=94=80=E2=94=80 vin (inputs) =E2=94=9C=E2=94=80=E2=94=80 vout (outputs) =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 P2SOP Output =E2=86=90 segOP an= chor =E2=94=9C=E2=94=80=E2=94=80 witness (if any) =E2=94=9C=E2=94=80=E2=94=80 segOP marker (0xFA) =E2=94=9C=E2=94=80=E2=94=80 segOP section (if present) =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 chunk_count (varint) =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 TLV chunk 1 =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 TLV chunk 2 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 ... =E2=94=94=E2=94=80=E2=94=80 nLockTime Activation rules: - segOP section only appears if at least one P2SOP output exists. - Old nodes ignore unknown post-witness data =E2=86=92 transaction vali= d=20 (soft-fork safe). - New nodes validate the segOP section against the Merkle root in the= =20 P2SOP output. How segOP works: segOP extends the Bitcoin transaction format by adding a new optional= =20 section after the witness field. This section is linked cryptographically to a special output type =E2= =80=94 the=20 P2SOP output =E2=80=94 whose script commits to the Merkle root of the segOP= data. The design mirrors SegWit: a segregated data structure, excluded from= =20 txid but included in wtxid, ensuring backward compatibility. 1. Transaction Creation When a wallet or protocol wants to include on-chain structured= =20 data (for example, a document hash, timestamp, or proof set), it performs= =20 the following steps: a. Build TLV Chunks Each data element is encoded in Type-Length-Value (TLV)= =20 format: - type (varint) - length (varint) - value (bytes) Each type defines a data meaning (e.g., type=3D1:=20 manifest, type=3D2: payload, type=3D3: metadata, etc.). This allows future= =20 extensions without breaking parsers. b. Construct the Merkle Tree Each TLV is hashed as: leaf =3D dsha256(0x00 || TLV) and combined recursively: node =3D dsha256(0x01 || left || right) until a single Merkle root is produced. This root=20 uniquely commits to all TLV data while allowing compact partial proofs. c. Commit to the Root (P2SOP Output) The wallet then inserts a special output into the=20 transaction: scriptPubKey =3D OP_SUCCESS184 0x20 <32-byte Merkle root>=20 (OP_SUCCESS184 is reserved for soft-fork activation). Legacy nodes treat it as =E2=80=9Calways true,=E2=80=9D= so the=20 transaction remains spendable under pre-segOP rules. The 32-byte push commits to the root of the segOP=20 section. Multiple P2SOP outputs may exist if a transaction=20 carries multiple data trees, but each must be validated independently. d. Serialize the segOP Section After the witness data, a segOP marker (0xFA) signals= =20 presence, followed by the serialized data: 0xFA varint: chunk_count [TLV #1] [TLV #2] ... This section is included in the wtxid but not the txid,= =20 keeping legacy hashes unchanged (soft-fork compatible). 2. Transaction Relay and Policy segOP transactions are relayed like any other, with a few=20 policy rules: - Size limit: The total size of segOP data (plus OP_RETURN= =20 + witness data >520 B) must not exceed 100,000 bytes. This prevents block= =20 bloat. - Fee treatment: segOP data counts at 4 weight units per=20 byte (no discount), restoring parity between data and signatures. - Standardness check: Non-mining nodes enforce segOP as a= =20 standard policy rule (like SegWit=E2=80=99s P2WSH), rejecting noncompliant = data=20 from mempool relay. These are policy rules, not consensus, but miners enforcing= =20 them makes segOP behavior uniform across the network. 3. Validation (Node-Level) When a segOP transaction reaches a full node, validation=20 happens in three stages: a. Detect segOP Presence - If any output script begins with OP_SUCCESS184, the= =20 node checks for a corresponding segOP section at the end of the transaction= =20 serialization. - If no segOP section is found =E2=86=92 transaction in= valid=20 under segOP rules. b. Verify Size and Fee The node computes total data size: - All OP_RETURN payloads - All segOP TLVs - All witness items >520 bytes (these count as=20 =E2=80=9Cdata=E2=80=9D) - If this exceeds 100 KB, the transaction is=20 invalid. - The total weight is adjusted to include all segOP= =20 bytes at full cost. c. Verify Merkle Root - The node rebuilds the TLV Merkle tree and ensures: - calculated_root =3D=3D - If the root mismatches =E2=86=92 reject. - This makes segOP cryptographically bound to the=20 transaction body, just like Taproot commits to script paths. 4. Inclusion in a Block - Miners include segOP transactions normally. - When calculating block weight: segOP bytes count fully (4=20 WU/byte). - segOP does not alter the legacy 4M weight limit but competes= =20 fairly for space. - Miners can optionally expose segOP data through RPC or=20 indexing APIs (e.g., gettxoutdata), similar to how they expose witness data= . 5. Verification by Light Clients - Because segOP uses a Merkle structure: SPV clients or oracles= =20 can request proofs for individual TLVs without downloading full data. For= =20 example, a timestamp verifier can request: getsegopproof =20 and receive the TLV + Merkle proof + root verification path.= =20 This makes segOP efficient for decentralized proof storage or timestamping= =20 protocols. 6. Spending a P2SOP Output - Spending a P2SOP output works like spending an OP_SUCCESS=20 output: Until activation, it behaves as anyone-can-spend, ensuring=20 soft-fork safety. After activation, future consensus rules can restrict or= =20 redefine P2SOP redemption scripts. - Example forward path: A future BIP may define OP_SUCCESS184= =20 redemption to require proof of segOP validity or special conditions (e.g.,= =20 hash preimage commitments). Until then, nodes treat these outputs as valid= =20 spends, ensuring no forks. 7. Post-Activation Behavior - After segOP activation: All upgraded nodes enforce the 100 KB= =20 cap and Merkle root validation. - Legacy nodes still accept the transactions, unaware of segOP= =20 structure. - Any mismatch between segOP section and root simply makes the= =20 tx invalid for upgraded miners =E2=80=94 thus ensuring consensus alignment. Examples of segOP: Example 1: Timestamp a Document (50 KB) TLV #1: Type =3D 1, Manifest (JSON) TLV #2: Type =3D 2, PDF payload (50 KB) Build Merkle root =E2=86=92 abc123... Create output: OP_SUCCESS184 0x20 abc123... segOP section: 0x02 # chunk count Fee: =E2=89=88 $30 at current full-fee rates Permanent, verifiable, structured. Example 2: Ordinals Tries 3.8 MB data_size =3D 3.8 MB =E2=86=92 REJECTED (exceeds 100 KB cap) Attempt in witness =E2=86=92 REJECTED (data > 520 B =E2=86=92 full = fee policy =E2=86=92 cap=20 still enforced) Example 3: Normal BTC Send No P2SOP output : No segOP section Fee Unchanged (~$0.09) Normal transactions unaffected. How to Use segOP: Build a segOP Transaction (Python) # 1. Prepare TLV chunks manifest =3D b'{"type":"proof","size":50000}' payload =3D b'50 KB of data...' tlv1 =3D varint(1) + varint(len(manifest)) + manifest tlv2 =3D varint(2) + varint(len(payload)) + payload # 2. Build Merkle root def dsha256(x): return sha256(sha256(x)).digest() leaf1 =3D dsha256(b'\x00' + tlv1) leaf2 =3D dsha256(b'\x00' + tlv2) root =3D dsha256(b'\x01' + leaf1 + leaf2) # 3. Create P2SOP output p2sop =3D b'\xb8\x20' + root # 4. Build segOP section segop =3D b'\xFA' + varint(2) + tlv1 + tlv2 # 0xFA marker # 5. Attach to tx tx.vout.append(CTxOut(0, CScript(p2sop))) tx.segop_section =3D segop Validation Logic (C++ Pseudocode): bool CheckSegOP(const CTransaction& tx) { size_t total_data =3D 0; for (const auto& out : tx.vout) { if (out.scriptPubKey[0] =3D=3D OP_SUCCESS184) { // segOP output detected if (!tx.HasSegOPSection()) return false; total_data +=3D tx.segOPSectionSize(); } if (out.scriptPubKey[0] =3D=3D OP_RETURN &&=20 out.scriptPubKey.size() > 1) { total_data +=3D out.scriptPubKey.size() - 1; } } for (const auto& in : tx.vin) { for (const auto& item : in.scriptWitness.stack) { if (item.size() > 520) total_data +=3D item.size(); // witness data counts= =20 fully } } if (total_data > 100000) return false; // 100 KB consensus cap // Apply full weight to data for fee calc tx.virtual_size +=3D total_data; return true; } Soft Fork Proof: - Old node: Ignores segOP - New node: Validates segOP - No chain split - Backward compatible - Miner-activated soft fork possible via versionbits Developer Q&A: Where is segOP serialized? : After witness, before nLockTime Does it affect txid? : No - only wtxid Can old nodes parse it? : Yes (ignored like witness) Max size? : 100 KB total data Fee rate? : Full fee (4 WU/byte) Can I use OP_RETURN too? : Yes =E2=80=94 total combined data =E2=89=A4 = 100 KB Future extensions? : TLV unknown types ignored (safe forward-compat) How do I signal presence? : 0xFA marker after witness Conclusion: - On-chain - Structured (TLV + Merkle) - Full-fee and fair - Soft-fork safe - Future-proof segOP introduces the clean, capped, verifiable data lane Bitcoin needs= =20 =E2=80=94 ending witness discount abuse while preserving freedom for legiti= mate=20 metadata. --=20 You received this message because you are subscribed to the Google Groups "= Bitcoin Development Mailing List" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoindev+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/= c38d00f7-a42b-4f7b-899e-11e823a43d7dn%40googlegroups.com. ------=_Part_9707_1698293394.1761781250142 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi a= ll,

I attempted to propose a BIP earlier today. I was notified of = my incorrect actions versus core procedures.

See attached or bel= ow - my proposal for discussion.

Regards

Defenwycke.
<= br />
---

A proposed discussion of segOP
Author: Defenwycke /=C2= =A0defenwycke@icloud.com
29.10.2025

segOP (Segregated OP_RET= URN)

=C2=A0=C2=A0=C2=A0 A proposed extension to Bitcoin transactio= ns. It introduces a dedicated, structured, full-fee data lane for on-chain = data, without disrupting existing transaction rules. Think of it like this = - segOP is to arbitrary data what SegWit was to signatures =E2=80=94 a clea= n, isolated, forward-compatible path that preserves old-node harmony while = restoring fee fairness.

Abstract:

=C2=A0=C2=A0=C2=A0 segO= P defines a new segregated data section for Bitcoin transactions, cryptogra= phically committed via OP_SUCCESS184. It standardizes on-chain metadata sto= rage by enforcing full fees, structured TLV encoding, and a 100 KB cap, whi= le remaining backward-compatible with legacy nodes.

It is not:
=C2=A0=C2=A0=C2=A0 - A replacement for OP_RETURN
=C2=A0=C2=A0=C2=A0 = - An off-chain mechanism
=C2=A0=C2=A0=C2=A0 - A hard fork

It is:=
=C2=A0=C2=A0=C2=A0 - A soft-fork-safe, future-proof, SegWit-style= data section
=C2=A0=C2=A0=C2=A0 - Full-fee (4 weight units per byte)
=C2= =A0=C2=A0=C2=A0 - Structured (TLV + Merkle-root verified)
=C2=A0=C2=A0= =C2=A0 - Limited to 100 KB per transaction

What issues could segOP= rectify?:

=C2=A0=C2=A0=C2=A0 1. Ordinals abuse witness discount. = segOP will apply full fee rate for large data.
=C2=A0=C2=A0=C2=A0 2. No st= ructured metadata lane. segOP introduces TLV-encoded + Merkle-verified sect= ion.
=C2=A0=C2=A0=C2=A0 3. Witness discount abused for megabytes. segOP En= forces 100 KB cap.
=C2=A0=C2=A0=C2=A0 4. OP_RETURN unstructured & limi= ted. segOP =3D structured + verifiable.
=C2=A0=C2=A0=C2=A0 5. Spam cheap s= torage. segOP deters spam with fees.

=C2=A0=C2=A0=C2=A0 In short -= segOP restores fairness =E2=80=94 data pays its real weight cost, preservi= ng block space for financial use.

Where segOP lives:

=
=C2= =A0=C2=A0=C2=A0 Transaction Layout (Post-segOP)
=C2=A0=C2=A0=C2=A0 Transac= tion
=C2=A0=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 nVersion
=C2=A0=C2=A0= =C2=A0 =E2=94=9C=E2=94=80=E2=94=80 vin (inputs)
=C2=A0=C2=A0=C2=A0 =E2=94= =9C=E2=94=80=E2=94=80 vout (outputs)
=C2=A0=C2=A0=C2=A0 =E2=94=82=C2=A0=C2= =A0 =E2=94=94=E2=94=80=E2=94=80 P2SOP Output =E2=86=90 segOP anchor
=C2=A0= =C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 witness (if any)
=C2=A0=C2=A0= =C2=A0 =E2=94=9C=E2=94=80=E2=94=80 segOP marker (0xFA)
=C2=A0=C2=A0=C2=A0 = =E2=94=9C=E2=94=80=E2=94=80 segOP section (if present)
=C2=A0=C2=A0=C2=A0 = =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 chunk_count (varint)
=C2= =A0=C2=A0=C2=A0 =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 TLV chunk= 1
=C2=A0=C2=A0=C2=A0 =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 TL= V chunk 2
=C2=A0=C2=A0=C2=A0 =E2=94=82=C2=A0=C2=A0 =E2=94=94=E2=94=80=E2= =94=80 ...
=C2=A0=C2=A0=C2=A0 =E2=94=94=E2=94=80=E2=94=80 nLockTime
<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">
Activation rules:

=C2=A0=C2=A0=C2=A0 - segOP section only appea= rs if at least one P2SOP output exists.
=C2=A0=C2=A0=C2=A0 - Old nodes ign= ore unknown post-witness data =E2=86=92 transaction valid (soft-fork safe).=

How segOP works:

=C2=A0=C2= =A0=C2=A0 segOP extends the Bitcoin transaction format by adding a new opti= onal section after the witness field.
=C2=A0=C2=A0=C2=A0 This section is l= inked cryptographically to a special output type =E2=80=94 the P2SOP output= =E2=80=94 whose script commits to the Merkle root of the segOP data.
=

=C2=A0=C2=A0=C2=A0 The design mirrors SegWit: a segregated data structu= re, excluded from txid but included in wtxid, ensuring backward compatibili= ty.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 1. Transaction Crea= tion

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 When a wallet or protocol wants to include on-chain structured data = (for example, a document hash, timestamp, or proof set), it performs the fo= llowing steps:

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 a. Build TLV Chunks

=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Each data element is encoded in Type-Leng= th-Value (TLV) format:

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 - type (varint)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 - length (varint)
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - value (bytes)

=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 Each type defines a data meaning (e.g., type=3D= 1: manifest, type=3D2: payload, type=3D3: metadata, etc.). This allows futu= re extensions without breaking parsers.

=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 b. Const= ruct the Merkle Tree

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Each = TLV is hashed as:

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 leaf =3D= dsha256(0x00 || TLV)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 and combine= d recursively:
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 node =3D dsha256(= 0x01 || left || right)

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 un= til a single Merkle root is produced. This root uniquely commits to all TLV= data while allowing compact partial proofs.

=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 c. Co= mmit to the Root (P2SOP Output)

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 The wallet then inserts a special output into the transaction: scrip= tPubKey =3D OP_SUCCESS184 0x20 <32-byte Merkle root> (OP_SUCCESS184 i= s reserved for soft-fork activation).
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 Legacy nodes treat it as =E2=80=9Calways true,=E2=80=9D so the transact= ion remains spendable under pre-segOP rules.
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 The 32-byte push commits to the root of the segOP section.
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Multiple P2SOP outputs may exist if= a transaction carries multiple data trees, but each must be validated inde= pendently.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 d. Serialize the segOP Section

=

= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0xFA
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 varint: chunk_count
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= [TLV #1]
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [TLV #2]
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 ...

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 This section is included in the wtxid but not the txid, keeping lega= cy hashes unchanged (soft-fork compatible).

=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 2. Transaction Relay and Policy

=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 segOP transactions a= re relayed like any other, with a few policy rules:

=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 - Size limit: The total size of segOP data (plus OP_RETURN + witness da= ta >520 B) must not exceed 100,000 bytes. This prevents block bloat.
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 - Fee treatment: segOP data counts at 4 weight units per by= te (no discount), restoring parity between data and signatures.
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 - Standardness check: Non-mining nodes enforce segOP as a standard p= olicy rule (like SegWit=E2=80=99s P2WSH), rejecting noncompliant data from = mempool relay.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 These are policy rules, not consens= us, but miners enforcing them makes segOP behavior uniform across the netwo= rk.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 3. Validation (Node= -Level)

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 When a segOP transaction reaches a full node, validation happens = in three stages:

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 a. Detect segOP Presence

=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 - If no segOP section is found =E2=86=92 transaction invalid under segO= P rules.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 b. Verify Size and Fee

=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The node computes total data size:
=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - All OP_RETURN p= ayloads
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - = All segOP TLVs
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 - All witness items >520 bytes (these count as =E2=80=9Cdata=E2= =80=9D)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - = If this exceeds 100 KB, the transaction is invalid.
=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - The total weight is adjusted t= o include all segOP bytes at full cost.

=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 c. Verif= y Merkle Root

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - The node = rebuilds the TLV Merkle tree and ensures:
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 - calculated_root =3D=3D <root in P2SOP output>
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - If the root mismatches =E2=86=92 reject.
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - This makes segOP cryptographicall= y bound to the transaction body, just like Taproot commits to script paths.=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 4. Inclusion in a Bloc= k

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 - Miners include segOP transactions normally.
=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - When calculating block weight:= segOP bytes count fully (4 WU/byte).
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - segOP does not alter the legacy 4M weight = limit but competes fairly for space.
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - Miners can optionally expose segOP data th= rough RPC or indexing APIs (e.g., gettxoutdata), similar to how they expose= witness data.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 5. Verif= ication by Light Clients

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 - Because segOP uses a Merkle structure: SPV cl= ients or oracles can request proofs for individual TLVs without downloading= full data. For example, a timestamp verifier can request: getsegopproof &l= t;txid> <chunk_type> and receive the TLV + Merkle proof + root ver= ification path. This makes segOP efficient for decentralized proof storage = or timestamping protocols.

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 6. Spending a P2SOP Output

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - Spending a P2SOP output works like spen= ding an OP_SUCCESS output: Until activation, it behaves as anyone-can-spend= , ensuring soft-fork safety. After activation, future consensus rules can r= estrict or redefine P2SOP redemption scripts.
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - Example forward path: A future BI= P may define OP_SUCCESS184 redemption to require proof of segOP validity or= special conditions (e.g., hash preimage commitments). Until then, nodes tr= eat these outputs as valid spends, ensuring no forks.

=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 7. Post-Activation Behavior

=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - After segOP = activation: All upgraded nodes enforce the 100 KB cap and Merkle root valid= ation.
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 = - Legacy nodes still accept the transactions, unaware of segOP structure.
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 - Any mi= smatch between segOP section and root simply makes the tx invalid for upgra= ded miners =E2=80=94 thus ensuring consensus alignment.

Examples o= f segOP:

=C2=A0=C2=A0=C2=A0 Example 1: Timestamp a Document (50 KB= )
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TLV #1: Type =3D 1, Manifest = (JSON)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TLV #2: Type =3D 2, PDF = payload (50 KB)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Build Merkle ro= ot =E2=86=92 abc123...
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Create o= utput:
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OP_SUCCESS184 0x20 abc12= 3...
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 segOP section:
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0x02=C2=A0 # chunk count
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <TLV1> <TLV2>
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 Fee: =E2=89=88 $30 at current full-fee rates
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Permanent, verifiable, structure= d.

=C2=A0=C2=A0=C2=A0 Example 2: Ordinals Tries 3.8 MB
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 data_size =3D 3.8 MB =E2=86=92 REJECTED (= exceeds 100 KB cap)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Attempt in = witness =E2=86=92 REJECTED (data > 520 B =E2=86=92 full fee policy =E2= =86=92 cap still enforced)

=C2=A0=C2=A0=C2=A0 Example 3: Normal BT= C Send
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 No P2SOP output : No seg= OP section
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Fee Unchanged (~$0.0= 9)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Normal transactions unaffect= ed.

How to Use segOP:

=C2=A0=C2=A0=C2=A0 Build a segOP Tr= ansaction (Python)

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 # 1.= Prepare TLV chunks
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 manifest = =3D b'{"type":"proof","size":50000}'
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 payload=C2=A0 =3D b'50 KB of data...'
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 tlv1 =3D varint(1) + varint(len(manifest)) + manifest
=
=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tlv2 =3D varint(2) + varint(len(pay= load)) + payload

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 # 2. B= uild Merkle root
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 def dsha256(x)= : return sha256(sha256(x)).digest()
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 leaf1 =3D dsha256(b'\x00' + tlv1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 leaf2 =3D dsha256(b'\x00' + tlv2)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 root=C2=A0 =3D dsha256(b'\x01' + leaf1 + leaf2)

<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 # 3. Create P2SOP output
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 p2sop =3D b'\xb8\x20' + root

=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 # 4. Build segOP section
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 segop =3D b'\xFA' + varint(2) + tlv1 + tl= v2=C2=A0 # 0xFA marker

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 = # 5. Attach to tx
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tx.vout.appen= d(CTxOut(0, CScript(p2sop)))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tx= .segop_section =3D segop

=C2=A0=C2=A0=C2=A0 Validation Logic (C++ = Pseudocode):

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bool Check= SegOP(const CTransaction& tx) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 size_t total_data =3D 0;

=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (const auto&a= mp; out : tx.vout) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (out.scriptPubKey[0] =3D=3D OP_S= UCCESS184) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // segOP output dete= cted
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!tx.HasSegOPSection()) re= turn false;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 total_data +=3D tx.s= egOPSectionSize();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (out.scriptPub= Key[0] =3D=3D OP_RETURN && out.scriptPubKey.size() > 1) {
<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 total_data +=3D out.scriptPubKey.size(= ) - 1;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 for (const auto& in : tx.vin) {
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 for (const auto& item : in.scriptWitness.stack) {
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 if (item.size() > 520)
=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 total_data +=3D item.size(); = // witness data counts fully
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (total_data > 100000) r= eturn false; // 100 KB consensus cap

=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Apply full weight to data for fe= e calc
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 = tx.virtual_size +=3D total_data;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 return true;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 }

Soft Fork Proof:

=C2=A0=C2=A0=C2=A0 - Old nod= e: Ignores segOP
=C2=A0=C2=A0=C2=A0 - New node: Validates segOP
=C2=A0=C2= =A0=C2=A0 - No chain split
=C2=A0=C2=A0=C2=A0 - Backward compatible
<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">=C2= =A0=C2=A0=C2=A0 - Miner-activated soft fork possible via versionbits
<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">
Developer Q&A:

=C2=A0=C2=A0=C2=A0 Where is segOP serialized= ? : After witness, before nLockTime
=C2=A0=C2=A0=C2=A0 Does it affect txid= ? : No - only wtxid
=C2=A0=C2=A0=C2=A0 Can old nodes parse it? : Yes (igno= red like witness)
=C2=A0=C2=A0=C2=A0 Max size? : 100 KB total data
=C2=A0= =C2=A0=C2=A0 Fee rate? : Full fee (4 WU/byte)
=C2=A0=C2=A0=C2=A0 Can I use= OP_RETURN too? : Yes =E2=80=94 total combined data =E2=89=A4 100 KB
<= div style=3D"color: rgba(0, 0, 0, 0.88); font-family: "SF Pro Text&quo= t;, system-ui, sans-serif; font-size: 17px; letter-spacing: -0.37px;">=C2= =A0=C2=A0=C2=A0 Future extensions? : TLV unknown types ignored (safe forwar= d-compat)
=C2=A0=C2=A0=C2=A0 How do I signal presence? : 0xFA marker after= witness


Conclusion:

=C2=A0=C2=A0=C2=A0 - On-chai= n
=C2=A0=C2=A0=C2=A0 - Structured (TLV + Merkle)
=C2=A0=C2=A0=C2=A0 - Ful= l-fee and fair
=C2=A0=C2=A0=C2=A0 - Soft-fork safe
=C2=A0=C2=A0=C2=A0 - F= uture-proof

=C2=A0=C2=A0=C2=A0 segOP introduces the clean, capped,= verifiable data lane Bitcoin needs =E2=80=94 ending witness discount abuse= while preserving freedom for legitimate metadata.

--
You received this message because you are subscribed to the Google Groups &= quot;Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoind= ev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoind= ev/c38d00f7-a42b-4f7b-899e-11e823a43d7dn%40googlegroups.com.
------=_Part_9707_1698293394.1761781250142-- ------=_Part_9706_2146719748.1761781250142 Content-Type: text/plain; charset=UTF-8; name="A proposed discussion of segOP.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="A proposed discussion of segOP.txt" X-Attachment-Id: 9481f165-b42b-405d-884f-c41887378d71 Content-ID: <9481f165-b42b-405d-884f-c41887378d71> A proposed discussion of segOP Author: Defenwycke / defenwycke@icloud.com 29.10.2025 segOP (Segregated OP_RETURN) A proposed extension to Bitcoin transactions. It introduces a dedicated= , structured, full-fee data lane for on-chain data, without disrupting exis= ting transaction rules. Think of it like this - segOP is to arbitrary data = what SegWit was to signatures =E2=80=94 a clean, isolated, forward-compatib= le path that preserves old-node harmony while restoring fee fairness. Abstract: segOP defines a new segregated data section for Bitcoin transactions, c= ryptographically committed via OP_SUCCESS184. It standardizes on-chain meta= data storage by enforcing full fees, structured TLV encoding, and a 100 KB = cap, while remaining backward-compatible with legacy nodes. It is not: - A replacement for OP_RETURN - An off-chain mechanism - A hard fork It is: - A soft-fork-safe, future-proof, SegWit-style data section - Full-fee (4 weight units per byte) - Structured (TLV + Merkle-root verified) - Limited to 100 KB per transaction What issues could segOP rectify?: 1. Ordinals abuse witness discount. segOP will apply full fee rate for = large data. 2. No structured metadata lane. segOP introduces TLV-encoded + Merkle-v= erified section. 3. Witness discount abused for megabytes. segOP=09Enforces 100 KB cap. 4. OP_RETURN unstructured & limited. segOP =3D structured + verifiable. 5. Spam cheap storage. segOP deters spam with fees. In short - segOP restores fairness =E2=80=94 data pays its real weight = cost, preserving block space for financial use. Where segOP lives: Transaction Layout (Post-segOP) Transaction =E2=94=9C=E2=94=80=E2=94=80 nVersion =E2=94=9C=E2=94=80=E2=94=80 vin (inputs) =E2=94=9C=E2=94=80=E2=94=80 vout (outputs) =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 P2SOP Output =E2=86=90 segOP an= chor =E2=94=9C=E2=94=80=E2=94=80 witness (if any) =E2=94=9C=E2=94=80=E2=94=80 segOP marker (0xFA) =E2=94=9C=E2=94=80=E2=94=80 segOP section (if present) =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 chunk_count (varint) =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 TLV chunk 1 =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 TLV chunk 2 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 ... =E2=94=94=E2=94=80=E2=94=80 nLockTime Activation rules: - segOP section only appears if at least one P2SOP output exists. - Old nodes ignore unknown post-witness data =E2=86=92 transaction vali= d (soft-fork safe). - New nodes validate the segOP section against the Merkle root in the P= 2SOP output. How segOP works: segOP extends the Bitcoin transaction format by adding a new optional s= ection after the witness field. This section is linked cryptographically to a special output type =E2= =80=94 the P2SOP output =E2=80=94 whose script commits to the Merkle root o= f the segOP data. The design mirrors SegWit: a segregated data structure, excluded from t= xid but included in wtxid, ensuring backward compatibility. 1. Transaction Creation When a wallet or protocol wants to include on-chain structured = data (for example, a document hash, timestamp, or proof set), it performs t= he following steps: a. Build TLV Chunks Each data element is encoded in Type-Length-Value (TLV)= format: - type (varint) - length (varint) - value (bytes) Each type defines a data meaning (e.g., type=3D1: manif= est, type=3D2: payload, type=3D3: metadata, etc.). This allows future exten= sions without breaking parsers. b. Construct the Merkle Tree Each TLV is hashed as: leaf =3D dsha256(0x00 || TLV) and combined recursively: node =3D dsha256(0x01 || left || right) until a single Merkle root is produced. This root uniqu= ely commits to all TLV data while allowing compact partial proofs. c. Commit to the Root (P2SOP Output) The wallet then inserts a special output into the trans= action: scriptPubKey =3D OP_SUCCESS184 0x20 <32-byte Merkle root> (OP_SUCCE= SS184 is reserved for soft-fork activation). Legacy nodes treat it as =E2=80=9Calways true,=E2=80=9D= so the transaction remains spendable under pre-segOP rules. The 32-byte push commits to the root of the segOP secti= on. Multiple P2SOP outputs may exist if a transaction carri= es multiple data trees, but each must be validated independently. d. Serialize the segOP Section After the witness data, a segOP marker (0xFA) signals p= resence, followed by the serialized data: 0xFA varint: chunk_count [TLV #1] [TLV #2] ... This section is included in the wtxid but not the txid,= keeping legacy hashes unchanged (soft-fork compatible). 2. Transaction Relay and Policy segOP transactions are relayed like any other, with a few polic= y rules: - Size limit: The total size of segOP data (plus OP_RETURN = + witness data >520 B) must not exceed 100,000 bytes. This prevents block b= loat. - Fee treatment: segOP data counts at 4 weight units per by= te (no discount), restoring parity between data and signatures. - Standardness check: Non-mining nodes enforce segOP as a s= tandard policy rule (like SegWit=E2=80=99s P2WSH), rejecting noncompliant d= ata from mempool relay. These are policy rules, not consensus, but miners enforcing= them makes segOP behavior uniform across the network. 3. Validation (Node-Level) When a segOP transaction reaches a full node, validation happen= s in three stages: a. Detect segOP Presence - If any output script begins with OP_SUCCESS184, the n= ode checks for a corresponding segOP section at the end of the transaction = serialization. - If no segOP section is found =E2=86=92 transaction in= valid under segOP rules. b. Verify Size and Fee The node computes total data size: - All OP_RETURN payloads - All segOP TLVs - All witness items >520 bytes (these count as =E2= =80=9Cdata=E2=80=9D) - If this exceeds 100 KB, the transaction is invali= d. - The total weight is adjusted to include all segOP= bytes at full cost. c. Verify Merkle Root - The node rebuilds the TLV Merkle tree and ensures: - calculated_root =3D=3D - If the root mismatches =E2=86=92 reject. - This makes segOP cryptographically bound to the trans= action body, just like Taproot commits to script paths. 4. Inclusion in a Block - Miners include segOP transactions normally. - When calculating block weight: segOP bytes count fully (4 WU/= byte). - segOP does not alter the legacy 4M weight limit but competes = fairly for space. - Miners can optionally expose segOP data through RPC or indexi= ng APIs (e.g., gettxoutdata), similar to how they expose witness data. 5. Verification by Light Clients - Because segOP uses a Merkle structure: SPV clients or oracles= can request proofs for individual TLVs without downloading full data. For = example, a timestamp verifier can request: getsegopproof and receive the TLV + Merkle proof + root verification path. This makes s= egOP efficient for decentralized proof storage or timestamping protocols. 6. Spending a P2SOP Output - Spending a P2SOP output works like spending an OP_SUCCESS out= put: Until activation, it behaves as anyone-can-spend, ensuring soft-fork s= afety. After activation, future consensus rules can restrict or redefine P2= SOP redemption scripts. - Example forward path: A future BIP may define OP_SUCCESS184 r= edemption to require proof of segOP validity or special conditions (e.g., h= ash preimage commitments). Until then, nodes treat these outputs as valid s= pends, ensuring no forks. 7. Post-Activation Behavior - After segOP activation: All upgraded nodes enforce the 100 KB= cap and Merkle root validation. - Legacy nodes still accept the transactions, unaware of segOP = structure. - Any mismatch between segOP section and root simply makes the = tx invalid for upgraded miners =E2=80=94 thus ensuring consensus alignment. Examples of segOP: Example 1: Timestamp a Document (50 KB) TLV #1: Type =3D 1, Manifest (JSON) TLV #2: Type =3D 2, PDF payload (50 KB) Build Merkle root =E2=86=92 abc123... Create output: OP_SUCCESS184 0x20 abc123... segOP section: 0x02 # chunk count Fee: =E2=89=88 $30 at current full-fee rates Permanent, verifiable, structured. Example 2: Ordinals Tries 3.8 MB data_size =3D 3.8 MB =E2=86=92 REJECTED (exceeds 100 KB cap) Attempt in witness =E2=86=92 REJECTED (data > 520 B =E2=86=92 full = fee policy =E2=86=92 cap still enforced) Example 3: Normal BTC Send No P2SOP output=09: No segOP section Fee=09Unchanged (~$0.09) Normal transactions unaffected. How to Use segOP: Build a segOP Transaction (Python) # 1. Prepare TLV chunks manifest =3D b'{"type":"proof","size":50000}' payload =3D b'50 KB of data...' tlv1 =3D varint(1) + varint(len(manifest)) + manifest tlv2 =3D varint(2) + varint(len(payload)) + payload # 2. Build Merkle root def dsha256(x): return sha256(sha256(x)).digest() leaf1 =3D dsha256(b'\x00' + tlv1) leaf2 =3D dsha256(b'\x00' + tlv2) root =3D dsha256(b'\x01' + leaf1 + leaf2) # 3. Create P2SOP output p2sop =3D b'\xb8\x20' + root # 4. Build segOP section segop =3D b'\xFA' + varint(2) + tlv1 + tlv2 # 0xFA marker # 5. Attach to tx tx.vout.append(CTxOut(0, CScript(p2sop))) tx.segop_section =3D segop Validation Logic (C++ Pseudocode): bool CheckSegOP(const CTransaction& tx) { size_t total_data =3D 0; for (const auto& out : tx.vout) { if (out.scriptPubKey[0] =3D=3D OP_SUCCESS184) { // segOP output detected if (!tx.HasSegOPSection()) return false; total_data +=3D tx.segOPSectionSize(); } if (out.scriptPubKey[0] =3D=3D OP_RETURN && out.scriptPubKe= y.size() > 1) { total_data +=3D out.scriptPubKey.size() - 1; } } for (const auto& in : tx.vin) { for (const auto& item : in.scriptWitness.stack) { if (item.size() > 520) total_data +=3D item.size(); // witness data counts= fully } } if (total_data > 100000) return false; // 100 KB consensus cap // Apply full weight to data for fee calc tx.virtual_size +=3D total_data;=20 return true; } Soft Fork Proof: - Old node: Ignores segOP - New node: Validates segOP - No chain split - Backward compatible - Miner-activated soft fork possible via versionbits Developer Q&A: Where is segOP serialized? : After witness, before nLockTime Does it affect txid? : No - only wtxid Can old nodes parse it?=09: Yes (ignored like witness) Max size? : 100 KB total data Fee rate? : Full fee (4 WU/byte) Can I use OP_RETURN too? : Yes =E2=80=94 total combined data =E2=89=A4 = 100 KB Future extensions? : TLV unknown types ignored (safe forward-compat) How do I signal presence? : 0xFA marker after witness Conclusion: - On-chain - Structured (TLV + Merkle) - Full-fee and fair - Soft-fork safe - Future-proof segOP introduces the clean, capped, verifiable data lane Bitcoin needs = =E2=80=94 ending witness discount abuse while preserving freedom for legiti= mate metadata. ------=_Part_9706_2146719748.1761781250142--