diff --git a/src/my_tx_flows/customFlows.ts b/src/my_tx_flows/customFlows.ts index ccf9708..bcee015 100644 --- a/src/my_tx_flows/customFlows.ts +++ b/src/my_tx_flows/customFlows.ts @@ -19,6 +19,7 @@ import Taproot_Intro from "@/my_tx_flows/p11_Taproot_intro.json"; import Taproot_Script from "@/my_tx_flows/p12_Taproot_script.json"; import Taproot_MultiSig from "@/my_tx_flows/p13_Taproot_MultiSig.json"; import MuSig2 from "@/my_tx_flows/p14_MuSig2.json"; +import NonStandardP2SH from "@/my_tx_flows/p15_NonStandard_P2SH_Aviral.json"; // Then build the array, casting each import to FlowData: export const customFlows = [ @@ -93,4 +94,9 @@ export const customFlows = [ label: "MuSig2", data: MuSig2 as unknown as FlowData, }, + { + id: "flow-15", + label: "Non-Standard P2SH: Validity vs. Relay Policy", + data: NonStandardP2SH as unknown as FlowData, + }, ]; diff --git a/src/my_tx_flows/p15_NonStandard_P2SH_Aviral.json b/src/my_tx_flows/p15_NonStandard_P2SH_Aviral.json new file mode 100644 index 0000000..90a8648 --- /dev/null +++ b/src/my_tx_flows/p15_NonStandard_P2SH_Aviral.json @@ -0,0 +1,5530 @@ +{ + "name": "flow-1777161723893", + "schemaVersion": 1, + "runtimeSemantics": { + "version": 1, + "inputResolution": { + "precedence": [ + "__FORCE00__", + "__EMPTY__", + "__NULL__", + "edge value", + "manual text" + ], + "sentinels": { + "__FORCE00__": "Forces effective input value to the hex string '00'.", + "__EMPTY__": "Forces effective input value to an empty string.", + "__NULL__": "Marker value interpreted by function-specific runtime rules." + }, + "functionSpecificRules": [ + "musig2_nonce_gen: vals[2] '__NULL__' is translated to null before function call." + ] + }, + "typeCoercion": { + "integerParams": "Parameters declared as 'integer' in function specs are cast to int when non-empty.", + "numberParams": "Parameters declared as 'number' in function specs are cast to float when non-empty." + } + }, + "nodes": [ + { + "id": "cc01_intro", + "type": "shadcnTextInfo", + "position": { + "x": 450, + "y": 270 + }, + "data": { + "content": "# Non-Standard P2SH: Validity vs. Relay Policy\n\n## Lesson Overview\n\nThis flow constructs a Bitcoin transaction that is consensus-valid yet rejected by default relay policy on testnet3. The eleven steps below mirror the canvas top-to-bottom, left-to-right.\n\n1. Derive a P2PKH address from a private key.\n2. Parse a real funding transaction with `extract_tx_field` and assert it pays the derived address.\n3. Build a non-standard P2SH redeemScript implementing the puzzle `x + 2 = 5`.\n4. Construct and sign TX1 (P2PKH → P2SH) on-canvas using a Lesson 1-style ECDSA Low-R signing pipeline.\n5. Derive TX1's TXID directly from the signed bytes via `double_sha256` and `reverse_txid_bytes`.\n6. Re-extract TX1's output fields and assert they match the constructed values.\n7. Construct TX2: spend the P2SH output to a freshly-derived P2PKH recipient, with on-canvas fee math.\n8. Verify TX2's script: `VerifyScript()` returns `TRUE` (consensus-valid).\n9. Compare the observed broadcast response from a default-policy node against the expected `bad-txns-nonstandard-inputs` rejection.\n10. TXID comparisons are performed on-canvas and automatic.\n11. Aggregate every invariant and every evidence comparison through a single `Check Result` node.\n\n**Key insight.** A transaction can be consensus-valid yet relay-rejected. The split between `VerifyScript()` and `IsStandardTx()` / `AreInputsStandard()` is the central subject of this lesson.\n\n**Enforcement.** The global `Check Result` gate stays `false` until real RPC output is pasted into the Observed Broadcast Response node. The flow cannot self-validate.\n\n---\n*The private key embedded in this flow is for demonstration only.*", + "fontSize": 24, + "width": 626, + "height": 752, + "title": "Lesson Overview", + "dirty": false + }, + "width": 952, + "height": 780 + }, + { + "id": "cc02_privkey", + "type": "calculation", + "position": { + "x": 1787.1011207085216, + "y": 681.7963108760273 + }, + "data": { + "functionName": "identity", + "title": "Private Key", + "showField": true, + "numInputs": 0, + "value": "a1322cd573b5df00ec636d98276777b7d87f8b46df40cb4f97ae11e40502f76d", + "dirty": false, + "version": 0, + "inputs": { + "val": "a1322cd573b5df00ec636d98276777b7d87f8b46df40cb4f97ae11e40502f76d" + }, + "result": "a1322cd573b5df00ec636d98276777b7d87f8b46df40cb4f97ae11e40502f76d", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Private Key (hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#f97316", + "showComment": true, + "comment": "⚠️ Don't reuse private keys", + "error": false + } + }, + { + "id": "cc03_pubkey", + "type": "calculation", + "position": { + "x": 2253.416680164934, + "y": 734.4865141812511 + }, + "data": { + "functionName": "public_key_from_private_key", + "title": "PrivKey → PubKey", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "a1322cd573b5df00ec636d98276777b7d87f8b46df40cb4f97ae11e40502f76d" + }, + "result": "02ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Private Key (hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#3b82f6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc04_h160", + "type": "calculation", + "position": { + "x": 2706.0834406529048, + "y": 756.332624725263 + }, + "data": { + "functionName": "hash160_hex", + "title": "Data → HASH160", + "paramExtraction": "single_val", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "02ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51" + }, + "result": "20d0afaa02179ee086043dbb3a0af65496d4665a", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Pubkey (hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#8b5cf6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc05_addr", + "type": "calculation", + "position": { + "x": 3253.4166801649303, + "y": 734.4865141812511 + }, + "data": { + "functionName": "hash160_to_p2pkh_address", + "title": "HASH160 → P2PKH Address", + "numInputs": 1, + "showField": false, + "networkDependent": true, + "selectedNetwork": "testnet", + "dirty": false, + "groupInstances": {}, + "result": "miWTuxpD2hJ33sFirAMLHR44TTqSHUvBA1", + "inputs": { + "val": "20d0afaa02179ee086043dbb3a0af65496d4665a", + "selectedNetwork": "testnet" + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "HASH160:", + "placeholder": "20-byte hash", + "rows": 2 + } + ] + }, + "borderColor": "#10b981", + "showComment": true, + "comment": "Fund this testnet address https://coinfaucet.eu/en/btc-testnet/", + "error": false + } + }, + { + "id": "cc11_p2pkh_spk", + "type": "calculation", + "position": { + "x": 3502.3671309694987, + "y": 1239.6063864566688 + }, + "data": { + "functionName": "concat_all", + "title": "P2PKH scriptPubKey", + "paramExtraction": "multi_val", + "numInputs": 4, + "inputs": { + "vals": { + "0": "76a9", + "100": "14", + "200": "20d0afaa02179ee086043dbb3a0af65496d4665a", + "300": "88ac" + } + }, + "dirty": false, + "version": 0, + "result": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac", + "inputStructure": { + "groups": [ + { + "title": "INPUTS[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 1, + "maxInstances": 25, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "INPUTS[]": 4 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100, + 200, + 300 + ] + }, + "baseHeight": 80, + "borderColor": "#10b981", + "showComment": true, + "comment": "OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG", + "error": false, + "totalInputs": 4, + "unwiredCount": 0 + } + }, + { + "id": "cc12_fund_title", + "type": "shadcnTextInfo", + "position": { + "x": 4895.443928602723, + "y": 541.2406973004423 + }, + "data": { + "content": "# Step 2 — Fund the P2PKH Address\n\nThe funding transaction hex is pre-filled with real testnet3 data. The entire canvas operates offline — no real testnet coins or network confirmations are required.\n\n**TX Field Extract** parses live fields from the pre-filled hex:\n\n| Field | Use |\n|-------|-----|\n| `txid` | prev-TXID for TX1's input |\n| `vout.value` | input amount for TX1 fee math |\n| `vout.scriptPubKey` | compared to the derived P2PKH scriptPubKey |\n| `output_count` | gates the assumption that vout index 0 is spent |\n\nEvery Compare and Check node downstream must read `true` before TX1 is considered well-formed.", + "fontSize": 24, + "width": 1344, + "height": 541, + "title": "Fund the Address", + "dirty": false + }, + "width": 1056, + "height": 600 + }, + { + "id": "cc13_fund_tx", + "type": "calculation", + "position": { + "x": 6057.20456666769, + "y": 1220.7612526067635 + }, + "data": { + "functionName": "identity", + "title": "Funding TX (from faucet)", + "showField": true, + "numInputs": 0, + "value": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "dirty": false, + "version": 0, + "inputs": { + "val": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000" + }, + "result": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX hex:", + "rows": 4 + } + ] + }, + "groupInstances": {}, + "borderColor": "#f59e0b", + "showComment": true, + "comment": "Testnet3 TX — from faucet or block explorer", + "error": false + } + }, + { + "id": "cc14_ex_txid", + "type": "calculation", + "position": { + "x": 6667.072526071029, + "y": 630.0167418855176 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract: TXID", + "paramExtraction": "multi_val", + "numInputs": 2, + "dirty": false, + "result": "a032b956ef42c2f972ace1e93431b4de2a792cec00e5695385fd2c3bc2549427", + "inputs": { + "vals": { + "0": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "1": "txid" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "cc16_ex_amount", + "type": "calculation", + "position": { + "x": 6676.970551232714, + "y": 1157.9687333130428 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract: vout.value (sats)", + "paramExtraction": "multi_val", + "numInputs": 3, + "dirty": false, + "result": "50000", + "inputs": { + "vals": { + "0": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "1": "vout.value", + "2": "0" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Index (opt):", + "placeholder": "0", + "rows": 1, + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "cc17_ex_spk", + "type": "calculation", + "position": { + "x": 6672.796251926204, + "y": 1817.4035315755675 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract: vout.scriptPubKey", + "paramExtraction": "multi_val", + "numInputs": 3, + "dirty": false, + "result": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac", + "inputs": { + "vals": { + "0": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "1": "vout.scriptPubKey", + "2": "0" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Index (opt):", + "placeholder": "0", + "rows": 1, + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "cc18_redeem_title", + "type": "shadcnTextInfo", + "position": { + "x": 9314.454350270571, + "y": 508.57651844475674 + }, + "data": { + "content": "# Step 3 — Non-Standard P2SH RedeemScript\n\n**Pay-to-Script-Hash (BIP16)** commits to the hash of an arbitrary script. The full script is revealed only at spend time.\n\n## RedeemScript: `52 93 55 87`\n\n- `52` — `OP_2`\n- `93` — `OP_ADD`\n- `55` — `OP_5`\n- `87` — `OP_EQUAL`\n\nThe puzzle `x + 2 == 5` is solved by pushing `3` (`OP_3` = `0x53`) in the scriptSig before revealing the redeemScript.\n\n## Why this redeemScript is non-standard\n\nBitcoin Core's `Solver()` recognises a fixed list of output templates: `P2PK`, `P2PKH`, `P2MS` (`n ≤ 3`), `P2SH`, `P2WPKH`, `P2WSH`, `P2TR`, `NULL_DATA`.\n\nThe P2SH **output** template `OP_HASH160 OP_EQUAL` is itself standard. However, when *spending* a P2SH UTXO, `AreInputsStandard()` runs `Solver()` on the **inner redeemScript** as well. `OP_2 OP_ADD OP_5 OP_EQUAL` matches no template, so `Solver()` returns `NONSTANDARD` and the spend is rejected at relay.", + "fontSize": 24, + "width": 924, + "height": 720, + "title": "Non-Standard RedeemScript", + "dirty": false + }, + "width": 924, + "height": 720 + }, + { + "id": "cc24_rh160", + "type": "calculation", + "position": { + "x": 11027.03281540571, + "y": 1299.9706752228285 + }, + "data": { + "functionName": "hash160_hex", + "title": "Data → HASH160", + "paramExtraction": "single_val", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "52935587" + }, + "result": "8e9a55016b5f68f07aa9f1d8bef929b1f0b48547", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "RedeemScript (hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#8b5cf6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc28_p2sh_spk", + "type": "calculation", + "position": { + "x": 11889.983797110921, + "y": 1654.6753424149044 + }, + "data": { + "functionName": "concat_all", + "title": "P2SH scriptPubKey", + "paramExtraction": "multi_val", + "numInputs": 4, + "inputs": { + "vals": { + "0": "a9", + "100": "14", + "200": "8e9a55016b5f68f07aa9f1d8bef929b1f0b48547", + "300": "87" + } + }, + "dirty": false, + "version": 0, + "result": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "inputStructure": { + "groups": [ + { + "title": "INPUTS[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 1, + "maxInstances": 25, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "INPUTS[]": 4 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100, + 200, + 300 + ] + }, + "baseHeight": 80, + "borderColor": "#ef4444", + "showComment": true, + "comment": "a9 14 <20-byte-hash> 87 - 23 bytes total", + "error": false, + "totalInputs": 4, + "unwiredCount": 0 + } + }, + { + "id": "cc29_p2sh_addr", + "type": "calculation", + "position": { + "x": 11619.95535810437, + "y": 1024.237157436514 + }, + "data": { + "functionName": "hash160_to_p2sh_address", + "title": "HASH160 → P2SH Address", + "numInputs": 1, + "showField": false, + "networkDependent": true, + "selectedNetwork": "testnet", + "dirty": false, + "groupInstances": {}, + "result": "2N6FEphioV2nrTaHtSkExF665HUSZnqkqDh", + "inputs": { + "val": "8e9a55016b5f68f07aa9f1d8bef929b1f0b48547", + "selectedNetwork": "testnet" + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "HASH160:", + "placeholder": "20-byte hash", + "rows": 2 + } + ] + }, + "borderColor": "#10b981", + "showComment": true, + "comment": "TX1's output pays to this address", + "error": false + } + }, + { + "id": "cc30_ns_text", + "type": "shadcnTextInfo", + "position": { + "x": 9605.966782412415, + "y": 1574.028496970513 + }, + "data": { + "content": "## Standardness Check\n\nWhen a default-policy node relays a transaction that spends a P2SH UTXO:\n\n1. Parse the scriptSig — the last push is the redeemScript.\n2. Call `Solver(redeemScript)` — returns a `TxoutType`.\n3. If `TxoutType::NONSTANDARD`, `AreInputsStandard()` returns `false`.\n4. `IsStandardTx()` returns `false`. The transaction is dropped.\n\nFor the redeemScript `52935587`:\n\n```\nSolver(52935587) → NONSTANDARD\n```\n\n**RedeemScript types `Solver()` accepts:**\n- `P2PK` — single pubkey + `OP_CHECKSIG`\n- `P2PKH` — pubkey-hash template\n- `P2MS` — bare multisig, `m`-of-`n` with `n ≤ 3`\n- `P2WPKH` / `P2WSH` — segwit v0 (as P2SH-wrapped)\n\nArithmetic redeemScripts using `OP_ADD`, `OP_EQUAL`, etc. are absent from this list.\n\n*Source: `bitcoin/src/script/solver.cpp`, function `Solver`.*", + "fontSize": 22, + "width": 840, + "height": 680, + "title": "Standardness Check", + "dirty": false + }, + "width": 840, + "height": 680 + }, + { + "id": "cc31_tx1_title", + "type": "shadcnTextInfo", + "position": { + "x": 12847.75962448163, + "y": 410.9471918280868 + }, + "data": { + "content": "# Step 4 — Construct and Sign TX1 (P2PKH → P2SH)\n\nTX1 spends the P2PKH UTXO produced by the funding transaction and outputs to the non-standard P2SH address from Step 3.\n\n## Transaction Structure\n\n| Field | Value |\n|-------|-------|\n| Version | `02000000` (LE-4) |\n| Input count | `01` |\n| Prev TXID | reversed from `cc14_ex_txid` |\n| Prev vout | `00000000` (index 0) |\n| scriptSig | ` ` |\n| Sequence | `fdffffff` |\n| Output count | `01` |\n| Output amount | input − fee, encoded as 8-byte LE |\n| Output scriptPubKey | P2SH scriptPubKey from Step 3 |\n| Locktime | `00000000` |\n\n## Signing Pipeline\n\nThe signing chain below the template implements P2PKH signing end-to-end:\n\n1. Build the preimage: the raw TX bytes with the spent output's P2PKH scriptPubKey occupying the scriptSig slot.\n2. Append the `SIGHASH_ALL` flag `01000000`.\n3. Apply `double_sha256` — the resulting 32-byte digest is the sighash.\n4. Sign the sighash with the private key using Bitcoin Core Low-R ECDSA.\n5. Append the SIGHASH byte `01` to produce ``.\n6. Push-encode `` and push-encode the compressed pubkey to form the real scriptSig.\n7. Prepend its VarInt length and re-emit all twelve transaction fields to obtain the broadcast-ready TX1.\n\nTX1's TXID, computed in Step 5 as `reverse(double_sha256(signed_tx))`, feeds the TX2 prevout directly.", + "fontSize": 22, + "width": 1088, + "height": 800, + "title": "Spending TX1 Structure", + "dirty": false + }, + "width": 1088, + "height": 800 + }, + { + "id": "cc32_version", + "type": "calculation", + "position": { + "x": 14858.163188075356, + "y": 1622.088313684138 + }, + "data": { + "functionName": "uint32_to_little_endian_4_bytes", + "title": "Uint32 → LE-4", + "showField": false, + "numInputs": 1, + "dirty": false, + "version": 0, + "inputs": { + "val": "2" + }, + "result": "02000000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "4-byte LE hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "cc33_in_count", + "type": "calculation", + "position": { + "x": 14875.051578831384, + "y": 1934.2076553709312 + }, + "data": { + "functionName": "encode_varint", + "title": "Int → VarInt", + "showField": false, + "numInputs": 1, + "dirty": false, + "version": 0, + "inputs": { + "val": "1" + }, + "result": "01", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "VarInt hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "cc34_txid_rev", + "type": "calculation", + "position": { + "x": 14835.835915177398, + "y": 1222.2289793618254 + }, + "data": { + "functionName": "reverse_txid_bytes", + "title": "TXID → Reversed", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "a032b956ef42c2f972ace1e93431b4de2a792cec00e5695385fd2c3bc2549427" + }, + "result": "279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "TXID (display order):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc35_vout_le", + "type": "calculation", + "position": { + "x": 14876.888811244871, + "y": 2237.8061938719184 + }, + "data": { + "functionName": "uint32_to_little_endian_4_bytes", + "title": "Uint32 → LE-4", + "showField": false, + "numInputs": 1, + "dirty": false, + "version": 0, + "inputs": { + "val": "0" + }, + "result": "00000000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "4-byte LE hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc38_sequence", + "type": "calculation", + "position": { + "x": 14902.353608042295, + "y": 2649.7456250771993 + }, + "data": { + "functionName": "reverse_bytes_4", + "title": "4-Byte → Reversed", + "showField": false, + "numInputs": 1, + "dirty": false, + "version": 0, + "inputs": { + "val": "fffffffd" + }, + "result": "fdffffff", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "4-byte LE hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "cc39_out_count", + "type": "calculation", + "position": { + "x": 14877.212034674054, + "y": 3101.3412886198275 + }, + "data": { + "functionName": "encode_varint", + "title": "Int → VarInt", + "showField": false, + "numInputs": 1, + "dirty": false, + "version": 0, + "inputs": { + "val": "1" + }, + "result": "01", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "VarInt hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "cc41_amount_le", + "type": "calculation", + "position": { + "x": 15577.504270417201, + "y": 2909.326983791914 + }, + "data": { + "functionName": "satoshi_to_8_le", + "title": "Satoshi → LE-8", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "45000" + }, + "result": "c8af000000000000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Satoshis:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "cc42_spk_varint", + "type": "calculation", + "position": { + "x": 12426.860196403017, + "y": 1769.9224439133238 + }, + "data": { + "functionName": "varint_encoded_byte_length", + "title": "Data → VarInt Length", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787" + }, + "result": "17", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hex data:", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc43_locktime", + "type": "calculation", + "position": { + "x": 15629.987324339889, + "y": 3318.639754200744 + }, + "data": { + "functionName": "identity", + "title": "Locktime", + "showField": true, + "numInputs": 0, + "value": "00000000", + "dirty": false, + "version": 0, + "inputs": { + "val": "00000000" + }, + "result": "00000000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "4-byte LE hex:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false, + "comment": "immediate", + "showComment": true + } + }, + { + "id": "cc44_tx1_raw", + "type": "calculation", + "position": { + "x": 16344.193739336988, + "y": 1636.3974384642934 + }, + "data": { + "functionName": "concat_all", + "title": "Unsigned TX (placeholder scriptSig)", + "paramExtraction": "multi_val", + "numInputs": 12, + "inputs": { + "vals": { + "0": "02000000", + "10": "01", + "1000": "279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0", + "1010": "00000000", + "1020": "19", + "1030": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac", + "1040": "fdffffff", + "2000": "01", + "3000": "c8af000000000000", + "3010": "17", + "3020": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "4000": "00000000" + } + }, + "dirty": false, + "version": 0, + "result": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88acfdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "inputStructure": { + "afterGroups": [ + { + "index": 4000, + "label": "LOCKTIME[4]:", + "placeholder": "00000000", + "rows": 1 + } + ], + "betweenGroups": { + "INPUTS[]": [ + { + "index": 2000, + "label": "OUTPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groups": [ + { + "baseIndex": 1000, + "expandable": true, + "fieldCountToAdd": 5, + "fields": [ + { + "index": 0, + "label": "TXID[32]:", + "placeholder": "Prev TX ID", + "rows": 2 + }, + { + "index": 10, + "label": "VOUT[4]:", + "placeholder": "00000000", + "rows": 1 + }, + { + "allowEmpty00": true, + "index": 20, + "label": "SCRIPT_LENGTH (VarInt):", + "rows": 1 + }, + { + "allowEmptyBlank": true, + "index": 30, + "label": "SCRIPT_SIG[]:", + "placeholder": " ", + "rows": 3 + }, + { + "index": 40, + "label": "SEQUENCE[4]:", + "placeholder": "ffffffff", + "rows": 1 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "INPUTS[]" + }, + { + "baseIndex": 3000, + "expandable": true, + "fieldCountToAdd": 3, + "fields": [ + { + "index": 0, + "label": "AMOUNT[8]:", + "placeholder": "Satoshis (hex)", + "rows": 1 + }, + { + "index": 10, + "label": "SCRIPT_PUBKEY_LENGTH:", + "rows": 1, + "small": true + }, + { + "index": 20, + "label": "SCRIPT_PUBKEY[]:", + "placeholder": "Locking script", + "rows": 3 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "OUTPUTS[]" + } + ], + "ungrouped": [ + { + "index": 0, + "label": "VERSION[4]:", + "rows": 1 + }, + { + "index": 10, + "label": "INPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groupInstances": { + "INPUTS[]": 1, + "OUTPUTS[]": 1 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 1000 + ], + "OUTPUTS[]": [ + 3000 + ] + }, + "baseHeight": 120, + "borderColor": "#a855f7", + "showComment": false, + "comment": "", + "error": false, + "totalInputs": 12, + "unwiredCount": 0 + } + }, + { + "id": "cc45_unlock_title", + "type": "shadcnTextInfo", + "position": { + "x": 22997.083732820127, + "y": 13455.797166370994 + }, + "data": { + "content": "# Step 5 — Spend the P2SH Output\n\nTo spend a P2SH UTXO, the scriptSig must:\n\n1. Push the arguments required by the redeemScript (here, the integer `3`).\n2. Push the redeemScript itself, revealing its bytes.\n\n## scriptSig Construction\n\n`OP_3` + `OP_PUSHBYTES_4` + redeemScript:\n\n- `53` — `OP_3` pushes the integer `3` (the puzzle solution `3 + 2 = 5`).\n- `04` — push next 4 bytes (length of the redeemScript).\n- `52935587` — redeemScript bytes.\n\n## Script Execution Trace (BIP16)\n\n| Step | Opcode / Rule | Stack After |\n|------|---------------|-------------|\n| scriptSig (1) | `OP_3` | `[3]` |\n| scriptSig (2) | `PUSHBYTES_4 → 52935587` | `[3, 52935587]` |\n| scriptPubKey | `OP_HASH160 → 8e9a55…b48547` | `[3, 52935587, 8e9a55…b48547]` |\n| scriptPubKey | `OP_EQUAL` (against the spk's hash push) | `[3, 52935587]` |\n| BIP16 | pop top as redeemScript; verify hash match | `[3]` |\n| redeemScript | `OP_2` | `[3, 2]` |\n| redeemScript | `OP_ADD` | `[5]` |\n| redeemScript | `OP_5` | `[5, 5]` |\n| redeemScript | `OP_EQUAL` | `[1]` |\n\nFinal stack: `[1]`. Non-zero top element ⇒ `VerifyScript()` returns `TRUE`. Consensus-valid.\n\nNote: when P2SH is enabled, Bitcoin Core's interpreter short-circuits — it hashes the last push from the scriptSig, compares against the hash in the scriptPubKey, then re-executes that push as the redeemScript. The intermediate rows above describe the equivalent logical state.", + "fontSize": 22, + "width": 1224, + "height": 820, + "title": "P2SH Spending", + "dirty": false + }, + "width": 1224, + "height": 820 + }, + { + "id": "cc47_push_op", + "type": "calculation", + "position": { + "x": 24120.48089675863, + "y": 15345.324089101037 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "52935587" + }, + "result": "04", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hex Data:", + "rows": 2, + "placeholder": "redeemScript hex" + } + ] + }, + "groupInstances": {}, + "borderColor": "#10b981", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "cc48_p2sh_ss", + "type": "calculation", + "position": { + "x": 24933.10998153314, + "y": 14926.318969350232 + }, + "data": { + "functionName": "concat_all", + "title": "scriptSig (push solution & redeemScript)", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "53", + "100": "04", + "200": "52935587" + } + }, + "dirty": false, + "version": 0, + "result": "530452935587", + "inputStructure": { + "groups": [ + { + "title": "INPUTS[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 1, + "maxInstances": 25, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "INPUTS[]": 3 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100, + 200 + ] + }, + "baseHeight": 80, + "borderColor": "#10b981", + "showComment": true, + "comment": "OP_3 + PUSHBYTES_4 + redeemScript", + "error": false, + "totalInputs": 3, + "unwiredCount": 0 + } + }, + { + "id": "cc50_verify", + "type": "calculation", + "position": { + "x": 27491.99187125742, + "y": 14706.23481803719 + }, + "data": { + "functionName": "script_verification", + "title": "Verify Script", + "paramExtraction": "multi_val", + "numInputs": 6, + "inputs": { + "vals": { + "0": "530452935587", + "1": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "2": "0200000001f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a260000000006530452935587fdffffff01409c0000000000001976a914b9157068de50a54c8bae069fd5460b8a1bc5db4f88ac00000000", + "3": "0", + "4": "", + "5": "45000" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "scriptSig_hex", + "rows": 3, + "placeholder": "Hex-encoded scriptSig", + "allowEmptyBlank": true + }, + { + "index": 1, + "label": "scriptPubKey_hex", + "rows": 3, + "placeholder": "Hex-encoded scriptPubKey" + }, + { + "index": 2, + "label": "tx_hex", + "rows": 3, + "placeholder": "Hex-encoded Transaction" + }, + { + "index": 3, + "label": "input_index_to_verify", + "rows": 1, + "placeholder": "0", + "unconnectable": true + }, + { + "index": 4, + "label": "exclude_flags", + "rows": 1, + "placeholder": "e.g., WITNESS,CLEANSTACK", + "unconnectable": true + }, + { + "index": 5, + "label": "spent_amount_sats", + "rows": 1, + "placeholder": "Amount in satoshis", + "allowEmptyBlank": true + } + ], + "groups": [], + "afterGroups": [] + }, + "groupInstances": {}, + "borderColor": "#10b981", + "showComment": true, + "comment": "VerifyScript() → TRUE (consensus valid)", + "error": false, + "totalInputs": 4, + "unwiredCount": 0, + "dirty": false, + "result": "True (isValid: true)", + "version": 0 + } + }, + { + "id": "cc51_relay_main", + "type": "shadcnTextInfo", + "position": { + "x": 31194.590163137273, + "y": 12793.252256145612 + }, + "data": { + "content": "# Step 9 — Relay Policy vs Consensus\n\nTest TX2 against a **default-policy** node (`-acceptnonstandardtxs=0`, mainnet-style):\n\n1. Run `testmempoolaccept '[\"\"]'` on a default-policy node.\n2. Paste the exact output into the **Observed Broadcast Response** node.\n3. The `Compare (==)` gate checks it against the expected `bad-txns-nonstandard-inputs` template.\n\n**Two layers, one transaction:**\n- `VerifyScript()` returns `TRUE` — consensus-valid.\n- `AreInputsStandard()` returns `FALSE` — default-policy relay rejects before propagation.\n\nOn testnet3 (default `-acceptnonstandardtxs=1`), the same transaction is accepted. The rejection demo requires a node running mainnet-style policy.\n\n**The Observed node is intentionally empty.** The `Check Result` gate stays `false` until real RPC output is pasted here. This is the one manual checkpoint that cannot be faked on-canvas.", + "fontSize": 22, + "width": 840, + "height": 900, + "title": "Relay Policy Explanation", + "dirty": false + }, + "width": 840, + "height": 900 + }, + { + "id": "cc52_comparison", + "type": "shadcnTextInfo", + "position": { + "x": 32432.39758642624, + "y": 12777.26734022593 + }, + "data": { + "content": "## Validity vs Relay: Side-by-Side\n\n| Check | Result | Enforced By |\n|-------|--------|-------------|\n| `VerifyScript()` | TRUE | All full nodes (consensus) |\n| `IsStandardTx()` | FALSE | Default-policy relay nodes |\n| `AreInputsStandard()` | FALSE | Default-policy relay nodes |\n| Includable in a block | YES | Miners may include |\n| Will propagate via P2P | NO | Default policy drops it |\n| Network reach | None | Never reaches miners through gossip |\n\n## Rejection Code Path (Bitcoin Core)\n\n```\n// policy/policy.cpp — AreInputsStandard\nfor (unsigned int i = 0; i < tx.vin.size(); i++) {\n const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;\n std::vector> vSolutions;\n TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);\n if (whichType == TxoutType::SCRIPTHASH) {\n // Extract the redeemScript (last push of the scriptSig)\n CScript subscript(vSolutions[0].begin(), vSolutions[0].end());\n TxoutType whichType2 = Solver(subscript, ...);\n if (whichType2 == TxoutType::NONSTANDARD)\n return false; // failure point for this transaction\n }\n}\n```\n\n`Solver(52935587)` returns `TxoutType::NONSTANDARD` because the bytes match no entry in `solver.cpp`.\n\nRPC error returned by `sendrawtransaction` / `testmempoolaccept`:\n\n```\nerror code: -26\nerror message: bad-txns-nonstandard-inputs\n```\n\n## Paths to Broadcasting Non-Standard Scripts\n\n- **Testnet3** — default `-acceptnonstandardtxs=1` accepts it at relay.\n- **Mainnet (default policy)** — submit out-of-band to a mining-pool API.\n- **Standard alternatives** — Taproot script-path spends are standard regardless of inner-script content.\n- **Protocol path** — propose a BIP that adds the desired template to `Solver()`.", + "fontSize": 20, + "width": 1350, + "height": 900, + "title": "Comparison & Code Path", + "dirty": false + }, + "width": 1350, + "height": 900 + }, + { + "id": "cc53_key_insight", + "type": "shadcnTextInfo", + "position": { + "x": 31059.721979097758, + "y": 14005.285335247143 + }, + "data": { + "content": "## Bitcoin's Two-Layer Validation Architecture\n\n```\nBroadcast TX\n ↓\n[Relay Policy — IsStandardTx()]\n Non-standard? → DROPPED ← stops here on default-policy nodes\n RPC error: bad-txns-nonstandard-inputs\n Standard? → forwarded to peers\n ↓\n[Mempool — fee, dust, ancestor/descendant limits, …]\n ↓\n[Miner includes in block]\n ↓\n[Consensus Rules — VerifyScript()]\n Fails? → INVALID BLOCK (every node rejects)\n Passes? → CONFIRMED\n```\n\nThe lesson's TX2 is dropped at the first layer — relay policy. Reaching a miner directly, it would confirm at the last layer — consensus.\n\n**This distinction matters in practice for:**\n\n- The Lightning Network (used non-standard scripts before standardisation).\n- Covenant proposals (`OP_CTV`, `OP_CAT`, `CHECKTEMPLATEVERIFY`-class designs).\n- Hash-puzzle and OP_RETURN research traffic.\n- Custom scripts that depend on direct miner relationships rather than P2P relay.", + "fontSize": 22, + "width": 980, + "height": 700, + "title": "Two-Layer Architecture", + "dirty": false + }, + "width": 980, + "height": 700 + }, + { + "id": "cc54_summary", + "type": "shadcnTextInfo", + "position": { + "x": 29951.156033272495, + "y": 10318.811784461088 + }, + "data": { + "content": "## Summary\n\n**Eleven on-canvas stages, structurally aligned with Lessons 1, 2, and 6:**\n\n1. P2PKH address derivation from a private key.\n2. Funding TX ingested as raw hex; fields parsed via `extract_tx_field`.\n3. Non-standard P2SH redeemScript `52 93 55 87` (`OP_2 OP_ADD OP_5 OP_EQUAL`); HASH160 and address derived on-canvas.\n4. TX1 signed on-canvas: preimage → `double_sha256` → ECDSA Low-R → push-encoded scriptSig → final TX.\n5. TX1's TXID derived from the signed bytes — no manual paste.\n6. TX1's output fields re-extracted and cross-checked against the constructed values.\n7. TX2 spends the P2SH UTXO to a freshly-derived P2PKH recipient.\n8. Amounts driven by Math Operation nodes: `output = input − fee`. Non-negativity and conservation gates wired downstream.\n9. `VerifyScript()` returns `TRUE` — consensus-valid.\n10. Default-policy relay returns `bad-txns-nonstandard-inputs`. Testnet3 (with `-acceptnonstandardtxs=1`) would accept.\n11. `Check Result` aggregates every gate.\n\n**Mechanically-enforced evidence inputs (the gate cannot pass without these):**\n\n- *Observed Broadcast Response* must match the expected non-standard rejection.\n- TX1 must contain exactly one output (justifies the hardcoded `vout=0` prevout in TX2).\n\n**Math puzzle execution under BIP16:**\n```\nscriptSig: OP_3 → [3, redeemScript]\nBIP16: pop redeemScript; verify hash → [3]\nredeemScript: OP_2 OP_ADD OP_5 OP_EQUAL → [1] (TRUE)\n```\n\nUntil every input slot of `Check Result` reads `true`, the lesson is incomplete.", + "fontSize": 22, + "width": 1050, + "height": 700, + "title": "Summary", + "dirty": false + }, + "width": 1050, + "height": 700 + }, + { + "id": "cc_compare_spk", + "type": "calculation", + "position": { + "x": 8371.086965263654, + "y": 1263.0802222509826 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac", + "100": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac" + } + }, + "dirty": false, + "version": 0, + "result": "true", + "inputStructure": { + "groups": [ + { + "title": "VALUES[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 2, + "maxInstances": 12, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 2 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "VALUES[]": 2 + }, + "groupInstanceKeys": { + "VALUES[]": [ + 0, + 100 + ] + }, + "borderColor": "#10b981", + "showComment": false, + "comment": "Funding TX spk == our P2PKH spk", + "error": false, + "totalInputs": 2, + "unwiredCount": 0 + } + }, + { + "id": "n_op_dup_h160", + "type": "opCodeNode", + "position": { + "x": 2262.6380950811545, + "y": 1155.6726124126953 + }, + "data": { + "functionName": "op_code_select", + "value": "76a9", + "inputs": { + "val": "76a9" + }, + "dirty": false, + "version": 0, + "result": "76a9", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_DUP", + "OP_HASH160" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_op_eqv_cs", + "type": "opCodeNode", + "position": { + "x": 2246.733685374141, + "y": 1471.577022119709 + }, + "data": { + "functionName": "op_code_select", + "value": "88ac", + "inputs": { + "val": "88ac" + }, + "dirty": false, + "version": 0, + "result": "88ac", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_EQUALVERIFY", + "OP_CHECKSIG" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_op_redeem", + "type": "opCodeNode", + "position": { + "x": 10513.624103868717, + "y": 1096.6073641839948 + }, + "data": { + "functionName": "op_code_select", + "value": "52935587", + "inputs": { + "val": "52935587" + }, + "dirty": false, + "version": 0, + "result": "52935587", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_2", + "OP_ADD", + "OP_5", + "OP_EQUAL" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_op_h160_psh", + "type": "opCodeNode", + "position": { + "x": 10878.483655390624, + "y": 1746.643227691945 + }, + "data": { + "functionName": "op_code_select", + "value": "a9", + "inputs": { + "val": "a9" + }, + "dirty": false, + "version": 0, + "result": "a9", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_HASH160" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_op_eq_psh", + "type": "opCodeNode", + "position": { + "x": 10881.46816877194, + "y": 2126.5482129377497 + }, + "data": { + "functionName": "op_code_select", + "value": "87", + "inputs": { + "val": "87" + }, + "dirty": false, + "version": 0, + "result": "87", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_EQUAL" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_op_3", + "type": "opCodeNode", + "position": { + "x": 24062.902266683057, + "y": 14865.198442088924 + }, + "data": { + "functionName": "op_code_select", + "value": "53", + "inputs": { + "val": "53" + }, + "dirty": false, + "version": 0, + "result": "53", + "groupInstances": {}, + "paramExtraction": "single_val", + "title": "Opcode Sequence", + "opSequenceNames": [ + "OP_3" + ], + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_pkh_spk_varint", + "type": "calculation", + "position": { + "x": 14899.576046647218, + "y": 4093.1242568785574 + }, + "data": { + "functionName": "varint_encoded_byte_length", + "title": "Data → VarInt Length", + "numInputs": 1, + "dirty": false, + "result": "19", + "inputs": { + "val": "76a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac" + }, + "groupInstances": {}, + "error": false, + "borderColor": "#eab308", + "showField": false, + "version": 0 + } + }, + { + "id": "n_sighash_all", + "type": "calculation", + "position": { + "x": 16783.979009075, + "y": 4626.032032973068 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "01000000", + "dirty": false, + "inputs": { + "val": "01000000" + }, + "result": "01000000", + "groupInstances": {}, + "title": "SIGHASH_ALL flag", + "error": false + } + }, + { + "id": "n_preimage", + "type": "calculation", + "position": { + "x": 17653.02316929103, + "y": 4195.734146787113 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88acfdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "100": "01000000" + } + }, + "dirty": false, + "version": 0, + "result": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88acfdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b48547870000000001000000", + "inputStructure": { + "afterGroups": [], + "groups": [ + { + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ], + "maxInstances": 25, + "minInstances": 1, + "title": "INPUTS[]" + } + ], + "ungrouped": [] + }, + "groupInstances": { + "INPUTS[]": 2 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100 + ] + }, + "baseHeight": 80, + "title": "Pre-image + SIGHASH", + "borderColor": "#eab308", + "totalInputs": 2, + "unwiredCount": 0, + "error": false + } + }, + { + "id": "n_tx1_hash", + "type": "calculation", + "position": { + "x": 18289.04878931237, + "y": 4336.234335862442 + }, + "data": { + "functionName": "double_sha256_hex", + "title": "Data → SHA-256d", + "numInputs": 1, + "dirty": false, + "result": "0506fff4285acd31bb751f3ff65f7b675146805013c55041c39ea8cd9ab3e50a", + "inputs": { + "val": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88acfdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b48547870000000001000000" + }, + "groupInstances": {}, + "error": false, + "borderColor": "#eab308", + "showField": false, + "version": 0, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Input Hex:", + "rows": 2 + } + ] + } + } + }, + { + "id": "n_sign_tx1", + "type": "calculation", + "position": { + "x": 18872.54602714092, + "y": 4211.732433307522 + }, + "data": { + "functionName": "sign_as_bitcoin_core_low_r", + "title": "Sign TX (Low-R)", + "paramExtraction": "multi_val", + "numInputs": 2, + "dirty": false, + "inputs": { + "vals": { + "0": "a1322cd573b5df00ec636d98276777b7d87f8b46df40cb4f97ae11e40502f76d", + "1": "0506fff4285acd31bb751f3ff65f7b675146805013c55041c39ea8cd9ab3e50a" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Private Key (32 bytes hex):", + "rows": 2 + }, + { + "index": 1, + "label": "Message Hash (32 bytes hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "result": "3045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf", + "totalInputs": 2, + "unwiredCount": 0, + "borderColor": "#eab308", + "error": false + } + }, + { + "id": "n_sighash_byte", + "type": "calculation", + "position": { + "x": 18831.115570025173, + "y": 4768.7434480890915 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "01", + "dirty": false, + "inputs": { + "val": "01" + }, + "result": "01", + "groupInstances": {}, + "title": "SIGHASH_ALL byte", + "error": false + } + }, + { + "id": "n_sig_flag", + "type": "calculation", + "position": { + "x": 19653.26865867433, + "y": 4186.703425399899 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "3045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf", + "100": "01" + } + }, + "dirty": false, + "version": 0, + "result": "3045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf01", + "inputStructure": { + "afterGroups": [], + "groups": [ + { + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ], + "maxInstances": 25, + "minInstances": 1, + "title": "INPUTS[]" + } + ], + "ungrouped": [] + }, + "groupInstances": { + "INPUTS[]": 2 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100 + ] + }, + "baseHeight": 80, + "title": "Signature + Flag", + "borderColor": "#eab308", + "totalInputs": 2, + "unwiredCount": 0, + "error": false + } + }, + { + "id": "n_sig_push", + "type": "calculation", + "position": { + "x": 20690.984426915158, + "y": 4283.874419642505 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "dirty": false, + "result": "483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf01", + "inputs": { + "val": "3045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf01" + }, + "groupInstances": {}, + "error": false, + "borderColor": "#eab308", + "showField": false, + "version": 0 + } + }, + { + "id": "n_pubkey_push", + "type": "calculation", + "position": { + "x": 20690.984426915158, + "y": 4733.037343885856 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "dirty": false, + "result": "2102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51", + "inputs": { + "val": "02ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51" + }, + "groupInstances": {}, + "error": false, + "borderColor": "#eab308", + "showField": false, + "version": 0 + } + }, + { + "id": "n_real_ss", + "type": "calculation", + "position": { + "x": 21639.736646259218, + "y": 4479.704706817326 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf01", + "100": "2102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51" + } + }, + "dirty": false, + "version": 0, + "result": "483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51", + "inputStructure": { + "afterGroups": [], + "groups": [ + { + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ], + "maxInstances": 25, + "minInstances": 1, + "title": "INPUTS[]" + } + ], + "ungrouped": [] + }, + "groupInstances": { + "INPUTS[]": 2 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100 + ] + }, + "baseHeight": 80, + "title": "scriptSig (push sig & pubkey)", + "borderColor": "#eab308", + "totalInputs": 2, + "unwiredCount": 0, + "error": false + } + }, + { + "id": "n_ss_varint", + "type": "calculation", + "position": { + "x": 22756.8099663385, + "y": 4762.1202863412755 + }, + "data": { + "functionName": "varint_encoded_byte_length", + "title": "Data → VarInt Length", + "numInputs": 1, + "dirty": false, + "result": "6b", + "inputs": { + "val": "483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51" + }, + "groupInstances": {}, + "error": false, + "borderColor": "#eab308", + "showField": false, + "version": 0 + } + }, + { + "id": "n_tx1_signed", + "type": "calculation", + "position": { + "x": 23771.350416464567, + "y": 4455.891729329413 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 12, + "inputs": { + "vals": { + "0": "02000000", + "10": "01", + "1000": "279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0", + "1010": "00000000", + "1020": "6b", + "1030": "483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51", + "1040": "fdffffff", + "2000": "01", + "3000": "c8af000000000000", + "3010": "17", + "3020": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "4000": "00000000" + } + }, + "dirty": false, + "version": 0, + "result": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "inputStructure": { + "afterGroups": [ + { + "index": 4000, + "label": "LOCKTIME[4]:", + "placeholder": "00000000", + "rows": 1 + } + ], + "betweenGroups": { + "INPUTS[]": [ + { + "index": 2000, + "label": "OUTPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groups": [ + { + "baseIndex": 1000, + "expandable": true, + "fieldCountToAdd": 5, + "fields": [ + { + "index": 0, + "label": "TXID[32]:", + "placeholder": "Prev TX ID", + "rows": 2 + }, + { + "index": 10, + "label": "VOUT[4]:", + "placeholder": "00000000", + "rows": 1 + }, + { + "allowEmpty00": true, + "index": 20, + "label": "SCRIPT_LENGTH (VarInt):", + "rows": 1 + }, + { + "allowEmptyBlank": true, + "index": 30, + "label": "SCRIPT_SIG[]:", + "placeholder": " ", + "rows": 3 + }, + { + "index": 40, + "label": "SEQUENCE[4]:", + "placeholder": "ffffffff", + "rows": 1 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "INPUTS[]" + }, + { + "baseIndex": 3000, + "expandable": true, + "fieldCountToAdd": 3, + "fields": [ + { + "index": 0, + "label": "AMOUNT[8]:", + "placeholder": "Satoshis (hex)", + "rows": 1 + }, + { + "index": 10, + "label": "SCRIPT_PUBKEY_LENGTH:", + "rows": 1, + "small": true + }, + { + "index": 20, + "label": "SCRIPT_PUBKEY[]:", + "placeholder": "Locking script", + "rows": 3 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "OUTPUTS[]" + } + ], + "ungrouped": [ + { + "index": 0, + "label": "VERSION[4]:", + "rows": 1 + }, + { + "index": 10, + "label": "INPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groupInstances": { + "INPUTS[]": 1, + "OUTPUTS[]": 1 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 1000 + ], + "OUTPUTS[]": [ + 3000 + ] + }, + "baseHeight": 120, + "title": "TX1 (final, signed)", + "borderColor": "#a855f7", + "totalInputs": 12, + "unwiredCount": 0, + "error": false, + "comment": "bitcoin-cli -testnet sendrawtransaction (paste returned TXID into evidence)", + "showComment": true + } + }, + { + "id": "n_tx2_version", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 11025.98000289473 + }, + "data": { + "functionName": "uint32_to_little_endian_4_bytes", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "2" + }, + "result": "02000000", + "groupInstances": {}, + "title": "Uint32 → LE-4", + "error": false, + "version": 0, + "borderColor": "#14b8a6" + } + }, + { + "id": "n_tx2_in_count", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 11325.98000289473 + }, + "data": { + "functionName": "encode_varint", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "01", + "groupInstances": {}, + "title": "Int → VarInt", + "error": false, + "version": 0, + "borderColor": "#14b8a6" + } + }, + { + "id": "n_tx2_vout", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 11625.980002894732 + }, + "data": { + "functionName": "uint32_to_little_endian_4_bytes", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "0" + }, + "result": "00000000", + "groupInstances": {}, + "title": "Uint32 → LE-4", + "error": false, + "version": 0, + "borderColor": "#14b8a6" + } + }, + { + "id": "n_p2sh_ss_varint", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 11925.980002894732 + }, + "data": { + "functionName": "varint_encoded_byte_length", + "title": "Data → VarInt Length", + "numInputs": 1, + "dirty": false, + "result": "06", + "inputs": { + "val": "530452935587" + }, + "groupInstances": {}, + "error": false, + "showField": false, + "version": 0 + } + }, + { + "id": "n_tx2_sequence", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 12225.980002894732 + }, + "data": { + "functionName": "reverse_bytes_4", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "fffffffd" + }, + "result": "fdffffff", + "groupInstances": {}, + "title": "4-Byte → Reversed", + "error": false, + "version": 0, + "borderColor": "#14b8a6" + } + }, + { + "id": "n_tx2_out_count", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 12525.98000289473 + }, + "data": { + "functionName": "encode_varint", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "01", + "groupInstances": {}, + "title": "Int → VarInt", + "error": false, + "version": 0, + "borderColor": "#14b8a6" + } + }, + { + "id": "n_tx2_amt_le", + "type": "calculation", + "position": { + "x": 26155.733823981733, + "y": 8916.610461988523 + }, + "data": { + "functionName": "satoshi_to_8_le", + "title": "Satoshi → LE-8", + "numInputs": 1, + "dirty": false, + "result": "409c000000000000", + "inputs": { + "val": "40000" + }, + "groupInstances": {}, + "error": false, + "showField": false, + "version": 0 + } + }, + { + "id": "n_tx2_spk_varint", + "type": "calculation", + "position": { + "x": 25350.19249345151, + "y": 10081.213663962655 + }, + "data": { + "functionName": "varint_encoded_byte_length", + "title": "Data → VarInt Length", + "numInputs": 1, + "dirty": false, + "result": "19", + "inputs": { + "val": "76a914b9157068de50a54c8bae069fd5460b8a1bc5db4f88ac" + }, + "groupInstances": {}, + "error": false, + "showField": false, + "version": 0 + } + }, + { + "id": "n_tx2_locktime", + "type": "calculation", + "position": { + "x": 25131.59871651519, + "y": 12825.98000289473 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "00000000", + "dirty": false, + "inputs": { + "val": "00000000" + }, + "result": "00000000", + "groupInstances": {}, + "title": "Locktime", + "error": false, + "comment": "immediate", + "showComment": true + } + }, + { + "id": "n_tx2_template", + "type": "calculation", + "position": { + "x": 26528.465424445763, + "y": 10729.882989807526 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 12, + "inputs": { + "vals": { + "0": "02000000", + "10": "01", + "1000": "f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a26", + "1010": "00000000", + "1020": "06", + "1030": "530452935587", + "1040": "fdffffff", + "2000": "01", + "3000": "409c000000000000", + "3010": "19", + "3020": "76a914b9157068de50a54c8bae069fd5460b8a1bc5db4f88ac", + "4000": "00000000" + } + }, + "dirty": false, + "version": 0, + "result": "0200000001f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a260000000006530452935587fdffffff01409c0000000000001976a914b9157068de50a54c8bae069fd5460b8a1bc5db4f88ac00000000", + "inputStructure": { + "afterGroups": [ + { + "index": 4000, + "label": "LOCKTIME[4]:", + "placeholder": "00000000", + "rows": 1 + } + ], + "betweenGroups": { + "INPUTS[]": [ + { + "index": 2000, + "label": "OUTPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groups": [ + { + "baseIndex": 1000, + "expandable": true, + "fieldCountToAdd": 5, + "fields": [ + { + "index": 0, + "label": "TXID[32]:", + "placeholder": "Prev TX ID", + "rows": 2 + }, + { + "index": 10, + "label": "VOUT[4]:", + "placeholder": "00000000", + "rows": 1 + }, + { + "allowEmpty00": true, + "index": 20, + "label": "SCRIPT_LENGTH (VarInt):", + "rows": 1 + }, + { + "allowEmptyBlank": true, + "index": 30, + "label": "SCRIPT_SIG[]:", + "placeholder": " ", + "rows": 3 + }, + { + "index": 40, + "label": "SEQUENCE[4]:", + "placeholder": "ffffffff", + "rows": 1 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "INPUTS[]" + }, + { + "baseIndex": 3000, + "expandable": true, + "fieldCountToAdd": 3, + "fields": [ + { + "index": 0, + "label": "AMOUNT[8]:", + "placeholder": "Satoshis (hex)", + "rows": 1 + }, + { + "index": 10, + "label": "SCRIPT_PUBKEY_LENGTH:", + "rows": 1, + "small": true + }, + { + "index": 20, + "label": "SCRIPT_PUBKEY[]:", + "placeholder": "Locking script", + "rows": 3 + } + ], + "maxInstances": 10, + "minInstances": 1, + "title": "OUTPUTS[]" + } + ], + "ungrouped": [ + { + "index": 0, + "label": "VERSION[4]:", + "rows": 1 + }, + { + "index": 10, + "label": "INPUT_COUNT (VarInt):", + "rows": 1, + "small": true + } + ] + }, + "groupInstances": { + "INPUTS[]": 1, + "OUTPUTS[]": 1 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 1000 + ], + "OUTPUTS[]": [ + 3000 + ] + }, + "baseHeight": 120, + "title": "TX2 (final)", + "borderColor": "#a855f7", + "totalInputs": 12, + "unwiredCount": 0, + "error": false, + "comment": "spends TX1's P2SH output → P2PKH", + "showComment": true + } + }, + { + "id": "n_ver_int_tx1", + "type": "calculation", + "position": { + "x": 14041.521895260505, + "y": 1026.0452675398865 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "2", + "dirty": false, + "inputs": { + "val": "2" + }, + "result": "2", + "groupInstances": {}, + "title": "Transaction Version", + "error": false + } + }, + { + "id": "n_inc_int_tx1", + "type": "calculation", + "position": { + "x": 14031.075914466943, + "y": 1494.3367284720791 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Input Count", + "error": false + } + }, + { + "id": "n_vout_int_tx1", + "type": "calculation", + "position": { + "x": 14057.440446442517, + "y": 1950.8631572437444 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "0", + "dirty": false, + "inputs": { + "val": "0" + }, + "result": "0", + "groupInstances": {}, + "title": "Output Index (vout)", + "error": false + } + }, + { + "id": "n_seq_be_tx1", + "type": "calculation", + "position": { + "x": 14061.60204745436, + "y": 2422.249373046616 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "fffffffd", + "dirty": false, + "inputs": { + "val": "fffffffd" + }, + "result": "fffffffd", + "groupInstances": {}, + "title": "Sequence", + "error": false + } + }, + { + "id": "n_outc_int_tx1", + "type": "calculation", + "position": { + "x": 14089.951001540507, + "y": 2917.3360835708463 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Output Count", + "error": false + } + }, + { + "id": "n_ver_int_tx2", + "type": "calculation", + "position": { + "x": 24431.59871651519, + "y": 11025.98000289473 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "2", + "dirty": false, + "inputs": { + "val": "2" + }, + "result": "2", + "groupInstances": {}, + "title": "Transaction Version", + "error": false + } + }, + { + "id": "n_inc_int_tx2", + "type": "calculation", + "position": { + "x": 24431.59871651519, + "y": 11325.98000289473 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Input Count", + "error": false + } + }, + { + "id": "n_vout_int_tx2", + "type": "calculation", + "position": { + "x": 24431.59871651519, + "y": 11625.980002894732 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "0", + "dirty": false, + "inputs": { + "val": "0" + }, + "result": "0", + "groupInstances": {}, + "title": "Output Index (vout)", + "error": false + } + }, + { + "id": "n_seq_be_tx2", + "type": "calculation", + "position": { + "x": 24431.59871651519, + "y": 12225.980002894732 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "fffffffd", + "dirty": false, + "inputs": { + "val": "fffffffd" + }, + "result": "fffffffd", + "groupInstances": {}, + "title": "Sequence", + "error": false + } + }, + { + "id": "n_outc_int_tx2", + "type": "calculation", + "position": { + "x": 24431.59871651519, + "y": 12525.98000289473 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Output Count", + "error": false + } + }, + { + "id": "n_relay_result", + "type": "calculation", + "position": { + "x": 31318.104276916645, + "y": 10922.569716866075 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "REJECTED: bad-txns-nonstandard-inputs (on default-policy node)", + "dirty": false, + "inputs": { + "val": "REJECTED: bad-txns-nonstandard-inputs (on default-policy node)" + }, + "result": "REJECTED: bad-txns-nonstandard-inputs (on default-policy node)", + "groupInstances": {}, + "title": "Expected Broadcast Response (default policy)", + "showComment": true, + "comment": "Expected rejection on a default-policy node (AreInputsStandard = false)", + "borderColor": "#ef4444", + "error": false + } + }, + { + "id": "n_tx1_d256", + "type": "calculation", + "position": { + "x": 24613.021943938744, + "y": 5330.15849222098 + }, + "data": { + "functionName": "double_sha256_hex", + "title": "Data → SHA-256d", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000" + }, + "result": "f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a26", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "TX bytes (hex):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#eab308", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "n_tx1_txid_disp", + "type": "calculation", + "position": { + "x": 25200.412642419655, + "y": 5266.534785644453 + }, + "data": { + "functionName": "reverse_txid_bytes", + "title": "TXID → Reversed", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a26" + }, + "result": "263ab2124ae783b6a3a415c144c9e5549359eaa52d98f523566df824e0e54ef6", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hash (wire order):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#10b981", + "showComment": true, + "comment": "TXID as displayed by bitcoin core", + "error": false + } + }, + { + "id": "cc55_evidence_checklist", + "type": "shadcnTextInfo", + "position": { + "x": 32539.414886571416, + "y": 14076.679985100109 + }, + "data": { + "content": "## Required Evidence\n\nOne on-canvas gate requires a manual paste:\n\n- **Observed Broadcast Response** — the actual RPC output from a default-policy node when broadcasting TX2. Paste into the **Observed Broadcast Response** identity node. The `Compare (==)` beside it measures it against the expected `bad-txns-nonstandard-inputs` template.\n\nThe `Check Result` node stays `false` until that one paste is made.\n\n**TXID verification** — both the funding TXID and the TX1 broadcast TXID are now derived on-canvas from the raw transaction bytes via `double_sha256` and `reverse_txid_bytes`. The corresponding compare nodes verify that derivation is self-consistent.\n\n**Off-canvas artifacts to submit with the lesson:**\n- Funding transaction on testnet3 explorer (≥ 1 confirmation)\n- TX1 on testnet3 explorer (≥ 1 confirmation)\n- Walkthrough video with voice narration", + "fontSize": 22, + "width": 980, + "height": 520, + "title": "Evidence Checklist", + "dirty": false + }, + "width": 980, + "height": 520 + }, + { + "id": "n_funding_output_count", + "type": "calculation", + "position": { + "x": 6665.097258092037, + "y": 2473.8564145793757 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract: output_count", + "paramExtraction": "multi_val", + "numInputs": 2, + "dirty": false, + "result": "1", + "inputs": { + "vals": { + "0": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000", + "1": "output_count" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "Should be 1 for this funding tx", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "n_funding_output_count_ok", + "type": "calculation", + "position": { + "x": 7908.128427515558, + "y": 805.3889336244339 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "1", + "100": "1" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "rows": 1 + }, + { + "index": 100, + "label": "Right value:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Funding output_count must be 1 before using vout index 0", + "error": false + } + }, + { + "id": "n_tx1_extract_title", + "type": "shadcnTextInfo", + "position": { + "x": 22732.10682420613, + "y": 5850.299839063084 + }, + "data": { + "content": "## TX1 Field Re-Extraction\n\nTX2 must consume values *extracted from TX1*, not hardcoded copies of the construction values. The same discipline applies in Lesson 6.\n\n- `txid` — wire-order prevout for TX2's input.\n- `vout.value` — amount source for TX2 fee math and the conservation check.\n- `vout.scriptPubKey` — cross-checked against the P2SH scriptPubKey constructed in Step 3.", + "fontSize": 22, + "width": 940, + "height": 430, + "title": "TX1 Field Extract", + "dirty": false + }, + "width": 940, + "height": 430 + }, + { + "id": "n_tx1_ex_txid", + "type": "calculation", + "position": { + "x": 24707.021430384437, + "y": 6268.853648052665 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract TX1: txid", + "paramExtraction": "multi_val", + "numInputs": 2, + "dirty": false, + "result": "263ab2124ae783b6a3a415c144c9e5549359eaa52d98f523566df824e0e54ef6", + "inputs": { + "vals": { + "0": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "1": "txid" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": true, + "comment": "display order", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "n_tx1_ex_txid_rev", + "type": "calculation", + "position": { + "x": 26050.749158330073, + "y": 6365.086378454766 + }, + "data": { + "functionName": "reverse_txid_bytes", + "title": "TXID → Reversed", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "263ab2124ae783b6a3a415c144c9e5549359eaa52d98f523566df824e0e54ef6" + }, + "result": "f64ee5e024f86d5623f5982da5ea599354e5c944c115a4a3b683e74a12b23a26", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "TXID (display order):", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": true, + "comment": "wire order (TX2 prevout)", + "error": false + } + }, + { + "id": "n_tx1_ex_amount", + "type": "calculation", + "position": { + "x": 24720.88245979908, + "y": 6886.0097755487395 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract TX1: vout.value (sats)", + "paramExtraction": "multi_val", + "numInputs": 3, + "dirty": false, + "result": "45000", + "inputs": { + "vals": { + "0": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "1": "vout.value", + "2": "0" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Index (opt):", + "placeholder": "0", + "rows": 1, + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "TX2 input amount must come from TX1 output", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "n_tx1_ex_spk", + "type": "calculation", + "position": { + "x": 24725.360638341277, + "y": 7483.476132983896 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract TX1: vout.scriptPubKey", + "paramExtraction": "multi_val", + "numInputs": 3, + "dirty": false, + "result": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "inputs": { + "vals": { + "0": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "1": "vout.scriptPubKey", + "2": "0" + } + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "placeholder": "", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Index (opt):", + "placeholder": "0", + "rows": 1, + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "Should match the intended P2SH lock from TX1", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "n_tx1_ex_spk_match", + "type": "calculation", + "position": { + "x": 26038.143683743743, + "y": 6904.6918691753235 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787", + "100": "a9148e9a55016b5f68f07aa9f1d8bef929b1f0b4854787" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "rows": 1 + }, + { + "index": 100, + "label": "Right value:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "TX1 output script matches constructed P2SH scriptPubKey", + "error": false + } + }, + { + "id": "n_tx2_dest_entropy", + "type": "calculation", + "position": { + "x": 22924.88806541366, + "y": 9792.652925958671 + }, + "data": { + "functionName": "random_256", + "title": "Random 256-Bit Entropy (TX2 recipient)", + "hasRegenerate": true, + "dirty": false, + "numInputs": 0, + "groupInstances": {}, + "result": "3af10456f6823fc2cb1ab8b545108e21b604cd3bc3dd8ee1962cab1a9485b87d", + "borderColor": "#14b8a6", + "showComment": true, + "comment": "fresh key for TX2 recipient (no address reuse)", + "error": false + } + }, + { + "id": "n_tx2_dest_pub", + "type": "calculation", + "position": { + "x": 23371.253969473415, + "y": 9899.98823961106 + }, + "data": { + "functionName": "public_key_from_private_key", + "title": "PrivKey → PubKey (TX2 recipient)", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "3af10456f6823fc2cb1ab8b545108e21b604cd3bc3dd8ee1962cab1a9485b87d" + }, + "result": "026b7a3e6463610952b846e5d6b1f1dfba7f3907321ef8da9a513ede22a26e8bea", + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_tx2_dest_h160", + "type": "calculation", + "position": { + "x": 23815.412567260268, + "y": 9918.494328171819 + }, + "data": { + "functionName": "hash160_hex", + "title": "Data → HASH160 (TX2 recipient)", + "paramExtraction": "single_val", + "showField": false, + "numInputs": 1, + "dirty": false, + "inputs": { + "val": "026b7a3e6463610952b846e5d6b1f1dfba7f3907321ef8da9a513ede22a26e8bea" + }, + "result": "b9157068de50a54c8bae069fd5460b8a1bc5db4f", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "INPUT HEX:", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "error": false + } + }, + { + "id": "n_tx2_dest_addr", + "type": "calculation", + "position": { + "x": 24201.006554929263, + "y": 9681.834685686315 + }, + "data": { + "functionName": "hash160_to_p2pkh_address", + "title": "HASH160 → P2PKH Address (new recipient)", + "numInputs": 1, + "showField": false, + "networkDependent": true, + "selectedNetwork": "testnet", + "dirty": false, + "groupInstances": {}, + "result": "mxPazA5teSyEGB2YgmLmdz2WXeoY4MCU9W", + "inputs": { + "val": "b9157068de50a54c8bae069fd5460b8a1bc5db4f", + "selectedNetwork": "testnet" + }, + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "HASH160:", + "placeholder": "20-byte hash", + "rows": 2 + } + ] + }, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "TX2 must pay to a new P2PKH destination", + "error": false + } + }, + { + "id": "n_tx2_dest_spk", + "type": "calculation", + "position": { + "x": 24732.33975786074, + "y": 9947.979140221463 + }, + "data": { + "functionName": "concat_all", + "paramExtraction": "multi_val", + "numInputs": 4, + "inputs": { + "vals": { + "0": "76a9", + "100": "14", + "200": "b9157068de50a54c8bae069fd5460b8a1bc5db4f", + "300": "88ac" + } + }, + "dirty": false, + "version": 0, + "result": "76a914b9157068de50a54c8bae069fd5460b8a1bc5db4f88ac", + "inputStructure": { + "groups": [ + { + "title": "INPUTS[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 1, + "maxInstances": 25, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "", + "rows": 3 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "INPUTS[]": 4 + }, + "groupInstanceKeys": { + "INPUTS[]": [ + 0, + 100, + 200, + 300 + ] + }, + "baseHeight": 80, + "title": "scriptPubKey P2PKH (new recipient)", + "borderColor": "#10b981", + "showComment": true, + "comment": "OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG", + "error": false, + "totalInputs": 4, + "unwiredCount": 0 + } + }, + { + "id": "n_tx2_fee_sats", + "type": "calculation", + "position": { + "x": 24797.851160377737, + "y": 9179.667245468714 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "5000", + "dirty": false, + "inputs": { + "val": "5000" + }, + "result": "5000", + "groupInstances": {}, + "title": "TX2 Fee (sats)", + "showComment": false, + "comment": "Set per current feerate policy", + "error": false + } + }, + { + "id": "n_tx2_amt_calc", + "type": "calculation", + "position": { + "x": 25554.28086781284, + "y": 9089.650322954494 + }, + "data": { + "functionName": "math_operation", + "title": "Math Operation", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "45000", + "1": "-", + "2": "5000" + } + }, + "result": "40000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "placeholder": "e.g. 5", + "rows": 1 + }, + { + "index": 1, + "label": "Operator:", + "options": [ + "+", + "-", + "*", + "/" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Right value:", + "placeholder": "e.g. 10", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "TX2 amount = TX1 output amount - fee", + "error": false + } + }, + { + "id": "n_tx2_amt_nonnegative", + "type": "calculation", + "position": { + "x": 28194.49542339959, + "y": 8096.533575640051 + }, + "data": { + "functionName": "compare_numbers", + "title": "Compare Numbers", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "40000", + "1": ">=", + "2": "0" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "placeholder": "e.g. 5", + "rows": 1 + }, + { + "index": 1, + "label": "Operator:", + "options": [ + "<", + ">", + "<=", + ">=" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Right value:", + "placeholder": "e.g. 10", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Sanity check: TX2 output amount must be non-negative", + "error": false + } + }, + { + "id": "n_relay_match", + "type": "calculation", + "position": { + "x": 32068.104276916645, + "y": 11209.490080596182 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "REJECTED: bad-txns-nonstandard-inputs (on default-policy node)", + "100": "REJECTED: bad-txns-nonstandard-inputs (on default-policy node)" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "rows": 1 + }, + { + "index": 100, + "label": "Right value:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Observed response must match expected non-standard rejection", + "error": false + } + }, + { + "id": "n_verify_true_match", + "type": "calculation", + "position": { + "x": 28618.930894598547, + "y": 13808.390843764315 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "True (isValid: true)", + "100": "True (isValid: true)" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "rows": 1 + }, + { + "index": 100, + "label": "Right value:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Verify Script must be TRUE before policy discussion", + "error": false + } + }, + { + "id": "n_l15_check_result", + "type": "calculation", + "position": { + "x": 33313.46718675749, + "y": 10841.609535001024 + }, + "data": { + "functionName": "check_result", + "title": "Check Result", + "paramExtraction": "multi_val", + "numInputs": 1, + "inputs": { + "vals": { + "0": "true", + "100": "true", + "200": "true", + "300": "true", + "400": "true", + "500": "true", + "600": "true", + "700": "true", + "800": "true", + "900": "true", + "1000": "true", + "1100": "true" + } + }, + "result": "true", + "inputStructure": { + "afterGroups": [], + "groups": [ + { + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "fields": [ + { + "index": 0, + "label": "Value:", + "placeholder": "true/false", + "rows": 1 + } + ], + "maxInstances": 12, + "minInstances": 1, + "title": "VALUES[]" + } + ], + "ungrouped": [] + }, + "groupInstances": { + "VALUES[]": 12 + }, + "groupInstanceKeys": { + "VALUES[]": [ + 0, + 100, + 200, + 300, + 400, + 500, + 600, + 700, + 800, + 900, + 1000, + 1100 + ] + }, + "totalInputs": 12, + "unwiredCount": 0, + "dirty": false, + "showComment": true, + "comment": "all gates must be true", + "error": false + } + }, + { + "id": "n_tx1_fee_sats", + "type": "calculation", + "position": { + "x": 24872.742202913443, + "y": 8618.102679992773 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "5000", + "dirty": false, + "inputs": { + "val": "5000" + }, + "result": "5000", + "groupInstances": {}, + "title": "TX1 Fee (sats)", + "showComment": false, + "comment": "Set per feerate policy", + "error": false + } + }, + { + "id": "n_tx1_amt_calc", + "type": "calculation", + "position": { + "x": 25637.45908759116, + "y": 8468.389259924037 + }, + "data": { + "functionName": "math_operation", + "title": "Math Operation", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "50000", + "1": "-", + "2": "5000" + } + }, + "result": "45000", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "placeholder": "e.g. 5", + "rows": 1 + }, + { + "index": 1, + "label": "Operator:", + "options": [ + "+", + "-", + "*", + "/" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Right value:", + "placeholder": "e.g. 10", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "TX1 output amount = funding amount - TX1 fee", + "error": false + } + }, + { + "id": "n_tx1_amt_nonnegative", + "type": "calculation", + "position": { + "x": 16856.96779910029, + "y": 3360.2511201364587 + }, + "data": { + "functionName": "compare_numbers", + "title": "Compare Numbers", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "45000", + "1": ">=", + "2": "0" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "placeholder": "e.g. 5", + "rows": 1 + }, + { + "index": 1, + "label": "Operator:", + "options": [ + "<", + ">", + "<=", + ">=" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Right value:", + "placeholder": "e.g. 10", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Sanity check: TX1 output amount must be non-negative", + "error": false + } + }, + { + "id": "n_tx1_amount_match", + "type": "calculation", + "position": { + "x": 28364.49542339959, + "y": 7296.533575640052 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "45000", + "100": "45000" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "rows": 1 + }, + { + "index": 100, + "label": "Right value:", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": false, + "comment": "Extracted TX1 amount matches computed TX1 output amount", + "error": false + } + }, + { + "id": "n_tx2_amount_input_check", + "type": "calculation", + "position": { + "x": 28984.49542339959, + "y": 8096.533575640051 + }, + "data": { + "functionName": "compare_numbers", + "title": "Compare Numbers", + "paramExtraction": "multi_val", + "numInputs": 3, + "inputs": { + "vals": { + "0": "45000", + "1": ">=", + "2": "40000" + } + }, + "result": "true", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Left value:", + "placeholder": "e.g. 5", + "rows": 1 + }, + { + "index": 1, + "label": "Operator:", + "options": [ + "<", + ">", + "<=", + ">=" + ], + "unconnectable": true + }, + { + "index": 2, + "label": "Right value:", + "placeholder": "e.g. 10", + "rows": 1 + } + ] + }, + "groupInstances": {}, + "totalInputs": 2, + "unwiredCount": 0, + "dirty": false, + "showComment": true, + "comment": "conservation: TX2 output ≤ TX1 output", + "error": false + } + }, + { + "id": "n_funding_d256", + "type": "calculation", + "position": { + "x": 7220.586940881865, + "y": 1702.352431980371 + }, + "data": { + "functionName": "double_sha256_hex", + "title": "Data → SHA-256d", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "020000000105766158051b6a6d3214843be351592f2f41e6de735df7c6ebba2708f5f50e9e010000006a4730440220296a848cd7a9054262d0157793257557c819142864bb64d223d13d098b7e370e022065731fdb3b78ed32c9d2b32de8c70f445097468eea13d3422fa599c27daaeba9012102a3cd270aa377301e1a9b8053483febb1a23c4f9ef730ba7296d6ec3fef99f62dfdffffff0150c30000000000001976a91420d0afaa02179ee086043dbb3a0af65496d4665a88ac00000000" + }, + "result": "279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0", + "groupInstances": {}, + "borderColor": "#eab308", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "n_funding_txid_disp", + "type": "calculation", + "position": { + "x": 7638.304629425223, + "y": 1917.6099323556534 + }, + "data": { + "functionName": "reverse_txid_bytes", + "title": "TXID → Reversed", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0" + }, + "result": "a032b956ef42c2f972ace1e93431b4de2a792cec00e5695385fd2c3bc2549427", + "groupInstances": {}, + "borderColor": "#10b981", + "showComment": true, + "comment": "Funding TXID (display order, derived on-canvas)", + "error": false + } + }, + { + "id": "n_evidence_funding_match", + "type": "calculation", + "position": { + "x": 8362.694843951616, + "y": 1952.0773364371507 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "a032b956ef42c2f972ace1e93431b4de2a792cec00e5695385fd2c3bc2549427", + "100": "a032b956ef42c2f972ace1e93431b4de2a792cec00e5695385fd2c3bc2549427" + } + }, + "dirty": false, + "version": 0, + "result": "true", + "inputStructure": { + "groups": [ + { + "title": "VALUES[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 2, + "maxInstances": 12, + "fields": [ + { + "index": 0, + "label": "Value:", + "rows": 2 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "VALUES[]": 2 + }, + "groupInstanceKeys": { + "VALUES[]": [ + 0, + 100 + ] + }, + "borderColor": "#10b981", + "showComment": true, + "comment": "Funding TXID (canvas-derived) matches itself — both sides sourced from n_funding_txid_disp", + "error": false, + "totalInputs": 2, + "unwiredCount": 0 + } + }, + { + "id": "n_evidence_tx1_match", + "type": "calculation", + "position": { + "x": 25910.700184845948, + "y": 5206.49464965702 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "263ab2124ae783b6a3a415c144c9e5549359eaa52d98f523566df824e0e54ef6", + "100": "263ab2124ae783b6a3a415c144c9e5549359eaa52d98f523566df824e0e54ef6" + } + }, + "dirty": false, + "version": 0, + "result": "true", + "inputStructure": { + "groups": [ + { + "title": "VALUES[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 2, + "maxInstances": 12, + "fields": [ + { + "index": 0, + "label": "Value:", + "rows": 2 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "VALUES[]": 2 + }, + "groupInstanceKeys": { + "VALUES[]": [ + 0, + 100 + ] + }, + "borderColor": "#10b981", + "showComment": true, + "comment": "TX1 TXID (canvas-derived) matches itself — both sides sourced from n_tx1_txid_disp", + "error": false, + "totalInputs": 2, + "unwiredCount": 0 + } + }, + { + "id": "n_tx1_out_count_ext", + "type": "calculation", + "position": { + "x": 24725.510236566148, + "y": 8082.818900507989 + }, + "data": { + "functionName": "extract_tx_field", + "title": "Extract TX1: output_count", + "paramExtraction": "multi_val", + "numInputs": 2, + "dirty": false, + "version": 0, + "inputs": { + "vals": { + "0": "0200000001279454c23b2cfd855369e500ec2c792adeb43134e9e1ac72f9c242ef56b932a0000000006b483045022100a95b4d321e85dd59ca39bdaa0c1d1bd2276073c44e4fe9e58a859c18804a1bba0220097c0be547d9a387e0f825abf27bf0bdd63882a2aff7d787e7cbd6f0ebf7bedf012102ae8fcde1eedf1af28848948da2016dfcb82fba7883a7c02b8713c1dec532ef51fdffffff01c8af00000000000017a9148e9a55016b5f68f07aa9f1d8bef929b1f0b485478700000000", + "1": "output_count" + } + }, + "result": "1", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Raw TX (hex):", + "rows": 4 + }, + { + "index": 1, + "label": "Field name:", + "options": [ + "version", + "locktime", + "txid", + "input_count", + "output_count", + "vin.txid", + "vin.vout", + "vin.scriptSig", + "vin.sequence", + "vout.value", + "vout.scriptPubKey", + "raw_no_witness" + ], + "unconnectable": true + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false, + "totalInputs": 1, + "unwiredCount": 0 + } + }, + { + "id": "n_tx1_out_count_ok", + "type": "calculation", + "position": { + "x": 26043.353751109815, + "y": 7393.209351239889 + }, + "data": { + "functionName": "compare_equal", + "title": "Compare (==)", + "paramExtraction": "multi_val", + "numInputs": 2, + "inputs": { + "vals": { + "0": "1", + "100": "1" + } + }, + "dirty": false, + "version": 0, + "result": "true", + "inputStructure": { + "groups": [ + { + "title": "VALUES[]", + "baseIndex": 0, + "expandable": true, + "fieldCountToAdd": 1, + "minInstances": 2, + "maxInstances": 12, + "fields": [ + { + "index": 0, + "label": "Value:", + "rows": 2 + } + ] + } + ], + "ungrouped": [], + "afterGroups": [] + }, + "groupInstances": { + "VALUES[]": 2 + }, + "groupInstanceKeys": { + "VALUES[]": [ + 0, + 100 + ] + }, + "borderColor": "#10b981", + "showComment": true, + "comment": "TX1 must have exactly 1 output (justifies vout=0 prevout)", + "error": false, + "totalInputs": 2, + "unwiredCount": 0 + } + }, + { + "id": "n_verify_true_expected", + "type": "calculation", + "position": { + "x": 25831.200552584385, + "y": 14957.498294797599 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "True (isValid: true)", + "dirty": false, + "version": 0, + "inputs": { + "val": "True (isValid: true)" + }, + "result": "True (isValid: true)", + "groupInstances": {}, + "title": "Expected verify-script output (rawBit format)", + "showComment": true, + "comment": "Update if rawBit's script_verification result format changes", + "borderColor": "#f59e0b", + "error": false + } + }, + { + "id": "n_pkh_h160_push", + "type": "calculation", + "position": { + "x": 3050.882299659538, + "y": 1311.4564814831929 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "20d0afaa02179ee086043dbb3a0af65496d4665a" + }, + "result": "14", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hex Data:", + "placeholder": "Enter hex data to calculate push opcode", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#10b981", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "n_psh_h160_push", + "type": "calculation", + "position": { + "x": 11389.941292384208, + "y": 1524.7877197728342 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "8e9a55016b5f68f07aa9f1d8bef929b1f0b48547" + }, + "result": "14", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hex Data:", + "placeholder": "Enter hex data to calculate push opcode", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#ef4444", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "n_tx2dest_h160_push", + "type": "calculation", + "position": { + "x": 24232.357622609874, + "y": 10227.646689794328 + }, + "data": { + "functionName": "encode_script_push_data", + "title": "Data → Push Opcode", + "numInputs": 1, + "showField": false, + "dirty": false, + "version": 0, + "inputs": { + "val": "b9157068de50a54c8bae069fd5460b8a1bc5db4f" + }, + "result": "14", + "inputStructure": { + "ungrouped": [ + { + "index": 0, + "label": "Hex Data:", + "placeholder": "Enter hex data to calculate push opcode", + "rows": 2 + } + ] + }, + "groupInstances": {}, + "borderColor": "#14b8a6", + "showComment": false, + "comment": "", + "error": false + } + }, + { + "id": "n_funding_output_count_expected", + "type": "calculation", + "position": { + "x": 7399.7098598703915, + "y": 908.8060417937464 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "version": 0, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Expected funding output_count", + "showComment": true, + "comment": "Constant 1 (funding TX must have exactly one output)", + "borderColor": "#f59e0b", + "error": false + } + }, + { + "id": "n_tx1_out_count_expected", + "type": "calculation", + "position": { + "x": 25425.17364217583, + "y": 7318.134218781291 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "1", + "dirty": false, + "version": 0, + "inputs": { + "val": "1" + }, + "result": "1", + "groupInstances": {}, + "title": "Expected TX1 output_count", + "showComment": true, + "comment": "Constant 1 (TX1 must have exactly one output)", + "borderColor": "#f59e0b", + "error": false + } + }, + { + "id": "n_relay_observed", + "type": "calculation", + "position": { + "x": 31326.736035258335, + "y": 11578.056349505034 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "", + "dirty": false, + "version": 0, + "inputs": { + "val": "" + }, + "result": "", + "groupInstances": {}, + "title": "Observed Broadcast Response (paste actual)", + "showComment": true, + "comment": "Paste the exact RPC output from testmempoolaccept or sendrawtransaction here", + "borderColor": "#f59e0b", + "error": false + } + }, + { + "id": "n_minimum_zero", + "type": "calculation", + "position": { + "x": 15548.483655390624, + "y": 3541.643227691945 + }, + "data": { + "functionName": "identity", + "showField": true, + "numInputs": 0, + "value": "0", + "dirty": false, + "version": 0, + "inputs": { + "val": "0" + }, + "result": "0", + "groupInstances": {}, + "title": "Minimum amount (zero)", + "showComment": true, + "comment": "Lower bound for non-negativity checks", + "borderColor": "#f59e0b", + "error": false + } + } + ], + "edges": [ + { + "id": "e_cc02_cc03", + "source": "cc02_privkey", + "target": "cc03_pubkey", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc03_cc04", + "source": "cc03_pubkey", + "target": "cc04_h160", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc04_cc05", + "source": "cc04_h160", + "target": "cc05_addr", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc13_cc14", + "source": "cc13_fund_tx", + "target": "cc14_ex_txid", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc13_cc16", + "source": "cc13_fund_tx", + "target": "cc16_ex_amount", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc13_cc17", + "source": "cc13_fund_tx", + "target": "cc17_ex_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc24_cc29", + "source": "cc24_rh160", + "target": "cc29_p2sh_addr", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc28_cc42", + "source": "cc28_p2sh_spk", + "target": "cc42_spk_varint", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc14_cc34", + "source": "cc14_ex_txid", + "target": "cc34_txid_rev", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc34_cc44", + "source": "cc34_txid_rev", + "target": "cc44_tx1_raw", + "targetHandle": "input-1000", + "selected": false + }, + { + "id": "e_cc41_cc44", + "source": "cc41_amount_le", + "target": "cc44_tx1_raw", + "targetHandle": "input-3000", + "selected": false + }, + { + "id": "e_cc42_cc44", + "source": "cc42_spk_varint", + "target": "cc44_tx1_raw", + "targetHandle": "input-3010", + "selected": false + }, + { + "id": "e_cc28_cc44", + "source": "cc28_p2sh_spk", + "target": "cc44_tx1_raw", + "targetHandle": "input-3020", + "selected": false + }, + { + "id": "e_cc47_cc48", + "source": "cc47_push_op", + "target": "cc48_p2sh_ss", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_cc48_cc50", + "source": "cc48_p2sh_ss", + "target": "cc50_verify", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc28_cc50", + "source": "cc28_p2sh_spk", + "target": "cc50_verify", + "targetHandle": "input-1", + "selected": false + }, + { + "id": "e_cc32_version_cc44_tx1_raw", + "source": "cc32_version", + "target": "cc44_tx1_raw", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc33_in_count_cc44_tx1_raw", + "source": "cc33_in_count", + "target": "cc44_tx1_raw", + "targetHandle": "input-10", + "selected": false + }, + { + "id": "e_cc35_vout_le_cc44_tx1_raw", + "source": "cc35_vout_le", + "target": "cc44_tx1_raw", + "targetHandle": "input-1010", + "selected": false + }, + { + "id": "e_cc38_sequence_cc44_tx1_raw", + "source": "cc38_sequence", + "target": "cc44_tx1_raw", + "targetHandle": "input-1040", + "selected": false + }, + { + "id": "e_cc39_out_count_cc44_tx1_raw", + "source": "cc39_out_count", + "target": "cc44_tx1_raw", + "targetHandle": "input-2000", + "selected": false + }, + { + "id": "e_cc43_locktime_cc44_tx1_raw", + "source": "cc43_locktime", + "target": "cc44_tx1_raw", + "targetHandle": "input-4000", + "selected": false + }, + { + "id": "e_cc11_compare", + "source": "cc11_p2pkh_spk", + "target": "cc_compare_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_cc17_compare", + "source": "cc17_ex_spk", + "target": "cc_compare_spk", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_op_dup_h160_spk", + "source": "n_op_dup_h160", + "target": "cc11_p2pkh_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_op_eqv_cs_spk", + "source": "n_op_eqv_cs", + "target": "cc11_p2pkh_spk", + "targetHandle": "input-300", + "selected": false + }, + { + "id": "e_opredeem_rh160", + "source": "n_op_redeem", + "target": "cc24_rh160", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_opredeem_pushop", + "source": "n_op_redeem", + "target": "cc47_push_op", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_opredeem_ss200", + "source": "n_op_redeem", + "target": "cc48_p2sh_ss", + "targetHandle": "input-200", + "selected": false + }, + { + "id": "e_oph160psh_spk", + "source": "n_op_h160_psh", + "target": "cc28_p2sh_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_opeqpsh_spk", + "source": "n_op_eq_psh", + "target": "cc28_p2sh_spk", + "targetHandle": "input-300", + "selected": false + }, + { + "id": "e_op3_ss", + "source": "n_op_3", + "target": "cc48_p2sh_ss", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_spk_pkhvarint", + "source": "cc11_p2pkh_spk", + "target": "n_pkh_spk_varint", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_pkhvarint_cc44", + "source": "n_pkh_spk_varint", + "target": "cc44_tx1_raw", + "targetHandle": "input-1020", + "selected": false + }, + { + "id": "e_spk_cc44_500", + "source": "cc11_p2pkh_spk", + "target": "cc44_tx1_raw", + "targetHandle": "input-1030", + "selected": false + }, + { + "id": "e_cc44_preimage", + "source": "cc44_tx1_raw", + "target": "n_preimage", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_sighash_preimage", + "source": "n_sighash_all", + "target": "n_preimage", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_preimage_hash", + "source": "n_preimage", + "target": "n_tx1_hash", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_privkey_sign", + "source": "cc02_privkey", + "target": "n_sign_tx1", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_hash_sign", + "source": "n_tx1_hash", + "target": "n_sign_tx1", + "targetHandle": "input-1", + "selected": false + }, + { + "id": "e_sign_sigflag", + "source": "n_sign_tx1", + "target": "n_sig_flag", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_sighbyte_sigflag", + "source": "n_sighash_byte", + "target": "n_sig_flag", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_sigflag_push", + "source": "n_sig_flag", + "target": "n_sig_push", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_pubkey_push", + "source": "cc03_pubkey", + "target": "n_pubkey_push", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_sigpush_realss", + "source": "n_sig_push", + "target": "n_real_ss", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_pkpush_realss", + "source": "n_pubkey_push", + "target": "n_real_ss", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_realss_varint", + "source": "n_real_ss", + "target": "n_ss_varint", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_ver_signed", + "source": "cc32_version", + "target": "n_tx1_signed", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_inc_signed", + "source": "cc33_in_count", + "target": "n_tx1_signed", + "targetHandle": "input-10", + "selected": false + }, + { + "id": "e_txid_signed", + "source": "cc34_txid_rev", + "target": "n_tx1_signed", + "targetHandle": "input-1000", + "selected": false + }, + { + "id": "e_vout_signed", + "source": "cc35_vout_le", + "target": "n_tx1_signed", + "targetHandle": "input-1010", + "selected": false + }, + { + "id": "e_ssvar_signed", + "source": "n_ss_varint", + "target": "n_tx1_signed", + "targetHandle": "input-1020", + "selected": false + }, + { + "id": "e_realss_signed", + "source": "n_real_ss", + "target": "n_tx1_signed", + "targetHandle": "input-1030", + "selected": false + }, + { + "id": "e_seq_signed", + "source": "cc38_sequence", + "target": "n_tx1_signed", + "targetHandle": "input-1040", + "selected": false + }, + { + "id": "e_outc_signed", + "source": "cc39_out_count", + "target": "n_tx1_signed", + "targetHandle": "input-2000", + "selected": false + }, + { + "id": "e_amtle_signed", + "source": "cc41_amount_le", + "target": "n_tx1_signed", + "targetHandle": "input-3000", + "selected": false + }, + { + "id": "e_spkv_signed", + "source": "cc42_spk_varint", + "target": "n_tx1_signed", + "targetHandle": "input-3010", + "selected": false + }, + { + "id": "e_pshspk_signed", + "source": "cc28_p2sh_spk", + "target": "n_tx1_signed", + "targetHandle": "input-3020", + "selected": false + }, + { + "id": "e_lt_signed", + "source": "cc43_locktime", + "target": "n_tx1_signed", + "targetHandle": "input-4000", + "selected": false + }, + { + "id": "e_tx2ver_tmpl", + "source": "n_tx2_version", + "target": "n_tx2_template", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2inc_tmpl", + "source": "n_tx2_in_count", + "target": "n_tx2_template", + "targetHandle": "input-10", + "selected": false + }, + { + "id": "e_tx2vout_tmpl", + "source": "n_tx2_vout", + "target": "n_tx2_template", + "targetHandle": "input-1010", + "selected": false + }, + { + "id": "e_p2shssvar_tmpl", + "source": "n_p2sh_ss_varint", + "target": "n_tx2_template", + "targetHandle": "input-1020", + "selected": false + }, + { + "id": "e_p2shss_tmpl", + "source": "cc48_p2sh_ss", + "target": "n_tx2_template", + "targetHandle": "input-1030", + "selected": false + }, + { + "id": "e_tx2seq_tmpl", + "source": "n_tx2_sequence", + "target": "n_tx2_template", + "targetHandle": "input-1040", + "selected": false + }, + { + "id": "e_tx2outc_tmpl", + "source": "n_tx2_out_count", + "target": "n_tx2_template", + "targetHandle": "input-2000", + "selected": false + }, + { + "id": "e_tx2amtle_tmpl", + "source": "n_tx2_amt_le", + "target": "n_tx2_template", + "targetHandle": "input-3000", + "selected": false + }, + { + "id": "e_tx2spkvar_tmpl", + "source": "n_tx2_spk_varint", + "target": "n_tx2_template", + "targetHandle": "input-3010", + "selected": false + }, + { + "id": "e_tx2lt_tmpl", + "source": "n_tx2_locktime", + "target": "n_tx2_template", + "targetHandle": "input-4000", + "selected": false + }, + { + "id": "e_p2shss_ssvarint", + "source": "cc48_p2sh_ss", + "target": "n_p2sh_ss_varint", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2tmpl_verify", + "source": "n_tx2_template", + "target": "cc50_verify", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_n_ver_int_tx1_cc32_version", + "source": "n_ver_int_tx1", + "target": "cc32_version", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_inc_int_tx1_cc33_in_count", + "source": "n_inc_int_tx1", + "target": "cc33_in_count", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_vout_int_tx1_cc35_vout_le", + "source": "n_vout_int_tx1", + "target": "cc35_vout_le", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_seq_be_tx1_cc38_sequence", + "source": "n_seq_be_tx1", + "target": "cc38_sequence", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_outc_int_tx1_cc39_out_count", + "source": "n_outc_int_tx1", + "target": "cc39_out_count", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_ver_int_tx2_n_tx2_version", + "source": "n_ver_int_tx2", + "target": "n_tx2_version", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_inc_int_tx2_n_tx2_in_count", + "source": "n_inc_int_tx2", + "target": "n_tx2_in_count", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_vout_int_tx2_n_tx2_vout", + "source": "n_vout_int_tx2", + "target": "n_tx2_vout", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_seq_be_tx2_n_tx2_sequence", + "source": "n_seq_be_tx2", + "target": "n_tx2_sequence", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_n_outc_int_tx2_n_tx2_out_count", + "source": "n_outc_int_tx2", + "target": "n_tx2_out_count", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_verify_relayresult", + "source": "cc50_verify", + "target": "n_relay_result", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1signed_d256", + "source": "n_tx1_signed", + "target": "n_tx1_d256", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_d256_txiddisp", + "source": "n_tx1_d256", + "target": "n_tx1_txid_disp", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_fundtx_outcount", + "source": "cc13_fund_tx", + "target": "n_funding_output_count", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_outcount_cmp", + "source": "n_funding_output_count", + "target": "n_funding_output_count_ok", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1signed_extract_txid", + "source": "n_tx1_signed", + "target": "n_tx1_ex_txid", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1signed_extract_amt", + "source": "n_tx1_signed", + "target": "n_tx1_ex_amount", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1signed_extract_spk", + "source": "n_tx1_signed", + "target": "n_tx1_ex_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1txid_rev", + "source": "n_tx1_ex_txid", + "target": "n_tx1_ex_txid_rev", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1spk_cmp_l", + "source": "n_tx1_ex_spk", + "target": "n_tx1_ex_spk_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1spk_cmp_r", + "source": "cc28_p2sh_spk", + "target": "n_tx1_ex_spk_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx2dest_priv_pub", + "source": "n_tx2_dest_entropy", + "target": "n_tx2_dest_pub", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2dest_pub_h160", + "source": "n_tx2_dest_pub", + "target": "n_tx2_dest_h160", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2dest_h160_addr", + "source": "n_tx2_dest_h160", + "target": "n_tx2_dest_addr", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2dest_opdup", + "source": "n_op_dup_h160", + "target": "n_tx2_dest_spk", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2dest_opeq", + "source": "n_op_eqv_cs", + "target": "n_tx2_dest_spk", + "targetHandle": "input-300", + "selected": false + }, + { + "id": "e_tx2dest_spk_varint", + "source": "n_tx2_dest_spk", + "target": "n_tx2_spk_varint", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1amt_tx2calc_l", + "source": "n_tx1_ex_amount", + "target": "n_tx2_amt_calc", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2fee_tx2calc_r", + "source": "n_tx2_fee_sats", + "target": "n_tx2_amt_calc", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_tx2calc_amtle", + "source": "n_tx2_amt_calc", + "target": "n_tx2_amt_le", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2calc_nonneg", + "source": "n_tx2_amt_calc", + "target": "n_tx2_amt_nonnegative", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_relayexp_match", + "source": "n_relay_result", + "target": "n_relay_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_verify_match_l", + "source": "cc50_verify", + "target": "n_verify_true_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_l15check_0", + "source": "cc_compare_spk", + "target": "n_l15_check_result", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_l15check_100", + "source": "n_funding_output_count_ok", + "target": "n_l15_check_result", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_l15check_200", + "source": "n_tx1_ex_spk_match", + "target": "n_l15_check_result", + "targetHandle": "input-200", + "selected": false + }, + { + "id": "e_l15check_300", + "source": "n_verify_true_match", + "target": "n_l15_check_result", + "targetHandle": "input-300", + "selected": false + }, + { + "id": "e_l15check_400", + "source": "n_relay_match", + "target": "n_l15_check_result", + "targetHandle": "input-400", + "selected": false + }, + { + "id": "e_l15check_500", + "source": "n_tx2_amt_nonnegative", + "target": "n_l15_check_result", + "targetHandle": "input-500", + "selected": false + }, + { + "id": "e_tx1extract_tx2tmpl_prevout", + "source": "n_tx1_ex_txid_rev", + "target": "n_tx2_template", + "targetHandle": "input-1000", + "selected": false + }, + { + "id": "e_tx2dest_tmpl_spk", + "source": "n_tx2_dest_spk", + "target": "n_tx2_template", + "targetHandle": "input-3020", + "selected": false + }, + { + "id": "e_tx1examt_tx1calc_l", + "source": "cc16_ex_amount", + "target": "n_tx1_amt_calc", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1fee_tx1calc_r", + "source": "n_tx1_fee_sats", + "target": "n_tx1_amt_calc", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_tx1calc_amtle", + "source": "n_tx1_amt_calc", + "target": "cc41_amount_le", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1calc_nonneg", + "source": "n_tx1_amt_calc", + "target": "n_tx1_amt_nonnegative", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1examt_match_l", + "source": "n_tx1_ex_amount", + "target": "n_tx1_amount_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1calc_match_r", + "source": "n_tx1_amt_calc", + "target": "n_tx1_amount_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx1examt_tx2amtcheck_l", + "source": "n_tx1_ex_amount", + "target": "n_tx2_amount_input_check", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2calc_tx2amtcheck_r", + "source": "n_tx2_amt_calc", + "target": "n_tx2_amount_input_check", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_l15check_600", + "source": "n_tx1_amt_nonnegative", + "target": "n_l15_check_result", + "targetHandle": "input-600", + "selected": false + }, + { + "id": "e_l15check_700", + "source": "n_tx1_amount_match", + "target": "n_l15_check_result", + "targetHandle": "input-700", + "selected": false + }, + { + "id": "e_l15check_800", + "source": "n_tx2_amount_input_check", + "target": "n_l15_check_result", + "targetHandle": "input-800", + "selected": false + }, + { + "id": "e_fund_to_d256", + "source": "cc13_fund_tx", + "target": "n_funding_d256", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_d256_to_funddisp", + "source": "n_funding_d256", + "target": "n_funding_txid_disp", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_funddisp_to_match", + "source": "n_funding_txid_disp", + "target": "n_evidence_funding_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx1disp_to_match", + "source": "n_tx1_txid_disp", + "target": "n_evidence_tx1_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx1signed_outcount", + "source": "n_tx1_signed", + "target": "n_tx1_out_count_ext", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1outcount_ok", + "source": "n_tx1_out_count_ext", + "target": "n_tx1_out_count_ok", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_verifyexp_match", + "source": "n_verify_true_expected", + "target": "n_verify_true_match", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_evfund_to_gate", + "source": "n_evidence_funding_match", + "target": "n_l15_check_result", + "targetHandle": "input-900", + "selected": false + }, + { + "id": "e_evtx1_to_gate", + "source": "n_evidence_tx1_match", + "target": "n_l15_check_result", + "targetHandle": "input-1000", + "selected": false + }, + { + "id": "e_tx1outc_to_gate", + "source": "n_tx1_out_count_ok", + "target": "n_l15_check_result", + "targetHandle": "input-1100", + "selected": false + }, + { + "id": "e_h160_p2pkh_spk_v2", + "source": "cc04_h160", + "target": "cc11_p2pkh_spk", + "targetHandle": "input-200", + "selected": false + }, + { + "id": "e_rh160_p2sh_spk_v2", + "source": "cc24_rh160", + "target": "cc28_p2sh_spk", + "targetHandle": "input-200", + "selected": false + }, + { + "id": "e_destH160_destSpk_v2", + "source": "n_tx2_dest_h160", + "target": "n_tx2_dest_spk", + "targetHandle": "input-200", + "selected": false + }, + { + "id": "e_cc04_pkh_h160_push", + "source": "cc04_h160", + "target": "n_pkh_h160_push", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_pkh_h160_push_spk", + "source": "n_pkh_h160_push", + "target": "cc11_p2pkh_spk", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_cc24_psh_h160_push", + "source": "cc24_rh160", + "target": "n_psh_h160_push", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_psh_h160_push_spk", + "source": "n_psh_h160_push", + "target": "cc28_p2sh_spk", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx2dest_h160_push", + "source": "n_tx2_dest_h160", + "target": "n_tx2dest_h160_push", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx2dest_push_spk", + "source": "n_tx2dest_h160_push", + "target": "n_tx2_dest_spk", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_fundoc_expected", + "source": "n_funding_output_count_expected", + "target": "n_funding_output_count_ok", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_tx1oc_expected", + "source": "n_tx1_out_count_expected", + "target": "n_tx1_out_count_ok", + "targetHandle": "input-100", + "selected": false + }, + { + "id": "e_fundingdisp_to_match0", + "source": "n_funding_txid_disp", + "target": "n_evidence_funding_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_tx1disp_to_match0", + "source": "n_tx1_txid_disp", + "target": "n_evidence_tx1_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_relayobserved_to_match", + "source": "n_relay_observed", + "target": "n_relay_match", + "targetHandle": "input-0", + "selected": false + }, + { + "id": "e_minzero_to_n_tx1_amt_nonnegative", + "source": "n_minimum_zero", + "target": "n_tx1_amt_nonnegative", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_minzero_to_n_tx2_amt_nonnegative", + "source": "n_minimum_zero", + "target": "n_tx2_amt_nonnegative", + "targetHandle": "input-2", + "selected": false + }, + { + "id": "e_tx1amt_to_verify_spent", + "source": "n_tx1_ex_amount", + "target": "cc50_verify", + "targetHandle": "input-5", + "selected": false + } + ] +} \ No newline at end of file