diff --git a/src/errors/mod.rs b/src/errors/mod.rs index 5a22934..f4556e9 100644 --- a/src/errors/mod.rs +++ b/src/errors/mod.rs @@ -158,6 +158,9 @@ pub enum BSVErrors { #[error("Error deserialising TxOut field {0}: {1}")] DeserialiseTxOut(String, #[source] std::io::Error), + #[error("NonScriptData can only appear after an OP_RETURN that is not in a branch block!")] + InvalidNonScriptData(), + #[error("Error serialising TxOut field {0}: {1}")] SerialiseTxOut(String, #[source] std::io::Error), diff --git a/src/script/mod.rs b/src/script/mod.rs index bd437ef..154d4db 100644 --- a/src/script/mod.rs +++ b/src/script/mod.rs @@ -240,13 +240,6 @@ impl Script { fn map_string_to_script_bit(code: &str, is_non_script_data: bool) -> Result { let code = code.trim(); - if is_non_script_data { - if code.starts_with("non-script-data:") { - let non_script_data = hex::decode(code.trim_start_matches("non-script-data:"))?; - return Ok(ScriptBit::NonScriptData(non_script_data)); - } - } - // Number OP_CODES match code { "0" => return Ok(ScriptBit::OpCode(OpCodes::OP_0)), @@ -274,6 +267,15 @@ impl Script { return Ok(ScriptBit::OpCode(opcode)); } + if code.starts_with("non-script-data:") { + if is_non_script_data { + let non_script_data = hex::decode(code.trim_start_matches("non-script-data:"))?; + return Ok(ScriptBit::NonScriptData(non_script_data)); + } else { + return Err(BSVErrors::InvalidNonScriptData()); + } + } + // PUSHDATA OP_CODES let data_bytes = hex::decode(code)?; let bit = match VarInt::get_pushdata_opcode(data_bytes.len() as u64) { @@ -340,7 +342,7 @@ impl Script { } /** - * Ordinary ASM, (for example, OP_RETURN 01 01) does not contain ScriptBit::NonScriptData after being converted into ScriptBit. + * Ordinary ASM, (for example, OP_RETURN 01 01) does not contain ScriptBit::NonScriptData after being converted into ScriptBit. * This function wraps all ScriptBit after OP_RETURN with ScriptBit::NonScriptData. */ fn wrap_with_non_script_data(bits_iter: &mut Iter, non_script_data_index: usize) -> Vec { diff --git a/tests/script.rs b/tests/script.rs index 07d1be1..ab11c3a 100644 --- a/tests/script.rs +++ b/tests/script.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod script_tests { - use bsv::{Hash, OpCodes, P2PKHAddress, Script, ScriptBit}; + use bsv::{BSVErrors, Hash, OpCodes, P2PKHAddress, Script, ScriptBit}; // #[test] // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] // fn to_hex_string() { @@ -540,7 +540,6 @@ mod script_tests { assert_eq!(&script.to_hex(), "006a0051"); } - #[test] fn non_script_data_asm() { let script = Script::from_asm_string("0 OP_RETURN 01 0102").unwrap(); @@ -554,4 +553,14 @@ mod script_tests { assert_eq!(&script.to_hex(), "006a0101020102"); } + #[test] + fn invalid_non_script_data() { + let result = Script::from_asm_string("0 non-script-data:0101020102 01 0102 OP_RETURN"); + + assert!(matches!(result, Err(BSVErrors::InvalidNonScriptData()))); + + let result = Script::from_asm_string("OP_1 OP_IF OP_1 OP_RETURN non-script-data:0101020102 01 0102 OP_ENDIF OP_1"); + + assert!(matches!(result, Err(BSVErrors::InvalidNonScriptData()))); + } }