From 2c95ea588c4780b7d31c7e99f02ce439e212cf0b Mon Sep 17 00:00:00 2001 From: Dao Nguyen Date: Wed, 11 Sep 2024 13:40:22 +0700 Subject: [PATCH 1/6] wip: add p2pk tests --- src/lib.cairo | 1 + src/opcodes/tests/test_p2pk.cairo | 62 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/opcodes/tests/test_p2pk.cairo diff --git a/src/lib.cairo b/src/lib.cairo index d521a7a1..21ae5222 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -30,6 +30,7 @@ pub mod opcodes { mod test_crypto; mod test_reserved; mod test_disabled; + mod test_p2pk; mod utils; } pub(crate) use opcodes::Opcode; diff --git a/src/opcodes/tests/test_p2pk.cairo b/src/opcodes/tests/test_p2pk.cairo new file mode 100644 index 00000000..00e03890 --- /dev/null +++ b/src/opcodes/tests/test_p2pk.cairo @@ -0,0 +1,62 @@ +use crate::transaction::TransactionTrait; +use crate::scriptnum::ScriptNum; +use crate::utils::{felt252_to_byte_array, hex_to_bytecode}; +use crate::compiler::CompilerImpl; +use crate::engine::{EngineImpl, EngineTrait}; +use crate::transaction::{TransactionImpl}; +use crate::utxo::UTXO; +use crate::validate; +use crate::scriptflags; +use crate::witness; +#[test] +fn test_coinbase_tx() { + let validate_raw_input = ValidateRawInput{ + raw_transaction: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", + utxo_hints: array![] + }; + let result = run_raw_transaction(validate_raw_input); + assert_eq!(result, 1); +} + +#[test] +fn test_satoshi_to_halfiney_tx(){ + let prevout_pk_script = + "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; + let prev_out = UTXO { + amount: 5000000000, + pubkey_script: hex_to_bytecode(@prevout_pk_script), + block_height: 9 + }; + let utxo_hints = array![prev_out]; + let validate_raw_input = ValidateRawInput{ + raw_transaction: "0x0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", + utxo_hints: utxo_hints, + }; + let result = run_raw_transaction(validate_raw_input); + assert_eq!(result, 1); +} + +#[derive(Drop)] +struct ValidateRawInput { + raw_transaction: ByteArray, + utxo_hints: Array +} + + +fn run_raw_transaction(input: ValidateRawInput) -> u8 { + println!("Running Bitcoin Script with raw transaction: '{}'", input.raw_transaction); + let raw_transaction = hex_to_bytecode(@input.raw_transaction); + let transaction = TransactionTrait::deserialize(raw_transaction); + let res = validate::validate_transaction(transaction, 0, input.utxo_hints); + + match res { + Result::Ok(_) => { + println!("Execution successful"); + 1 + }, + Result::Err(e) => { + println!("Execution failed: {}", felt252_to_byte_array(e)); + 0 + } + } +} \ No newline at end of file From 7bcea08b76b55cc9ffc056704b37a75536deb96a Mon Sep 17 00:00:00 2001 From: Dao Nguyen Date: Wed, 11 Sep 2024 14:01:26 +0700 Subject: [PATCH 2/6] scarb fmt --- src/opcodes/tests/test_p2pk.cairo | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/opcodes/tests/test_p2pk.cairo b/src/opcodes/tests/test_p2pk.cairo index 00e03890..f48e1818 100644 --- a/src/opcodes/tests/test_p2pk.cairo +++ b/src/opcodes/tests/test_p2pk.cairo @@ -10,7 +10,7 @@ use crate::scriptflags; use crate::witness; #[test] fn test_coinbase_tx() { - let validate_raw_input = ValidateRawInput{ + let validate_raw_input = ValidateRawInput { raw_transaction: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", utxo_hints: array![] }; @@ -19,16 +19,14 @@ fn test_coinbase_tx() { } #[test] -fn test_satoshi_to_halfiney_tx(){ +fn test_satoshi_to_halfiney_tx() { let prevout_pk_script = "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; let prev_out = UTXO { - amount: 5000000000, - pubkey_script: hex_to_bytecode(@prevout_pk_script), - block_height: 9 + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9 }; let utxo_hints = array![prev_out]; - let validate_raw_input = ValidateRawInput{ + let validate_raw_input = ValidateRawInput { raw_transaction: "0x0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", utxo_hints: utxo_hints, }; @@ -48,7 +46,7 @@ fn run_raw_transaction(input: ValidateRawInput) -> u8 { let raw_transaction = hex_to_bytecode(@input.raw_transaction); let transaction = TransactionTrait::deserialize(raw_transaction); let res = validate::validate_transaction(transaction, 0, input.utxo_hints); - + match res { Result::Ok(_) => { println!("Execution successful"); @@ -59,4 +57,4 @@ fn run_raw_transaction(input: ValidateRawInput) -> u8 { 0 } } -} \ No newline at end of file +} From df593c1e6dfbf0b75a49f9027c7863ae2e783745 Mon Sep 17 00:00:00 2001 From: Dao Nguyen Date: Thu, 12 Sep 2024 21:02:33 +0700 Subject: [PATCH 3/6] add more mainnet txs --- src/main.cairo | 8 +- src/opcodes/tests/test_p2pk.cairo | 125 +++++++++++++++++++++--------- src/validate.cairo | 1 + 3 files changed, 95 insertions(+), 39 deletions(-) diff --git a/src/main.cairo b/src/main.cairo index 33251e91..af15f2b8 100644 --- a/src/main.cairo +++ b/src/main.cairo @@ -182,12 +182,12 @@ fn backend_debug(input: InputData) -> u8 { } #[derive(Drop)] -struct ValidateRawInput { - raw_transaction: ByteArray, - utxo_hints: Array +pub struct ValidateRawInput { + pub raw_transaction: ByteArray, + pub utxo_hints: Array } -fn run_raw_transaction(input: ValidateRawInput) -> u8 { +pub fn run_raw_transaction(input: ValidateRawInput) -> u8 { println!("Running Bitcoin Script with raw transaction: '{}'", input.raw_transaction); let raw_transaction = utils::hex_to_bytecode(@input.raw_transaction); let transaction = TransactionTrait::deserialize(raw_transaction); diff --git a/src/opcodes/tests/test_p2pk.cairo b/src/opcodes/tests/test_p2pk.cairo index f48e1818..ae1d9131 100644 --- a/src/opcodes/tests/test_p2pk.cairo +++ b/src/opcodes/tests/test_p2pk.cairo @@ -1,60 +1,115 @@ -use crate::transaction::TransactionTrait; -use crate::scriptnum::ScriptNum; -use crate::utils::{felt252_to_byte_array, hex_to_bytecode}; +use crate::utils::{hex_to_bytecode}; use crate::compiler::CompilerImpl; -use crate::engine::{EngineImpl, EngineTrait}; +use crate::engine::{EngineImpl}; use crate::transaction::{TransactionImpl}; use crate::utxo::UTXO; -use crate::validate; -use crate::scriptflags; -use crate::witness; +use crate::main::{ValidateRawInput, run_raw_transaction}; + +// // coinbase tx of block 150,007 +// // +// https://learnmeabitcoin.com/explorer/tx/18a16d322b235f636ab90e62e79a9f20a0b9c14e8da51e9dc0974f99f82ee444 +// #[test] +// fn test_coinbase_tx() { +// let validate_raw_input = ValidateRawInput { +// raw_transaction: +// "0x01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804233fa04e028b12ffffffff0130490b2a010000004341047eda6bd04fb27cab6e7c28c99b94977f073e912f25d1ff7165d9c95cd9bbe6da7e7ad7f2acb09e0ced91705f7616af53bee51a238b7dc527f2be0aa60469d140ac00000000", +// utxo_hints: array![] +// }; +// let result = run_raw_transaction(validate_raw_input); +// assert_eq!(result, 1); +// } + +// https://learnmeabitcoin.com/explorer/tx/f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16 #[test] -fn test_coinbase_tx() { +fn test_satoshi_to_halfiney_tx() { + let prevout_pk_script = + "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; + let prev_out = UTXO { + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9 + }; + let utxo_hints = array![prev_out]; let validate_raw_input = ValidateRawInput { - raw_transaction: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", - utxo_hints: array![] + raw_transaction: "0x0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", + utxo_hints: utxo_hints, }; let result = run_raw_transaction(validate_raw_input); assert_eq!(result, 1); } +// https://learnmeabitcoin.com/explorer/tx/3db8816c460f674e47f0e5799656721a249acdd53cd43a530c83384577485947 #[test] -fn test_satoshi_to_halfiney_tx() { +fn test_compressed_pubkey() { + let prevout_pk_script = "0x76a9147fbff43f08b409a03febae114cf0885c37ffd7c488ac"; + let prev_out = UTXO { + amount: 3000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376 + }; + let validate_raw_input = ValidateRawInput { + raw_transaction: "0x010000000135655162f2df3af5e5f12b5b4b545e9069ed61897974622888b9c47e0f55e105000000006b483045022100bdd3796f6a6bb7f8ca42a70438a3150501f9ec760195b4d3314b1b4b21aac29402202f8479c9384a737bb323cd8600d9e3c5a379334a55acf7c3f4a4ca1eaaabe97e012103e49d61c45a729c427038b967df38459a2579a2c37057cf6a2efb2c3048f676aaffffffff018c0a000000000000232103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac00000000", + utxo_hints: array![prev_out], + }; + + let result = run_raw_transaction(validate_raw_input); + assert_eq!(result, 1); +} + +// https://learnmeabitcoin.com/explorer/tx/a16f3ce4dd5deb92d98ef5cf8afeaf0775ebca408f708b2146c4fb42b41e14be +#[test] +fn test_block_181_mainnet() { let prevout_pk_script = "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; let prev_out = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9 + amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 }; - let utxo_hints = array![prev_out]; let validate_raw_input = ValidateRawInput { - raw_transaction: "0x0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", - utxo_hints: utxo_hints, + raw_transaction: "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", + utxo_hints: array![prev_out], }; + let result = run_raw_transaction(validate_raw_input); assert_eq!(result, 1); } -#[derive(Drop)] -struct ValidateRawInput { - raw_transaction: ByteArray, - utxo_hints: Array +// https://learnmeabitcoin.com/explorer/tx/591e91f809d716912ca1d4a9295e70c3e78bab077683f79350f101da64588073 +#[test] +fn test_block_182_mainnet() { + let prevout_pk_script = + "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; + let prev_out = UTXO { + amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 + }; + let validate_raw_input = ValidateRawInput { + raw_transaction: "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", + utxo_hints: array![prev_out], + }; + + let result = run_raw_transaction(validate_raw_input); + assert_eq!(result, 1); } +// https://learnmeabitcoin.com/explorer/tx/a3b0e9e7cddbbe78270fa4182a7675ff00b92872d8df7d14265a2b1e379a9d33 +#[test] +fn test_block_496_mainnet() { + let prevout_pk_script = + "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; + let prevout_pk_script_2 = + "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; + let prevout_pk_script_3 = + "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; + let prev_out = UTXO { + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 + }; + let prev_out2 = UTXO { + amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 + }; + let prev_out3 = UTXO { + amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 + }; + let validate_raw_input = ValidateRawInput { + raw_transaction: "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000", + utxo_hints: array![prev_out, prev_out2, prev_out3], + }; -fn run_raw_transaction(input: ValidateRawInput) -> u8 { - println!("Running Bitcoin Script with raw transaction: '{}'", input.raw_transaction); - let raw_transaction = hex_to_bytecode(@input.raw_transaction); - let transaction = TransactionTrait::deserialize(raw_transaction); - let res = validate::validate_transaction(transaction, 0, input.utxo_hints); - - match res { - Result::Ok(_) => { - println!("Execution successful"); - 1 - }, - Result::Err(e) => { - println!("Execution failed: {}", felt252_to_byte_array(e)); - 0 - } - } + let result = run_raw_transaction(validate_raw_input); + assert_eq!(result, 1); } + diff --git a/src/validate.cairo b/src/validate.cairo index 93b08560..68bffeab 100644 --- a/src/validate.cairo +++ b/src/validate.cairo @@ -24,6 +24,7 @@ pub fn validate_transaction( let res = engine.execute(); if res.is_err() { err = res.unwrap_err(); + println!("debug {} {}", i, err); break; } From 675125138144cfcdf41dc0fef05326036b484d75 Mon Sep 17 00:00:00 2001 From: Dao Nguyen Date: Thu, 12 Sep 2024 21:24:30 +0700 Subject: [PATCH 4/6] refactor --- src/engine.cairo | 1 + src/opcodes/tests/test_p2pk.cairo | 88 ++++++++++++++++++++++++------- src/validate.cairo | 1 - 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/src/engine.cairo b/src/engine.cairo index 7469793e..d5d6174a 100644 --- a/src/engine.cairo +++ b/src/engine.cairo @@ -529,6 +529,7 @@ pub impl EngineImpl of EngineTrait { } else { // TODO: pop bool? let top_stack = self.dstack.peek_byte_array(0)?; + println!("debug22 {}", top_stack); let ret_val = top_stack.clone(); let mut is_ok = false; let mut i = 0; diff --git a/src/opcodes/tests/test_p2pk.cairo b/src/opcodes/tests/test_p2pk.cairo index ae1d9131..f0233c78 100644 --- a/src/opcodes/tests/test_p2pk.cairo +++ b/src/opcodes/tests/test_p2pk.cairo @@ -1,9 +1,10 @@ use crate::utils::{hex_to_bytecode}; use crate::compiler::CompilerImpl; use crate::engine::{EngineImpl}; -use crate::transaction::{TransactionImpl}; +use crate::transaction::{Transaction, TransactionInput, TransactionOutput, OutPoint}; use crate::utxo::UTXO; use crate::main::{ValidateRawInput, run_raw_transaction}; +use crate::validate::validate_transaction; // // coinbase tx of block 150,007 // // @@ -87,29 +88,80 @@ fn test_block_182_mainnet() { } // https://learnmeabitcoin.com/explorer/tx/a3b0e9e7cddbbe78270fa4182a7675ff00b92872d8df7d14265a2b1e379a9d33 +// #[test] +// fn test_block_496_mainnet() { + // let prevout_pk_script = + // "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; + // let prevout_pk_script_2 = + // "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; + // let prevout_pk_script_3 = + // "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; + // let prev_out = UTXO { + // amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 + // }; + // let prev_out2 = UTXO { + // amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 + // }; + // let prev_out3 = UTXO { + // amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 + // }; +// let validate_raw_input = ValidateRawInput { +// raw_transaction: "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000", +// utxo_hints: array![prev_out, prev_out2, prev_out3], +// }; + +// let result = run_raw_transaction(validate_raw_input); +// assert_eq!(result, 1); +// } + #[test] fn test_block_496_mainnet() { - let prevout_pk_script = + let tx_in0 = TransactionInput { + previous_outpoint: OutPoint { txid: 0x264299886446921c89e598ec2b1ec3eab6a2c9b0235b310ff513a039315ff721, vout: 0, }, + signature_script: "0x483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01", + witness: array![], + sequence: 0xffffffff, + }; + let tx_in1 = TransactionInput { + previous_outpoint: OutPoint { txid: 0x4385fcf8b14497d0659adccfe06ae7e38e0b5dc95ff8a13d7c62035994a0cd79, vout: 0, }, + signature_script: "0x483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501", + witness: array![], + sequence: 0xffffffff, + }; + let tx_in2 = TransactionInput { + previous_outpoint: OutPoint { txid: 0x828ef3b079f9c23829c56fe86e85b4a69d9e06e5b54ea597eef5fb3ffef509fe, vout: 0, }, + signature_script: "0x47304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01", + witness: array![], + sequence: 0xffffffff, + }; + + let tx_out0 = TransactionOutput{ + value: 6100000000, + publickey_script: "0x4104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac" + }; + let tx = Transaction{ + version: 1, + transaction_inputs: array![tx_in0, tx_in1, tx_in2], + transaction_outputs: array![tx_out0], + locktime: 0, + }; + + let prevout_pk_script_0 = "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; - let prevout_pk_script_2 = + let prevout_pk_script_1 = "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; - let prevout_pk_script_3 = + let prevout_pk_script_2 = "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; - let prev_out = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 + let prev_out_0 = UTXO { + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_0), block_height: 360 }; - let prev_out2 = UTXO { - amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 + let prev_out_1 = UTXO { + amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_1), block_height: 187 }; - let prev_out3 = UTXO { - amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 + let prev_out_2= UTXO { + amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 248 }; - let validate_raw_input = ValidateRawInput { - raw_transaction: "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000", - utxo_hints: array![prev_out, prev_out2, prev_out3], - }; - - let result = run_raw_transaction(validate_raw_input); - assert_eq!(result, 1); -} + let res = validate_transaction(tx, 0, array![prev_out_0, prev_out_1, prev_out_2]); + assert!(res.is_ok()); +} \ No newline at end of file diff --git a/src/validate.cairo b/src/validate.cairo index 68bffeab..93b08560 100644 --- a/src/validate.cairo +++ b/src/validate.cairo @@ -24,7 +24,6 @@ pub fn validate_transaction( let res = engine.execute(); if res.is_err() { err = res.unwrap_err(); - println!("debug {} {}", i, err); break; } From bbd66dceb28c6ec13f94814d77db9c3db00bc9ab Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Tue, 17 Sep 2024 01:14:14 -0400 Subject: [PATCH 5/6] Fix bug with remove_opcodeseperator and cleanup --- src/engine.cairo | 1 - src/lib.cairo | 2 +- src/opcodes/tests/test_p2pk.cairo | 167 ------------------------------ src/signature/utils.cairo | 19 +++- src/tests/test_p2pk.cairo | 85 +++++++++++++++ src/utils.cairo | 11 ++ 6 files changed, 111 insertions(+), 174 deletions(-) delete mode 100644 src/opcodes/tests/test_p2pk.cairo create mode 100644 src/tests/test_p2pk.cairo diff --git a/src/engine.cairo b/src/engine.cairo index d5d6174a..7469793e 100644 --- a/src/engine.cairo +++ b/src/engine.cairo @@ -529,7 +529,6 @@ pub impl EngineImpl of EngineTrait { } else { // TODO: pop bool? let top_stack = self.dstack.peek_byte_array(0)?; - println!("debug22 {}", top_stack); let ret_val = top_stack.clone(); let mut is_ok = false; let mut i = 0; diff --git a/src/lib.cairo b/src/lib.cairo index 21ae5222..ce8a504b 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -30,7 +30,6 @@ pub mod opcodes { mod test_crypto; mod test_reserved; mod test_disabled; - mod test_p2pk; mod utils; } pub(crate) use opcodes::Opcode; @@ -56,5 +55,6 @@ pub mod transaction; mod tests { mod test_coinbase; mod test_transactions; + mod test_p2pk; } mod main; diff --git a/src/opcodes/tests/test_p2pk.cairo b/src/opcodes/tests/test_p2pk.cairo deleted file mode 100644 index f0233c78..00000000 --- a/src/opcodes/tests/test_p2pk.cairo +++ /dev/null @@ -1,167 +0,0 @@ -use crate::utils::{hex_to_bytecode}; -use crate::compiler::CompilerImpl; -use crate::engine::{EngineImpl}; -use crate::transaction::{Transaction, TransactionInput, TransactionOutput, OutPoint}; -use crate::utxo::UTXO; -use crate::main::{ValidateRawInput, run_raw_transaction}; -use crate::validate::validate_transaction; - -// // coinbase tx of block 150,007 -// // -// https://learnmeabitcoin.com/explorer/tx/18a16d322b235f636ab90e62e79a9f20a0b9c14e8da51e9dc0974f99f82ee444 -// #[test] -// fn test_coinbase_tx() { -// let validate_raw_input = ValidateRawInput { -// raw_transaction: -// "0x01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804233fa04e028b12ffffffff0130490b2a010000004341047eda6bd04fb27cab6e7c28c99b94977f073e912f25d1ff7165d9c95cd9bbe6da7e7ad7f2acb09e0ced91705f7616af53bee51a238b7dc527f2be0aa60469d140ac00000000", -// utxo_hints: array![] -// }; -// let result = run_raw_transaction(validate_raw_input); -// assert_eq!(result, 1); -// } - -// https://learnmeabitcoin.com/explorer/tx/f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16 -#[test] -fn test_satoshi_to_halfiney_tx() { - let prevout_pk_script = - "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; - let prev_out = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9 - }; - let utxo_hints = array![prev_out]; - let validate_raw_input = ValidateRawInput { - raw_transaction: "0x0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", - utxo_hints: utxo_hints, - }; - let result = run_raw_transaction(validate_raw_input); - assert_eq!(result, 1); -} - -// https://learnmeabitcoin.com/explorer/tx/3db8816c460f674e47f0e5799656721a249acdd53cd43a530c83384577485947 -#[test] -fn test_compressed_pubkey() { - let prevout_pk_script = "0x76a9147fbff43f08b409a03febae114cf0885c37ffd7c488ac"; - let prev_out = UTXO { - amount: 3000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376 - }; - let validate_raw_input = ValidateRawInput { - raw_transaction: "0x010000000135655162f2df3af5e5f12b5b4b545e9069ed61897974622888b9c47e0f55e105000000006b483045022100bdd3796f6a6bb7f8ca42a70438a3150501f9ec760195b4d3314b1b4b21aac29402202f8479c9384a737bb323cd8600d9e3c5a379334a55acf7c3f4a4ca1eaaabe97e012103e49d61c45a729c427038b967df38459a2579a2c37057cf6a2efb2c3048f676aaffffffff018c0a000000000000232103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac00000000", - utxo_hints: array![prev_out], - }; - - let result = run_raw_transaction(validate_raw_input); - assert_eq!(result, 1); -} - -// https://learnmeabitcoin.com/explorer/tx/a16f3ce4dd5deb92d98ef5cf8afeaf0775ebca408f708b2146c4fb42b41e14be -#[test] -fn test_block_181_mainnet() { - let prevout_pk_script = - "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; - let prev_out = UTXO { - amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 - }; - let validate_raw_input = ValidateRawInput { - raw_transaction: "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", - utxo_hints: array![prev_out], - }; - - let result = run_raw_transaction(validate_raw_input); - assert_eq!(result, 1); -} - -// https://learnmeabitcoin.com/explorer/tx/591e91f809d716912ca1d4a9295e70c3e78bab077683f79350f101da64588073 -#[test] -fn test_block_182_mainnet() { - let prevout_pk_script = - "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; - let prev_out = UTXO { - amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 - }; - let validate_raw_input = ValidateRawInput { - raw_transaction: "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000", - utxo_hints: array![prev_out], - }; - - let result = run_raw_transaction(validate_raw_input); - assert_eq!(result, 1); -} - -// https://learnmeabitcoin.com/explorer/tx/a3b0e9e7cddbbe78270fa4182a7675ff00b92872d8df7d14265a2b1e379a9d33 -// #[test] -// fn test_block_496_mainnet() { - // let prevout_pk_script = - // "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; - // let prevout_pk_script_2 = - // "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; - // let prevout_pk_script_3 = - // "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; - // let prev_out = UTXO { - // amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 - // }; - // let prev_out2 = UTXO { - // amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 - // }; - // let prev_out3 = UTXO { - // amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 - // }; -// let validate_raw_input = ValidateRawInput { -// raw_transaction: "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000", -// utxo_hints: array![prev_out, prev_out2, prev_out3], -// }; - -// let result = run_raw_transaction(validate_raw_input); -// assert_eq!(result, 1); -// } - -#[test] -fn test_block_496_mainnet() { - let tx_in0 = TransactionInput { - previous_outpoint: OutPoint { txid: 0x264299886446921c89e598ec2b1ec3eab6a2c9b0235b310ff513a039315ff721, vout: 0, }, - signature_script: "0x483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01", - witness: array![], - sequence: 0xffffffff, - }; - let tx_in1 = TransactionInput { - previous_outpoint: OutPoint { txid: 0x4385fcf8b14497d0659adccfe06ae7e38e0b5dc95ff8a13d7c62035994a0cd79, vout: 0, }, - signature_script: "0x483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501", - witness: array![], - sequence: 0xffffffff, - }; - let tx_in2 = TransactionInput { - previous_outpoint: OutPoint { txid: 0x828ef3b079f9c23829c56fe86e85b4a69d9e06e5b54ea597eef5fb3ffef509fe, vout: 0, }, - signature_script: "0x47304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01", - witness: array![], - sequence: 0xffffffff, - }; - - let tx_out0 = TransactionOutput{ - value: 6100000000, - publickey_script: "0x4104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac" - }; - let tx = Transaction{ - version: 1, - transaction_inputs: array![tx_in0, tx_in1, tx_in2], - transaction_outputs: array![tx_out0], - locktime: 0, - }; - - let prevout_pk_script_0 = - "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; - let prevout_pk_script_1 = - "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; - let prevout_pk_script_2 = - "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; - let prev_out_0 = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_0), block_height: 360 - }; - let prev_out_1 = UTXO { - amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_1), block_height: 187 - }; - let prev_out_2= UTXO { - amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 248 - }; - - let res = validate_transaction(tx, 0, array![prev_out_0, prev_out_1, prev_out_2]); - assert!(res.is_ok()); -} \ No newline at end of file diff --git a/src/signature/utils.cairo b/src/signature/utils.cairo index 0e6b8446..76f34171 100644 --- a/src/signature/utils.cairo +++ b/src/signature/utils.cairo @@ -8,12 +8,20 @@ pub fn remove_opcodeseparator(script: @ByteArray) -> @ByteArray { let mut parsed_script: ByteArray = ""; let mut i: usize = 0; + // TODO: tokenizer/standardize script parsing while i < script.len() { - let value = script[i]; - if value != Opcode::OP_CODESEPARATOR { - parsed_script.append_byte(value); + let opcode = script[i]; + // TODO: Error handling + if opcode == Opcode::OP_CODESEPARATOR { + i += 1; + continue; + } + let data_len = Opcode::data_len(i, script).unwrap(); + let end = i + data_len + 1; + while i < end { + parsed_script.append_byte(script[i]); + i += 1; } - i += 1; }; @parsed_script @@ -44,7 +52,8 @@ pub fn transaction_procedure( >::new(); while i < transaction_input.len() { - let mut temp_transaction_input: TransactionInput = transaction_input.pop_front().unwrap(); + // TODO: Optimize this + let mut temp_transaction_input: TransactionInput = transaction_input[i].clone(); if hash_type_masked == constants::SIG_HASH_SINGLE && i < index { processed_transaction_output diff --git a/src/tests/test_p2pk.cairo b/src/tests/test_p2pk.cairo new file mode 100644 index 00000000..235edd4c --- /dev/null +++ b/src/tests/test_p2pk.cairo @@ -0,0 +1,85 @@ +use crate::utils::{hex_to_bytecode}; +use crate::compiler::CompilerImpl; +use crate::engine::{EngineImpl}; +use crate::transaction::TransactionTrait; +use crate::validate; +use crate::utxo::UTXO; +use crate::utils; + +// https://learnmeabitcoin.com/explorer/tx/3db8816c460f674e47f0e5799656721a249acdd53cd43a530c83384577485947 +#[test] +fn test_compressed_pubkey() { + let prevout_pk_script = "0x76a9147fbff43f08b409a03febae114cf0885c37ffd7c488ac"; + let prev_out = UTXO { + amount: 3000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376 + }; + let raw_transaction_hex = "0x010000000135655162f2df3af5e5f12b5b4b545e9069ed61897974622888b9c47e0f55e105000000006b483045022100bdd3796f6a6bb7f8ca42a70438a3150501f9ec760195b4d3314b1b4b21aac29402202f8479c9384a737bb323cd8600d9e3c5a379334a55acf7c3f4a4ca1eaaabe97e012103e49d61c45a729c427038b967df38459a2579a2c37057cf6a2efb2c3048f676aaffffffff018c0a000000000000232103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac00000000"; + let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); + let transaction = TransactionTrait::deserialize(raw_transaction); + let utxo_hints = array![prev_out]; + + let res = validate::validate_transaction(transaction, 0, utxo_hints); + assert!(res.is_ok(), "Transaction validation failed"); +} + +// https://learnmeabitcoin.com/explorer/tx/a16f3ce4dd5deb92d98ef5cf8afeaf0775ebca408f708b2146c4fb42b41e14be +#[test] +fn test_block_181_tx_mainnet() { + let prevout_pk_script = + "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; + let prev_out = UTXO { + amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 + }; + let raw_transaction_hex = "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; + let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); + let transaction = TransactionTrait::deserialize(raw_transaction); + let utxo_hints = array![prev_out]; + + let res = validate::validate_transaction(transaction, 0, utxo_hints); + assert!(res.is_ok(), "Transaction validation failed"); +} + +// https://learnmeabitcoin.com/explorer/tx/591e91f809d716912ca1d4a9295e70c3e78bab077683f79350f101da64588073 +#[test] +fn test_block_182_tx_mainnet() { + let prevout_pk_script = + "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; + let prev_out = UTXO { + amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 + }; + let raw_transaction_hex = "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; + let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); + let transaction = TransactionTrait::deserialize(raw_transaction); + let utxo_hints = array![prev_out]; + + let res = validate::validate_transaction(transaction, 0, utxo_hints); + assert!(res.is_ok(), "Transaction validation failed"); +} + +// https://learnmeabitcoin.com/explorer/tx/a3b0e9e7cddbbe78270fa4182a7675ff00b92872d8df7d14265a2b1e379a9d33 +#[test] +fn test_block_496_tx_mainnet() { + let prevout_pk_script = + "0x41044ca7baf6d8b658abd04223909d82f1764740bdc9317255f54e4910f888bd82950e33236798517591e4c2181f69b5eaa2fa1f21866780a0cc5d8396a04fd36310ac"; + let prevout_pk_script_2 = + "0x4104fe1b9ccf732e1f6b760c5ed3152388eeeadd4a073e621f741eb157e6a62e3547c8e939abbd6a513bf3a1fbe28f9ea85a4e64c526702435d726f7ff14da40bae4ac"; + let prevout_pk_script_3 = + "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; + let prev_out = UTXO { + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 + }; + let prev_out2 = UTXO { + amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 + }; + let prev_out3 = UTXO { + amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 + }; + + let raw_transaction_hex = "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000"; + let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); + let transaction = TransactionTrait::deserialize(raw_transaction); + let utxo_hints = array![prev_out, prev_out2, prev_out3]; + + let res = validate::validate_transaction(transaction, 0, utxo_hints); + assert!(res.is_ok(), "Transaction validation failed"); +} diff --git a/src/utils.cairo b/src/utils.cairo index c208f23f..e1987883 100644 --- a/src/utils.cairo +++ b/src/utils.cairo @@ -271,6 +271,17 @@ pub fn felt252_to_byte_array(value: felt252) -> ByteArray { byte_array.rev() } +pub fn u256_to_byte_array(value: u256) -> ByteArray { + let byte_shift = 256; + let mut byte_array = ""; + let mut valueU256: u256 = value; + while valueU256 > 0 { + byte_array.append_byte((valueU256 % byte_shift).try_into().unwrap()); + valueU256 /= byte_shift; + }; + byte_array.rev() +} + pub fn int_to_hex(value: u8) -> felt252 { let half_byte_shift = 16; let byte_shift = 256; From 05146c9a76c7575566f94482af1de3f504efbce3 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Tue, 17 Sep 2024 01:15:22 -0400 Subject: [PATCH 6/6] Scarb fmt --- src/main.cairo | 8 ++++---- src/tests/test_p2pk.cairo | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main.cairo b/src/main.cairo index af15f2b8..33251e91 100644 --- a/src/main.cairo +++ b/src/main.cairo @@ -182,12 +182,12 @@ fn backend_debug(input: InputData) -> u8 { } #[derive(Drop)] -pub struct ValidateRawInput { - pub raw_transaction: ByteArray, - pub utxo_hints: Array +struct ValidateRawInput { + raw_transaction: ByteArray, + utxo_hints: Array } -pub fn run_raw_transaction(input: ValidateRawInput) -> u8 { +fn run_raw_transaction(input: ValidateRawInput) -> u8 { println!("Running Bitcoin Script with raw transaction: '{}'", input.raw_transaction); let raw_transaction = utils::hex_to_bytecode(@input.raw_transaction); let transaction = TransactionTrait::deserialize(raw_transaction); diff --git a/src/tests/test_p2pk.cairo b/src/tests/test_p2pk.cairo index 235edd4c..fb20dcf9 100644 --- a/src/tests/test_p2pk.cairo +++ b/src/tests/test_p2pk.cairo @@ -13,7 +13,8 @@ fn test_compressed_pubkey() { let prev_out = UTXO { amount: 3000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376 }; - let raw_transaction_hex = "0x010000000135655162f2df3af5e5f12b5b4b545e9069ed61897974622888b9c47e0f55e105000000006b483045022100bdd3796f6a6bb7f8ca42a70438a3150501f9ec760195b4d3314b1b4b21aac29402202f8479c9384a737bb323cd8600d9e3c5a379334a55acf7c3f4a4ca1eaaabe97e012103e49d61c45a729c427038b967df38459a2579a2c37057cf6a2efb2c3048f676aaffffffff018c0a000000000000232103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac00000000"; + let raw_transaction_hex = + "0x010000000135655162f2df3af5e5f12b5b4b545e9069ed61897974622888b9c47e0f55e105000000006b483045022100bdd3796f6a6bb7f8ca42a70438a3150501f9ec760195b4d3314b1b4b21aac29402202f8479c9384a737bb323cd8600d9e3c5a379334a55acf7c3f4a4ca1eaaabe97e012103e49d61c45a729c427038b967df38459a2579a2c37057cf6a2efb2c3048f676aaffffffff018c0a000000000000232103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac00000000"; let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); let transaction = TransactionTrait::deserialize(raw_transaction); let utxo_hints = array![prev_out]; @@ -30,7 +31,8 @@ fn test_block_181_tx_mainnet() { let prev_out = UTXO { amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 }; - let raw_transaction_hex = "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; + let raw_transaction_hex = + "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); let transaction = TransactionTrait::deserialize(raw_transaction); let utxo_hints = array![prev_out]; @@ -47,7 +49,8 @@ fn test_block_182_tx_mainnet() { let prev_out = UTXO { amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 }; - let raw_transaction_hex = "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; + let raw_transaction_hex = + "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); let transaction = TransactionTrait::deserialize(raw_transaction); let utxo_hints = array![prev_out]; @@ -75,7 +78,8 @@ fn test_block_496_tx_mainnet() { amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 }; - let raw_transaction_hex = "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000"; + let raw_transaction_hex = + "0x010000000321f75f3139a013f50f315b23b0c9a2b6eac31e2bec98e5891c924664889942260000000049483045022100cb2c6b346a978ab8c61b18b5e9397755cbd17d6eb2fe0083ef32e067fa6c785a02206ce44e613f31d9a6b0517e46f3db1576e9812cc98d159bfdaf759a5014081b5c01ffffffff79cda0945903627c3da1f85fc95d0b8ee3e76ae0cfdc9a65d09744b1f8fc85430000000049483045022047957cdd957cfd0becd642f6b84d82f49b6cb4c51a91f49246908af7c3cfdf4a022100e96b46621f1bffcf5ea5982f88cef651e9354f5791602369bf5a82a6cd61a62501fffffffffe09f5fe3ffbf5ee97a54eb5e5069e9da6b4856ee86fc52938c2f979b0f38e82000000004847304402204165be9a4cbab8049e1af9723b96199bfd3e85f44c6b4c0177e3962686b26073022028f638da23fc003760861ad481ead4099312c60030d4cb57820ce4d33812a5ce01ffffffff01009d966b01000000434104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac00000000"; let raw_transaction = utils::hex_to_bytecode(@raw_transaction_hex); let transaction = TransactionTrait::deserialize(raw_transaction); let utxo_hints = array![prev_out, prev_out2, prev_out3];