|
| 1 | +package kernel |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/hex" |
| 5 | + "errors" |
| 6 | + "testing" |
| 7 | +) |
| 8 | + |
| 9 | +func TestValidScripts(t *testing.T) { |
| 10 | + tests := []struct { |
| 11 | + name string |
| 12 | + scriptPubkeyHex string |
| 13 | + amount int64 |
| 14 | + txToHex string |
| 15 | + inputIndex uint |
| 16 | + description string |
| 17 | + }{ |
| 18 | + { |
| 19 | + name: "old_style_transaction", |
| 20 | + scriptPubkeyHex: "76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac", |
| 21 | + amount: 0, |
| 22 | + txToHex: "02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700", |
| 23 | + inputIndex: 0, |
| 24 | + description: "a random old-style transaction from the blockchain", |
| 25 | + }, |
| 26 | + { |
| 27 | + name: "segwit_p2sh_transaction", |
| 28 | + scriptPubkeyHex: "a91434c06f8c87e355e123bdc6dda4ffabc64b6989ef87", |
| 29 | + amount: 1900000, |
| 30 | + txToHex: "01000000000101d9fd94d0ff0026d307c994d0003180a5f248146efb6371d040c5973f5f66d9df0400000017160014b31b31a6cb654cfab3c50567bcf124f48a0beaecffffffff012cbd1c000000000017a914233b74bf0823fa58bbbd26dfc3bb4ae715547167870247304402206f60569cac136c114a58aedd80f6fa1c51b49093e7af883e605c212bdafcd8d202200e91a55f408a021ad2631bc29a67bd6915b2d7e9ef0265627eabd7f7234455f6012103e7e802f50344303c76d12c089c8724c1b230e3b745693bbe16aad536293d15e300000000", |
| 31 | + inputIndex: 0, |
| 32 | + description: "a random segwit transaction from the blockchain using P2SH", |
| 33 | + }, |
| 34 | + { |
| 35 | + name: "native_segwit_transaction", |
| 36 | + scriptPubkeyHex: "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d", |
| 37 | + amount: 18393430, |
| 38 | + txToHex: "010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000", |
| 39 | + inputIndex: 0, |
| 40 | + description: "a random segwit transaction from the blockchain using native segwit", |
| 41 | + }, |
| 42 | + } |
| 43 | + |
| 44 | + for _, tt := range tests { |
| 45 | + t.Run(tt.name, func(t *testing.T) { |
| 46 | + err := testVerifyScript(t, tt.scriptPubkeyHex, tt.amount, tt.txToHex, tt.inputIndex) |
| 47 | + if err != nil { |
| 48 | + t.Errorf("testVerifyScript() error = %v", err) |
| 49 | + } |
| 50 | + }) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +func TestInvalidScripts(t *testing.T) { |
| 55 | + tests := []struct { |
| 56 | + name string |
| 57 | + scriptPubkeyHex string |
| 58 | + amount int64 |
| 59 | + txToHex string |
| 60 | + inputIndex uint |
| 61 | + description string |
| 62 | + }{ |
| 63 | + { |
| 64 | + name: "old_style_wrong_signature", |
| 65 | + scriptPubkeyHex: "76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ff", // Modified last byte from 'ac' to 'ff' |
| 66 | + amount: 0, |
| 67 | + txToHex: "02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700", |
| 68 | + inputIndex: 0, |
| 69 | + description: "a random old-style transaction from the blockchain - WITH WRONG SIGNATURE for the address", |
| 70 | + }, |
| 71 | + { |
| 72 | + name: "segwit_p2sh_wrong_amount", |
| 73 | + scriptPubkeyHex: "a91434c06f8c87e355e123bdc6dda4ffabc64b6989ef87", |
| 74 | + amount: 900000, // Wrong amount, should be 1900000 |
| 75 | + txToHex: "01000000000101d9fd94d0ff0026d307c994d0003180a5f248146efb6371d040c5973f5f66d9df0400000017160014b31b31a6cb654cfab3c50567bcf124f48a0beaecffffffff012cbd1c000000000017a914233b74bf0823fa58bbbd26dfc3bb4ae715547167870247304402206f60569cac136c114a58aedd80f6fa1c51b49093e7af883e605c212bdafcd8d202200e91a55f408a021ad2631bc29a67bd6915b2d7e9ef0265627eabd7f7234455f6012103e7e802f50344303c76d12c089c8724c1b230e3b745693bbe16aad536293d15e300000000", |
| 76 | + inputIndex: 0, |
| 77 | + description: "a random segwit transaction from the blockchain using P2SH - WITH WRONG AMOUNT", |
| 78 | + }, |
| 79 | + { |
| 80 | + name: "native_segwit_wrong_segwit", |
| 81 | + scriptPubkeyHex: "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58f", // Modified last byte from 'd' to 'f' |
| 82 | + amount: 18393430, |
| 83 | + txToHex: "010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000", |
| 84 | + inputIndex: 0, |
| 85 | + description: "a random segwit transaction from the blockchain using native segwit - WITH WRONG SEGWIT", |
| 86 | + }, |
| 87 | + } |
| 88 | + |
| 89 | + for _, tt := range tests { |
| 90 | + t.Run(tt.name, func(t *testing.T) { |
| 91 | + err := testVerifyScript(t, tt.scriptPubkeyHex, tt.amount, tt.txToHex, tt.inputIndex) |
| 92 | + if err == nil || !errors.Is(err, ErrScriptVerify) { |
| 93 | + t.Errorf("testVerifyScript() was expected to fail with error '%v'", ErrScriptVerify) |
| 94 | + } |
| 95 | + }) |
| 96 | + } |
| 97 | +} |
| 98 | + |
| 99 | +// testVerifyScript is a helper function that creates the necessary objects and calls VerifyScript |
| 100 | +func testVerifyScript(t *testing.T, scriptPubkeyHex string, amount int64, txToHex string, inputIndex uint) error { |
| 101 | + scriptPubkeyBytes, err := hex.DecodeString(scriptPubkeyHex) |
| 102 | + if err != nil { |
| 103 | + t.Fatalf("Failed to decode script pubkey hex: %v", err) |
| 104 | + } |
| 105 | + |
| 106 | + scriptPubkey, err := NewScriptPubkeyFromRaw(scriptPubkeyBytes) |
| 107 | + if err != nil { |
| 108 | + t.Fatalf("Failed to create script pubkey: %v", err) |
| 109 | + } |
| 110 | + defer scriptPubkey.Destroy() |
| 111 | + |
| 112 | + txToBytes, err := hex.DecodeString(txToHex) |
| 113 | + if err != nil { |
| 114 | + t.Fatalf("Failed to decode transaction hex: %v", err) |
| 115 | + } |
| 116 | + |
| 117 | + txTo, err := NewTransactionFromRaw(txToBytes) |
| 118 | + if err != nil { |
| 119 | + t.Fatalf("Failed to create transaction: %v", err) |
| 120 | + } |
| 121 | + defer txTo.Destroy() |
| 122 | + |
| 123 | + flags := ScriptFlagsVerifyAll &^ ScriptFlagsVerifyTaproot |
| 124 | + return VerifyScript(scriptPubkey, amount, txTo, nil, inputIndex, flags) |
| 125 | +} |
0 commit comments