From afa7dd33a7226fe2eaf5ba7cccd683af28628da5 Mon Sep 17 00:00:00 2001 From: Ori Newman Date: Tue, 19 May 2026 19:16:37 +0300 Subject: [PATCH] Add compiler version to CompiledContract --- docs/TUTORIAL.md | 2 ++ silverscript-lang/src/compiler/compile.rs | 1 + silverscript-lang/src/compiler/mod.rs | 1 + silverscript-lang/tests/compiler_tests.rs | 9 ++++++++- silverscript-lang/tests/silverc_tests.rs | 4 +++- 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/TUTORIAL.md b/docs/TUTORIAL.md index 49ee095..849542f 100644 --- a/docs/TUTORIAL.md +++ b/docs/TUTORIAL.md @@ -101,6 +101,7 @@ The `args.json` file should contain an array of constructor argument expressions The compiled JSON output includes: - `contract_name`: The name of the contract +- `compiler_version`: The SilverScript compiler version that produced the artifact - `script`: The compiled bytecode (as an array of bytes) - `ast`: The abstract syntax tree of the parsed contract - `abi`: An array of entrypoint functions with their parameter types @@ -132,6 +133,7 @@ fn main() -> Result<(), Box> { let compiled = compile_contract(source, &constructor_args, options)?; println!("Contract name: {}", compiled.contract_name); + println!("Compiler version: {}", compiled.compiler_version); println!("Script length: {} bytes", compiled.script.len()); println!("ABI: {:?}", compiled.abi); diff --git a/silverscript-lang/src/compiler/compile.rs b/silverscript-lang/src/compiler/compile.rs index 0e8e1f3..cbca247 100644 --- a/silverscript-lang/src/compiler/compile.rs +++ b/silverscript-lang/src/compiler/compile.rs @@ -284,6 +284,7 @@ fn build_compiled_contract<'i>( ) -> CompiledContract<'i> { CompiledContract { contract_name: lowered_contract.name.clone(), + compiler_version: COMPILER_VERSION.to_string(), script, ast: covenant_lowered_contract.clone(), abi: function_abi_entries, diff --git a/silverscript-lang/src/compiler/mod.rs b/silverscript-lang/src/compiler/mod.rs index 930b76c..d8c6281 100644 --- a/silverscript-lang/src/compiler/mod.rs +++ b/silverscript-lang/src/compiler/mod.rs @@ -93,6 +93,7 @@ pub struct CompiledStateLayout { #[derive(Debug, Serialize, Deserialize)] pub struct CompiledContract<'i> { pub contract_name: String, + pub compiler_version: String, pub script: Vec, pub ast: ContractAst<'i>, pub abi: Vec, diff --git a/silverscript-lang/tests/compiler_tests.rs b/silverscript-lang/tests/compiler_tests.rs index d35a9e4..312d588 100644 --- a/silverscript-lang/tests/compiler_tests.rs +++ b/silverscript-lang/tests/compiler_tests.rs @@ -18,7 +18,7 @@ use kaspa_txscript::{ }; use silverscript_lang::ast::{Expr, ExprKind, Statement, format_contract_ast, parse_contract_ast}; use silverscript_lang::compiler::{ - CompileOptions, CompiledContract, CovenantDeclCallOptions, FunctionAbiEntry, FunctionInputAbi, compile_contract, + COMPILER_VERSION, CompileOptions, CompiledContract, CovenantDeclCallOptions, FunctionAbiEntry, FunctionInputAbi, compile_contract, compile_contract_ast, function_branch_index, generated_covenant_auth_entrypoint_name, struct_object, }; use silverscript_lang::debug_info::StepKind; @@ -183,6 +183,13 @@ fn accepts_missing_pragma_without_version_check() { compile_contract(&source, &[], CompileOptions::default()).expect("contract without pragma should still compile"); } +#[test] +fn compiled_contract_includes_compiler_version() { + let source = pragma_source(None); + let compiled = compile_contract(&source, &[], CompileOptions::default()).expect("compile succeeds"); + assert_eq!(compiled.compiler_version, COMPILER_VERSION); +} + #[test] fn rejects_incompatible_pragma_versions() { let pragmas = [ diff --git a/silverscript-lang/tests/silverc_tests.rs b/silverscript-lang/tests/silverc_tests.rs index f2ceec4..f1b5170 100644 --- a/silverscript-lang/tests/silverc_tests.rs +++ b/silverscript-lang/tests/silverc_tests.rs @@ -13,7 +13,7 @@ use kaspa_txscript::script_builder::ScriptBuilder; use kaspa_txscript::{EngineCtx, EngineFlags, TxScriptEngine}; use rand::RngCore; use silverscript_lang::ast::ContractAst; -use silverscript_lang::compiler::{CompiledContract, function_branch_index}; +use silverscript_lang::compiler::{COMPILER_VERSION, CompiledContract, function_branch_index}; fn contract_fixture(name: &str) -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join("silverc-test-files").join(name) @@ -83,6 +83,7 @@ fn silverc_defaults_output_path_and_empty_ctor_args() { let json = fs::read_to_string(&out_path).expect("read output"); let compiled: CompiledContract = serde_json::from_str(&json).expect("parse compiled contract"); assert_eq!(compiled.contract_name, "Basic"); + assert_eq!(compiled.compiler_version, COMPILER_VERSION); } #[test] @@ -122,6 +123,7 @@ fn silverc_accepts_constructor_args_and_output_flag() { let json = fs::read_to_string(&out_path).expect("read output"); let compiled: CompiledContract = serde_json::from_str(&json).expect("parse compiled contract"); assert_eq!(compiled.contract_name, "WithCtor"); + assert_eq!(compiled.compiler_version, COMPILER_VERSION); let selector = if compiled.without_selector { None } else { Some(function_branch_index(&compiled.ast, "main").expect("selector resolved")) }; assert!(run_script_with_selector(compiled.script, selector).is_ok());