diff --git a/Cargo.lock b/Cargo.lock index d3eb9d7e..807fdf90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1948,8 +1948,9 @@ checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" [[package]] name = "pallas-addresses" -version = "0.29.0" -source = "git+https://github.com/KtorZ/pallas.git?rev=454b3bcf32cdc238aba65e4c3e4656a352480ec1#454b3bcf32cdc238aba65e4c3e4656a352480ec1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38fac39e0da3b0fc4c859635c72e97584f01f3a0f4f1508b0851c02d6d52f15" dependencies = [ "base58", "bech32", @@ -1963,8 +1964,9 @@ dependencies = [ [[package]] name = "pallas-codec" -version = "0.29.0" -source = "git+https://github.com/KtorZ/pallas.git?rev=454b3bcf32cdc238aba65e4c3e4656a352480ec1#454b3bcf32cdc238aba65e4c3e4656a352480ec1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8a4b87dbc8bcb8aeb865f7cca5e1eb29744330e23b307169fc30537648b264" dependencies = [ "hex", "minicbor", @@ -1975,8 +1977,9 @@ dependencies = [ [[package]] name = "pallas-crypto" -version = "0.29.0" -source = "git+https://github.com/KtorZ/pallas.git?rev=454b3bcf32cdc238aba65e4c3e4656a352480ec1#454b3bcf32cdc238aba65e4c3e4656a352480ec1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b98c3f204299d47d9b581ab425043789caff1f491c078ee3d3f109d6556f725" dependencies = [ "cryptoxide", "hex", @@ -1988,8 +1991,9 @@ dependencies = [ [[package]] name = "pallas-primitives" -version = "0.29.0" -source = "git+https://github.com/KtorZ/pallas.git?rev=454b3bcf32cdc238aba65e4c3e4656a352480ec1#454b3bcf32cdc238aba65e4c3e4656a352480ec1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f64835dd9cbdd75a38961a190b983f02746c872340daf1a921eada8c525a4b6" dependencies = [ "base58", "bech32", @@ -2003,8 +2007,9 @@ dependencies = [ [[package]] name = "pallas-traverse" -version = "0.29.0" -source = "git+https://github.com/KtorZ/pallas.git?rev=454b3bcf32cdc238aba65e4c3e4656a352480ec1#454b3bcf32cdc238aba65e4c3e4656a352480ec1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad516b05ba7d838ee84f9998d7b2b4ff7acc178cb052bcfd5fea9edc2ef6023f" dependencies = [ "hex", "itertools 0.13.0", diff --git a/Cargo.toml b/Cargo.toml index a95f3ee8..2c978863 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,11 +49,11 @@ x86_64-unknown-linux-gnu = "ubuntu-22.04" walkdir = "2.3.2" insta = { version = "1.30.0", features = ["yaml", "json", "redactions"] } miette = { version = "7.2.0", features = ["fancy"] } -pallas-addresses = { git = "https://github.com/KtorZ/pallas.git", rev = "454b3bcf32cdc238aba65e4c3e4656a352480ec1" } -pallas-codec = { git = "https://github.com/KtorZ/pallas.git", rev = "454b3bcf32cdc238aba65e4c3e4656a352480ec1", features = ["num-bigint"] } -pallas-crypto = { git = "https://github.com/KtorZ/pallas.git", rev = "454b3bcf32cdc238aba65e4c3e4656a352480ec1" } -pallas-primitives = { git = "https://github.com/KtorZ/pallas.git", rev = "454b3bcf32cdc238aba65e4c3e4656a352480ec1" } -pallas-traverse = { git = "https://github.com/KtorZ/pallas.git", rev = "454b3bcf32cdc238aba65e4c3e4656a352480ec1" } +pallas-addresses = "0.30.1" +pallas-codec = { version = "0.30.1", features = ["num-bigint"] } +pallas-crypto = "0.30.1" +pallas-primitives = "0.30.1" +pallas-traverse = "0.30.1" [profile.dev.package.insta] opt-level = 3 diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index f3b0782d..ae90feda 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -1,5 +1,7 @@ +pub mod well_known; + use crate::{ - builtins::{self, g1_element, g2_element}, + ast::well_known::VALIDATOR_ELSE, expr::{TypedExpr, UntypedExpr}, line_numbers::LineNumbers, parser::token::{Base, Token}, @@ -25,6 +27,13 @@ pub const ENV_MODULE: &str = "env"; pub const CONFIG_MODULE: &str = "config"; pub const DEFAULT_ENV_MODULE: &str = "default"; +pub const HANDLER_SPEND: &str = "spend"; +pub const HANDLER_MINT: &str = "mint"; +pub const HANDLER_WITHDRAW: &str = "withdraw"; +pub const HANDLER_PUBLISH: &str = "publish"; +pub const HANDLER_VOTE: &str = "vote"; +pub const HANDLER_PROPOSE: &str = "propose"; + pub type TypedModule = Module; pub type UntypedModule = Module<(), UntypedDefinition>; @@ -189,11 +198,7 @@ impl TypedModule { Definition::Validator(v) => { let module_name = self.name.as_str(); - if let Some((k, v)) = v.into_function_definition(module_name, |f, _| Some(f)) { - functions.insert(k, v); - } - - if let Some((k, v)) = v.into_function_definition(module_name, |_, f| f) { + for (k, v) in v.into_function_definitions(module_name) { functions.insert(k, v); } } @@ -237,6 +242,19 @@ fn str_to_keyword(word: &str) -> Option { pub type TypedFunction = Function, TypedExpr, TypedArg>; pub type UntypedFunction = Function<(), UntypedExpr, UntypedArg>; +impl UntypedFunction { + pub fn is_default_fallback(&self) -> bool { + matches!( + &self.arguments[..], + [UntypedArg { + by: ArgBy::ByName(ArgName::Discarded { .. }), + .. + }] + ) && matches!(&self.body, UntypedExpr::ErrorTerm { .. }) + && self.name.as_str() == well_known::VALIDATOR_ELSE + } +} + pub type TypedTest = Function, TypedExpr, TypedArgVia>; pub type UntypedTest = Function<(), UntypedExpr, UntypedArgVia>; @@ -261,6 +279,16 @@ pub struct Function { pub on_test_failure: OnTestFailure, } +impl Function { + pub fn is_spend(&self) -> bool { + self.name == HANDLER_SPEND + } + + pub fn is_mint(&self) -> bool { + self.name == HANDLER_MINT + } +} + impl TypedFunction { pub fn find_node(&self, byte_index: usize) -> Option> { self.arguments @@ -273,6 +301,33 @@ impl TypedFunction { .and_then(|a| a.find_node(byte_index)) }) } + + pub fn has_valid_purpose_name(&self) -> bool { + self.name == HANDLER_SPEND + || self.name == HANDLER_PUBLISH + || self.name == HANDLER_PROPOSE + || self.name == HANDLER_MINT + || self.name == HANDLER_WITHDRAW + || self.name == HANDLER_VOTE + } + + pub fn validator_arity(&self) -> usize { + if self.name == HANDLER_SPEND { + 4 + } else if self.name == HANDLER_MINT + || self.name == HANDLER_WITHDRAW + || self.name == HANDLER_VOTE + || self.name == HANDLER_PUBLISH + || self.name == HANDLER_PROPOSE + { + 3 + } else { + panic!( + "tried to get validator arity of a non-validator function {}", + &self.name + ); + } + } } impl TypedTest { @@ -349,153 +404,37 @@ pub struct FunctionAccessKey { pub function_name: String, } +pub type UntypedDataType = DataType<()>; pub type TypedDataType = DataType>; impl TypedDataType { - pub fn data() -> Self { - DataType { - constructors: vec![], - doc: None, + pub fn known_enum(name: &str, constructors: &[&str]) -> Self { + Self { + name: name.to_string(), + constructors: RecordConstructor::known_enum(constructors), location: Span::empty(), - name: "Data".to_string(), opaque: false, - parameters: vec![], public: true, + parameters: vec![], typed_parameters: vec![], + doc: None, } } - pub fn bool() -> Self { - DataType { - constructors: vec![ - RecordConstructor { - location: Span::empty(), - name: "False".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - RecordConstructor { - location: Span::empty(), - name: "True".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - ], - doc: None, - location: Span::empty(), - name: "Bool".to_string(), - opaque: false, - parameters: vec![], - public: true, - typed_parameters: vec![], - } - } - - pub fn prng() -> Self { - DataType { - constructors: vec![ - RecordConstructor { - location: Span::empty(), - name: "Seeded".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - RecordConstructor { - location: Span::empty(), - name: "Replayed".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - ], - doc: None, - location: Span::empty(), - name: "PRNG".to_string(), - opaque: false, - parameters: vec![], - public: true, - typed_parameters: vec![], - } - } - - pub fn ordering() -> Self { - DataType { - constructors: vec![ - RecordConstructor { - location: Span::empty(), - name: "Less".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - RecordConstructor { - location: Span::empty(), - name: "Equal".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - RecordConstructor { - location: Span::empty(), - name: "Greater".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - ], - doc: None, - location: Span::empty(), - name: "Ordering".to_string(), - opaque: false, - parameters: vec![], - public: true, - typed_parameters: vec![], - } - } - - pub fn option(tipo: Rc) -> Self { - DataType { - constructors: vec![ - RecordConstructor { - location: Span::empty(), - name: "Some".to_string(), - arguments: vec![RecordConstructorArg { - label: None, - annotation: Annotation::Var { - location: Span::empty(), - name: "a".to_string(), - }, - location: Span::empty(), - tipo: tipo.clone(), - doc: None, - }], - doc: None, - sugar: false, - }, - RecordConstructor { - location: Span::empty(), - name: "None".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - ], - doc: None, - location: Span::empty(), - name: "Option".to_string(), - opaque: false, - parameters: vec!["a".to_string()], - public: true, - typed_parameters: vec![tipo], - } + pub fn is_never(&self) -> bool { + self.name == well_known::NEVER + && self.constructors.len() == well_known::NEVER_CONSTRUCTORS.len() + && self.location == Span::empty() + && self + .constructors + .iter() + .zip(well_known::NEVER_CONSTRUCTORS) + .all(|(constructor, name)| { + name == &constructor.name && constructor.arguments.is_empty() + }) } } -pub type UntypedDataType = DataType<()>; - #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct DataType { pub constructors: Vec>, @@ -537,58 +476,260 @@ pub struct ModuleConstant { pub type TypedValidator = Validator, TypedArg, TypedExpr>; pub type UntypedValidator = Validator<(), UntypedArg, UntypedExpr>; +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub enum Purpose { + Spend, + Mint, + Withdraw, + Publish, + Propose, + Vote, +} + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct Validator { pub doc: Option, pub end_position: usize, - pub fun: Function, - pub other_fun: Option>, + pub handlers: Vec>, pub location: Span, + pub name: String, pub params: Vec, + pub fallback: Function, +} + +impl Validator { + pub fn handler_name(validator: &str, handler: &str) -> String { + format!("{}.{}", validator, handler) + } +} + +impl UntypedValidator { + pub fn default_fallback(location: Span) -> UntypedFunction { + Function { + arguments: vec![UntypedArg { + by: ArgBy::ByName(ArgName::Discarded { + name: "_".to_string(), + label: "_".to_string(), + location, + }), + location, + annotation: None, + doc: None, + is_validator_param: false, + }], + body: UntypedExpr::fail(None, location), + doc: None, + location, + end_position: location.end - 1, + name: well_known::VALIDATOR_ELSE.to_string(), + public: true, + return_annotation: Some(Annotation::boolean(location)), + return_type: (), + on_test_failure: OnTestFailure::FailImmediately, + } + } } impl TypedValidator { + pub fn available_handler_names() -> Vec { + vec![ + HANDLER_SPEND.to_string(), + HANDLER_MINT.to_string(), + HANDLER_WITHDRAW.to_string(), + HANDLER_PUBLISH.to_string(), + HANDLER_VOTE.to_string(), + HANDLER_PROPOSE.to_string(), + VALIDATOR_ELSE.to_string(), + ] + } + + // Define a validator wrapper extracting and matching on script purpose for + // users. + pub fn into_script_context_handler(&self) -> TypedExpr { + let var_context = "__context__"; + let var_transaction = "__transaction__"; + let var_redeemer = "__redeemer__"; + let var_purpose = "__purpose__"; + let var_purpose_arg = "__purpose_arg__"; + let var_datum = "__datum__"; + + TypedExpr::sequence(&[ + TypedExpr::let_( + TypedExpr::local_var(var_context, Type::script_context()), + TypedPattern::Constructor { + is_record: false, + location: Span::empty(), + name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(), + arguments: vec![ + CallArg::var(var_transaction), + CallArg::var(var_redeemer), + CallArg::var(var_purpose), + ], + module: None, + constructor: PatternConstructor::Record { + name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(), + field_map: None, + }, + spread_location: None, + tipo: Type::function( + vec![Type::data(), Type::data(), Type::script_purpose()], + Type::data(), + ), + }, + Type::script_context(), + ), + TypedExpr::When { + location: Span::empty(), + tipo: Type::bool(), + subject: TypedExpr::local_var(var_purpose, Type::script_purpose()).into(), + clauses: self + .handlers + .iter() + .map(|handler| { + let datum = if handler.name.as_str() == "spend" { + handler.arguments.first() + } else { + None + }; + + let redeemer = handler + .arguments + .get(if datum.is_some() { 1 } else { 0 }) + .unwrap(); + + let purpose_arg = handler.arguments.iter().nth_back(1).unwrap(); + + let transaction = handler.arguments.last().unwrap(); + + let pattern = match handler.name.as_str() { + "spend" => TypedPattern::spend_purpose(var_purpose_arg, var_datum), + "mint" => TypedPattern::mint_purpose(var_purpose_arg), + "withdraw" => TypedPattern::withdraw_purpose(var_purpose_arg), + "publish" => TypedPattern::publish_purpose(var_purpose_arg), + "propose" => TypedPattern::propose_purpose(var_purpose_arg), + "vote" => TypedPattern::vote_purpose(var_purpose_arg), + purpose => { + unreachable!("unexpected/unknown purpose: {:?}", purpose) + } + }; + + let mut then = vec![]; + + // expect redeemer: tipo = __redeemer__ + then.push(TypedExpr::flexible_expect( + TypedExpr::local_var(var_redeemer, Type::data()), + TypedPattern::var(redeemer.get_variable_name().unwrap_or("_")), + redeemer.tipo.clone(), + )); + + // Cast the datum, if any + if let Some(datum) = datum { + // expect datum: tipo = __datum__ + then.push(TypedExpr::flexible_expect( + TypedExpr::local_var(var_datum, Type::option(Type::data())), + TypedPattern::var(datum.get_variable_name().unwrap_or("_")), + datum.tipo.clone(), + )) + } + + // let purpose_arg = __purpose_arg__ + if let Some(arg_name) = purpose_arg.get_variable_name() { + then.push(TypedExpr::let_( + TypedExpr::local_var(var_purpose_arg, Type::data()), + TypedPattern::var(arg_name), + purpose_arg.tipo.clone(), + )); + } + + // let last_arg_name = __transaction__ + if let Some(arg_name) = transaction.get_variable_name() { + then.push(TypedExpr::let_( + TypedExpr::local_var(var_transaction, Type::data()), + TypedPattern::var(arg_name), + Type::data(), + )); + } + + then.push(handler.body.clone()); + + TypedClause { + location: Span::empty(), + pattern, + then: TypedExpr::Sequence { + location: Span::empty(), + expressions: then, + }, + } + }) + .chain(std::iter::once(&self.fallback).map(|fallback| { + let arg = fallback.arguments.first().unwrap(); + + let then = &[ + TypedExpr::let_( + TypedExpr::local_var(var_context, arg.tipo.clone()), + arg.get_variable_name().map(TypedPattern::var).unwrap_or( + TypedPattern::Discard { + name: var_context.to_string(), + location: Span::empty(), + }, + ), + arg.tipo.clone(), + ), + fallback.body.clone(), + ]; + + TypedClause { + location: Span::empty(), + pattern: TypedPattern::var(var_context), + then: TypedExpr::sequence(then), + } + })) + .collect(), + }, + ]) + } + pub fn find_node(&self, byte_index: usize) -> Option> { self.params .iter() .find_map(|arg| arg.find_node(byte_index)) - .or_else(|| self.fun.find_node(byte_index)) .or_else(|| { - self.other_fun - .as_ref() - .and_then(|f| f.find_node(byte_index)) + self.handlers + .iter() + .find_map(|func| func.find_node(byte_index)) }) + .or_else(|| self.fallback.find_node(byte_index)) } - pub fn into_function_definition<'a, F>( - &'a self, + pub fn into_function_definitions( + &self, module_name: &str, - select: F, - ) -> Option<(FunctionAccessKey, TypedFunction)> - where - F: Fn(&'a TypedFunction, Option<&'a TypedFunction>) -> Option<&'a TypedFunction> + 'a, - { - match select(&self.fun, self.other_fun.as_ref()) { - None => None, - Some(fun) => { - let mut fun = fun.clone(); + ) -> Vec<(FunctionAccessKey, TypedFunction)> { + self.handlers + .iter() + .chain(std::iter::once(&self.fallback)) + .map(|handler| { + let mut handler = handler.clone(); - fun.arguments = self + handler.arguments = self .params .clone() .into_iter() - .chain(fun.arguments) + .chain(handler.arguments) .collect(); - Some(( + ( FunctionAccessKey { module_name: module_name.to_string(), - function_name: fun.name.clone(), + function_name: TypedValidator::handler_name( + self.name.as_str(), + handler.name.as_str(), + ), }, - fun, - )) - } - } + handler, + ) + }) + .collect() } } @@ -731,12 +872,12 @@ pub enum Constant { impl Constant { pub fn tipo(&self) -> Rc { match self { - Constant::Int { .. } => builtins::int(), - Constant::String { .. } => builtins::string(), - Constant::ByteArray { .. } => builtins::byte_array(), + Constant::Int { .. } => Type::int(), + Constant::String { .. } => Type::string(), + Constant::ByteArray { .. } => Type::byte_array(), Constant::CurvePoint { point, .. } => match point.as_ref() { - Curve::Bls12_381(Bls12_381Point::G1(_)) => builtins::g1_element(), - Curve::Bls12_381(Bls12_381Point::G2(_)) => builtins::g2_element(), + Curve::Bls12_381(Bls12_381Point::G1(_)) => Type::g1_element(), + Curve::Bls12_381(Bls12_381Point::G2(_)) => Type::g2_element(), }, } } @@ -776,6 +917,19 @@ impl TypedCallArg { } } +impl CallArg { + pub fn var(name: &str) -> Self { + CallArg { + label: None, + location: Span::empty(), + value: TypedPattern::Var { + location: Span::empty(), + name: name.to_string(), + }, + } + } +} + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct RecordConstructor { pub location: Span, @@ -789,6 +943,19 @@ impl RecordConstructor { pub fn put_doc(&mut self, new_doc: String) { self.doc = Some(new_doc); } + + pub fn known_enum(names: &[&str]) -> Vec> { + names + .iter() + .map(|name| RecordConstructor { + location: Span::empty(), + name: name.to_string(), + arguments: vec![], + doc: None, + sugar: false, + }) + .collect() + } } #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] @@ -889,6 +1056,21 @@ pub struct TypedArg { } impl TypedArg { + pub fn new(name: &str, tipo: Rc) -> Self { + TypedArg { + arg_name: ArgName::Named { + name: name.to_string(), + label: name.to_string(), + location: Span::empty(), + }, + location: Span::empty(), + annotation: None, + doc: None, + is_validator_param: false, + tipo: tipo.clone(), + } + } + pub fn put_doc(&mut self, new_doc: String) { self.doc = Some(new_doc); } @@ -897,6 +1079,10 @@ impl TypedArg { self.arg_name.get_variable_name() } + pub fn get_name(&self) -> String { + self.arg_name.get_name() + } + pub fn is_capture(&self) -> bool { if let ArgName::Named { ref name, location, .. @@ -1103,6 +1289,15 @@ impl Annotation { } } + pub fn option(inner: Annotation) -> Self { + Annotation::Constructor { + name: "Option".to_string(), + module: None, + location: inner.location(), + arguments: vec![inner], + } + } + pub fn is_logically_equal(&self, other: &Annotation) -> bool { match self { Annotation::Constructor { @@ -1279,6 +1474,88 @@ impl BinOp { pub type UntypedPattern = Pattern<(), ()>; pub type TypedPattern = Pattern>; +impl TypedPattern { + pub fn var(name: &str) -> Self { + TypedPattern::Var { + name: name.to_string(), + location: Span::empty(), + } + } + + pub fn constructor(name: &str, arguments: &[CallArg], tipo: Rc) -> Self { + TypedPattern::Constructor { + is_record: false, + location: Span::empty(), + name: name.to_string(), + arguments: arguments.to_vec(), + module: None, + constructor: PatternConstructor::Record { + name: name.to_string(), + field_map: None, + }, + spread_location: None, + tipo: tipo.clone(), + } + } + + pub fn mint_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_MINT, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::byte_array()], Type::script_purpose()), + ) + } + + pub fn spend_purpose(var_purpose_arg: &str, var_datum: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_SPEND, + &[CallArg::var(var_purpose_arg), CallArg::var(var_datum)], + Type::function( + vec![Type::data(), Type::option(Type::data())], + Type::script_purpose(), + ), + ) + } + + pub fn withdraw_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_WITHDRAW, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::data()], Type::script_purpose()), + ) + } + + pub fn publish_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_PUBLISH, + &[ + CallArg::var("__discarded_purpose_ix__"), + CallArg::var(var_purpose_arg), + ], + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ) + } + + pub fn vote_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_VOTE, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::data()], Type::script_purpose()), + ) + } + + pub fn propose_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_PROPOSE, + &[ + CallArg::var("__discarded_purpose_ix__"), + CallArg::var(var_purpose_arg), + ], + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ) + } +} + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub enum Pattern { Int { @@ -1490,8 +1767,8 @@ impl TypedPattern { // TODO: This function definition is weird, see where this is used and how. pub fn tipo(&self, value: &TypedExpr) -> Option> { match self { - Pattern::Int { .. } => Some(builtins::int()), - Pattern::ByteArray { .. } => Some(builtins::byte_array()), + Pattern::Int { .. } => Some(Type::int()), + Pattern::ByteArray { .. } => Some(Type::byte_array()), Pattern::Constructor { tipo, .. } => Some(tipo.clone()), Pattern::Var { .. } | Pattern::Assign { .. } | Pattern::Discard { .. } => { Some(value.tipo()) @@ -1689,8 +1966,8 @@ impl<'de> serde::Deserialize<'de> for Bls12_381Point { impl Bls12_381Point { pub fn tipo(&self) -> Rc { match self { - Bls12_381Point::G1(_) => g1_element(), - Bls12_381Point::G2(_) => g2_element(), + Bls12_381Point::G1(_) => Type::g1_element(), + Bls12_381Point::G2(_) => Type::g2_element(), } } } diff --git a/crates/aiken-lang/src/ast/well_known.rs b/crates/aiken-lang/src/ast/well_known.rs new file mode 100644 index 00000000..a933b5e2 --- /dev/null +++ b/crates/aiken-lang/src/ast/well_known.rs @@ -0,0 +1,352 @@ +use crate::{ + ast::{Annotation, Span}, + tipo::{Type, TypeAliasAnnotation, TypeVar}, +}; +use std::{cell::RefCell, rc::Rc}; + +pub const BOOL: &str = "Bool"; +pub const BOOL_CONSTRUCTORS: &[&str] = &["False", "True"]; +pub const BYTE_ARRAY: &str = "ByteArray"; +pub const DATA: &str = "Data"; +pub const FUZZER: &str = "Fuzzer"; +pub const G1_ELEMENT: &str = "G1Element"; +pub const G2_ELEMENT: &str = "G2Element"; +pub const INT: &str = "Int"; +pub const LIST: &str = "List"; +pub const MILLER_LOOP_RESULT: &str = "MillerLoopResult"; +pub const OPTION: &str = "Option"; +pub const OPTION_CONSTRUCTORS: &[&str] = &["Some", "None"]; +pub const NEVER: &str = "Never"; +pub const NEVER_CONSTRUCTORS: &[&str] = &["__hole", "Never"]; +pub const ORDERING: &str = "Ordering"; +pub const ORDERING_CONSTRUCTORS: &[&str] = &["Less", "Equal", "Greater"]; +pub const PAIR: &str = "Pair"; +pub const PAIRS: &str = "Pairs"; +pub const PRNG: &str = "PRNG"; +pub const PRNG_CONSTRUCTORS: &[&str] = &["Seeded", "Replayed"]; +pub const REDEEMER_WRAPPER: &str = "RedeemerWrapper"; +pub const STRING: &str = "String"; +pub const VOID: &str = "Void"; +pub const VOID_CONSTRUCTORS: &[&str] = &["Void"]; + +pub const SCRIPT_CONTEXT: &str = "__ScriptContext"; +pub const SCRIPT_CONTEXT_CONSTRUCTORS: &[&str] = &["__ScriptContext"]; +pub const SCRIPT_CONTEXT_TRANSACTION: &str = "__Transaction"; +pub const SCRIPT_CONTEXT_REDEEMER: &str = "__Redeemer"; +pub const SCRIPT_CONTEXT_PURPOSE: &str = "__ScriptPurpose"; + +pub const SCRIPT_PURPOSE: &str = "__ScriptPurpose"; +pub const SCRIPT_PURPOSE_MINT: &str = "__Mint"; +pub const SCRIPT_PURPOSE_SPEND: &str = "__Spend"; +pub const SCRIPT_PURPOSE_WITHDRAW: &str = "__Withdraw"; +pub const SCRIPT_PURPOSE_PUBLISH: &str = "__Publish"; +pub const SCRIPT_PURPOSE_VOTE: &str = "__Vote"; +pub const SCRIPT_PURPOSE_PROPOSE: &str = "__Propose"; +pub const SCRIPT_PURPOSE_CONSTRUCTORS: &[&str] = &[ + SCRIPT_PURPOSE_MINT, + SCRIPT_PURPOSE_SPEND, + SCRIPT_PURPOSE_WITHDRAW, + SCRIPT_PURPOSE_PUBLISH, + SCRIPT_PURPOSE_VOTE, + SCRIPT_PURPOSE_PROPOSE, +]; + +pub const VALIDATOR_ELSE: &str = "else"; + +// ---------------------------------------------------------------------------- +// Types + +impl Type { + pub fn data() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + name: DATA.to_string(), + module: "".to_string(), + args: vec![], + alias: None, + }) + } + + pub fn int() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + name: INT.to_string(), + module: "".to_string(), + args: vec![], + alias: None, + }) + } + + pub fn bool() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: BOOL.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn byte_array() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: BYTE_ARRAY.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn g1_element() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + module: "".to_string(), + name: G1_ELEMENT.to_string(), + args: vec![], + alias: None, + }) + } + + pub fn g2_element() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + module: "".to_string(), + name: G2_ELEMENT.to_string(), + args: vec![], + alias: None, + }) + } + + pub fn miller_loop_result() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + module: "".to_string(), + name: MILLER_LOOP_RESULT.to_string(), + args: vec![], + alias: None, + }) + } + + pub fn tuple(elems: Vec>) -> Rc { + Rc::new(Type::Tuple { elems, alias: None }) + } + + pub fn pair(fst: Rc, snd: Rc) -> Rc { + Rc::new(Type::Pair { + fst, + snd, + alias: None, + }) + } + + pub fn script_purpose() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: SCRIPT_PURPOSE.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn script_context() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: SCRIPT_CONTEXT.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn prng() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: PRNG.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn fuzzer(a: Rc) -> Rc { + let prng_annotation = Annotation::Constructor { + location: Span::empty(), + module: None, + name: PRNG.to_string(), + arguments: vec![], + }; + + Rc::new(Type::Fn { + args: vec![Type::prng()], + ret: Type::option(Type::tuple(vec![Type::prng(), a])), + alias: Some( + TypeAliasAnnotation { + alias: FUZZER.to_string(), + parameters: vec!["a".to_string()], + annotation: Annotation::Fn { + location: Span::empty(), + arguments: vec![prng_annotation.clone()], + ret: Annotation::Constructor { + location: Span::empty(), + module: None, + name: OPTION.to_string(), + arguments: vec![Annotation::Tuple { + location: Span::empty(), + elems: vec![ + prng_annotation, + Annotation::Var { + location: Span::empty(), + name: "a".to_string(), + }, + ], + }], + } + .into(), + }, + } + .into(), + ), + }) + } + + pub fn map(k: Rc, v: Rc) -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + module: "".to_string(), + name: LIST.to_string(), + args: vec![Type::pair(k, v)], + alias: Some( + TypeAliasAnnotation { + alias: PAIRS.to_string(), + parameters: vec!["k".to_string(), "v".to_string()], + annotation: Annotation::Constructor { + location: Span::empty(), + module: None, + name: LIST.to_string(), + arguments: vec![Annotation::Pair { + location: Span::empty(), + fst: Box::new(Annotation::Var { + location: Span::empty(), + name: "k".to_string(), + }), + snd: Box::new(Annotation::Var { + location: Span::empty(), + name: "v".to_string(), + }), + }], + }, + } + .into(), + ), + }) + } + + pub fn list(t: Rc) -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: t.contains_opaque(), + name: LIST.to_string(), + module: "".to_string(), + args: vec![t], + alias: None, + }) + } + + pub fn string() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: STRING.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn void() -> Rc { + Rc::new(Type::App { + args: vec![], + public: true, + contains_opaque: false, + name: VOID.to_string(), + module: "".to_string(), + alias: None, + }) + } + + pub fn option(a: Rc) -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: a.contains_opaque(), + name: OPTION.to_string(), + module: "".to_string(), + args: vec![a], + alias: None, + }) + } + + pub fn never() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + name: NEVER.to_string(), + module: "".to_string(), + args: vec![], + alias: None, + }) + } + + pub fn ordering() -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + name: ORDERING.to_string(), + module: "".to_string(), + args: vec![], + alias: None, + }) + } + + pub fn function(args: Vec>, ret: Rc) -> Rc { + Rc::new(Type::Fn { + ret, + args, + alias: None, + }) + } + + pub fn generic_var(id: u64) -> Rc { + let tipo = Rc::new(RefCell::new(TypeVar::Generic { id })); + + Rc::new(Type::Var { tipo, alias: None }) + } + + pub fn unbound_var(id: u64) -> Rc { + let tipo = Rc::new(RefCell::new(TypeVar::Unbound { id })); + + Rc::new(Type::Var { tipo, alias: None }) + } + + pub fn wrapped_redeemer(redeemer: Rc) -> Rc { + Rc::new(Type::App { + public: true, + contains_opaque: false, + module: "".to_string(), + name: REDEEMER_WRAPPER.to_string(), + args: vec![redeemer], + alias: None, + }) + } +} diff --git a/crates/aiken-lang/src/builtins.rs b/crates/aiken-lang/src/builtins.rs index 3d9858cf..592b41be 100644 --- a/crates/aiken-lang/src/builtins.rs +++ b/crates/aiken-lang/src/builtins.rs @@ -1,42 +1,25 @@ use crate::{ aiken_fn, ast::{ - Annotation, ArgName, CallArg, DataTypeKey, Function, FunctionAccessKey, ModuleKind, - OnTestFailure, Span, TypedArg, TypedDataType, TypedFunction, UnOp, + well_known, Annotation, ArgName, CallArg, DataType, DataTypeKey, Function, + FunctionAccessKey, ModuleKind, OnTestFailure, RecordConstructor, RecordConstructorArg, + Span, TypedArg, TypedDataType, TypedFunction, UnOp, }, expr::TypedExpr, tipo::{ - fields::FieldMap, Type, TypeAliasAnnotation, TypeConstructor, TypeInfo, TypeVar, - ValueConstructor, ValueConstructorVariant, + fields::FieldMap, Type, TypeConstructor, TypeInfo, ValueConstructor, + ValueConstructorVariant, }, IdGenerator, }; use indexmap::IndexMap; -use std::{cell::RefCell, collections::HashMap, rc::Rc}; +use std::{collections::HashMap, rc::Rc}; use strum::IntoEnumIterator; use uplc::builtins::DefaultFunction; pub const PRELUDE: &str = "aiken"; pub const BUILTIN: &str = "aiken/builtin"; -pub const BYTE_ARRAY: &str = "ByteArray"; -pub const BOOL: &str = "Bool"; -pub const INT: &str = "Int"; -pub const DATA: &str = "Data"; -pub const LIST: &str = "List"; -pub const PAIR: &str = "Pair"; -pub const PAIRS: &str = "Pairs"; -pub const VOID: &str = "Void"; -pub const G1_ELEMENT: &str = "G1Element"; -pub const G2_ELEMENT: &str = "G2Element"; -pub const MILLER_LOOP_RESULT: &str = "MillerLoopResult"; -pub const STRING: &str = "String"; -pub const OPTION: &str = "Option"; -pub const ORDERING: &str = "Ordering"; -pub const REDEEMER_WRAPPER: &str = "RedeemerWrapper"; -pub const PRNG: &str = "PRNG"; -pub const FUZZER: &str = "Fuzzer"; - /// Build a prelude that can be injected /// into a compiler pipeline pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { @@ -51,196 +34,214 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { annotations: HashMap::new(), }; - // Int - prelude.types.insert( - INT.to_string(), - TypeConstructor { - parameters: vec![], - tipo: int(), - location: Span::empty(), - module: "".to_string(), - public: true, - }, - ); - // Data prelude.types.insert( - DATA.to_string(), - TypeConstructor { - parameters: vec![], - tipo: data(), - location: Span::empty(), - module: "".to_string(), - public: true, - }, + well_known::DATA.to_string(), + TypeConstructor::primitive(Type::data()), + ); + + // Int + prelude.types.insert( + well_known::INT.to_string(), + TypeConstructor::primitive(Type::int()), ); // ByteArray prelude.types.insert( - BYTE_ARRAY.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: byte_array(), - module: "".to_string(), - public: true, - }, + well_known::BYTE_ARRAY.to_string(), + TypeConstructor::primitive(Type::byte_array()), ); // Bool - prelude.types_constructors.insert( - BOOL.to_string(), - vec!["False".to_string(), "True".to_string()], - ); - - prelude.values.insert( - "False".to_string(), - ValueConstructor::public( - bool(), - ValueConstructorVariant::Record { - module: "".into(), - name: "False".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 2, - }, - ), - ); - - prelude.values.insert( - "True".to_string(), - ValueConstructor::public( - bool(), - ValueConstructorVariant::Record { - module: "".into(), - name: "True".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 2, - }, - ), - ); - prelude.types.insert( - BOOL.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: bool(), - module: "".to_string(), - public: true, - }, + well_known::BOOL.to_string(), + TypeConstructor::primitive(Type::bool()), + ); + prelude.types_constructors.insert( + well_known::BOOL.to_string(), + ValueConstructor::known_enum( + &mut prelude.values, + Type::bool(), + well_known::BOOL_CONSTRUCTORS, + ), ); // G1Element prelude.types.insert( - G1_ELEMENT.to_string(), - TypeConstructor { - parameters: vec![], - tipo: g1_element(), - location: Span::empty(), - module: "".to_string(), - public: true, - }, + well_known::G1_ELEMENT.to_string(), + TypeConstructor::primitive(Type::g1_element()), ); // G2Element prelude.types.insert( - G2_ELEMENT.to_string(), - TypeConstructor { - parameters: vec![], - tipo: g2_element(), - location: Span::empty(), - module: "".to_string(), - public: true, - }, + well_known::G2_ELEMENT.to_string(), + TypeConstructor::primitive(Type::g2_element()), ); // MillerLoopResult prelude.types.insert( - MILLER_LOOP_RESULT.to_string(), - TypeConstructor { - parameters: vec![], - tipo: miller_loop_result(), - location: Span::empty(), - module: "".to_string(), - public: true, - }, + well_known::MILLER_LOOP_RESULT.to_string(), + TypeConstructor::primitive(Type::miller_loop_result()), ); // Ordering + prelude.types.insert( + well_known::ORDERING.to_string(), + TypeConstructor::primitive(Type::ordering()), + ); prelude.types_constructors.insert( - ORDERING.to_string(), + well_known::ORDERING.to_string(), + ValueConstructor::known_enum( + &mut prelude.values, + Type::ordering(), + well_known::ORDERING_CONSTRUCTORS, + ), + ); + + // String + prelude.types.insert( + well_known::STRING.to_string(), + TypeConstructor::primitive(Type::string()), + ); + + // Void + prelude.types.insert( + well_known::VOID.to_string(), + TypeConstructor::primitive(Type::void()), + ); + prelude.types_constructors.insert( + well_known::VOID.to_string(), + ValueConstructor::known_enum( + &mut prelude.values, + Type::void(), + well_known::VOID_CONSTRUCTORS, + ), + ); + + // List(a) + prelude.types.insert( + well_known::LIST.to_string(), + TypeConstructor::primitive(Type::list(Type::generic_var(id_gen.next()))), + ); + + // Pair(a, b) + prelude.types.insert( + well_known::PAIR.to_string(), + TypeConstructor::primitive(Type::pair( + Type::generic_var(id_gen.next()), + Type::generic_var(id_gen.next()), + )), + ); + prelude.types_constructors.insert( + well_known::PAIR.to_string(), + vec![well_known::PAIR.to_string()], + ); + + // Pairs = List> + prelude.types.insert( + well_known::PAIRS.to_string(), + TypeConstructor::primitive(Type::map( + Type::generic_var(id_gen.next()), + Type::generic_var(id_gen.next()), + )), + ); + + // Option(value) + let option_value = Type::generic_var(id_gen.next()); + prelude.types.insert( + well_known::OPTION.to_string(), + TypeConstructor::primitive(Type::option(option_value.clone())), + ); + let some_type = Type::function( + vec![option_value.clone()], + Type::option(option_value.clone()), + ); + let none_type = Type::option(option_value); + prelude.types_constructors.insert( + well_known::OPTION.to_string(), + ValueConstructor::known_adt( + &mut prelude.values, + &[ + (well_known::OPTION_CONSTRUCTORS[0], some_type), + (well_known::OPTION_CONSTRUCTORS[1], none_type), + ], + ), + ); + + // Never + prelude.types.insert( + well_known::NEVER.to_string(), + TypeConstructor::primitive(Type::never()), + ); + prelude.types_constructors.insert( + well_known::NEVER.to_string(), + ValueConstructor::known_adt( + &mut prelude.values, + &[(well_known::NEVER_CONSTRUCTORS[1], Type::never())], + ), + ); + + // Cardano ScriptContext + prelude.types.insert( + well_known::SCRIPT_CONTEXT.to_string(), + TypeConstructor::primitive(Type::script_context()), + ); + prelude.types_constructors.insert( + well_known::SCRIPT_CONTEXT.to_string(), vec![ - "Less".to_string(), - "Equal".to_string(), - "Greater".to_string(), + well_known::SCRIPT_CONTEXT_TRANSACTION.to_string(), + well_known::SCRIPT_CONTEXT_REDEEMER.to_string(), + well_known::SCRIPT_CONTEXT_PURPOSE.to_string(), ], ); - prelude.values.insert( - "Less".to_string(), - ValueConstructor::public( - ordering(), - ValueConstructorVariant::Record { - module: "".into(), - name: "Less".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 3, - }, - ), - ); - - prelude.values.insert( - "Equal".to_string(), - ValueConstructor::public( - ordering(), - ValueConstructorVariant::Record { - module: "".into(), - name: "Equal".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 3, - }, - ), - ); - - prelude.values.insert( - "Greater".to_string(), - ValueConstructor::public( - ordering(), - ValueConstructorVariant::Record { - module: "".into(), - name: "Greater".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 3, - }, - ), - ); - + // Cardano ScriptPurpose prelude.types.insert( - ORDERING.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: ordering(), - module: "".to_string(), - public: true, - }, + well_known::SCRIPT_PURPOSE.to_string(), + TypeConstructor::primitive(Type::script_purpose()), + ); + + prelude.types_constructors.insert( + well_known::SCRIPT_PURPOSE.to_string(), + ValueConstructor::known_adt( + &mut prelude.values, + &[ + ( + well_known::SCRIPT_PURPOSE_MINT, + Type::function(vec![Type::data()], Type::script_purpose()), + ), + ( + well_known::SCRIPT_PURPOSE_SPEND, + Type::function( + vec![Type::data(), Type::option(Type::data())], + Type::script_purpose(), + ), + ), + ( + well_known::SCRIPT_PURPOSE_WITHDRAW, + Type::function(vec![Type::data()], Type::script_purpose()), + ), + ( + well_known::SCRIPT_PURPOSE_PUBLISH, + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ), + ( + well_known::SCRIPT_PURPOSE_VOTE, + Type::function(vec![Type::data()], Type::script_purpose()), + ), + ( + well_known::SCRIPT_PURPOSE_PROPOSE, + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ), + ], + ), ); // not prelude.values.insert( "not".to_string(), ValueConstructor::public( - function(vec![bool()], bool()), + Type::function(vec![Type::bool()], Type::bool()), ValueConstructorVariant::ModuleFn { name: "not".to_string(), field_map: None, @@ -253,11 +254,11 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { ); // identity - let identity_var = generic_var(id_gen.next()); + let identity_var = Type::generic_var(id_gen.next()); prelude.values.insert( "identity".to_string(), ValueConstructor::public( - function(vec![identity_var.clone()], identity_var), + Type::function(vec![identity_var.clone()], identity_var), ValueConstructorVariant::ModuleFn { name: "identity".to_string(), field_map: None, @@ -270,20 +271,20 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { ); // enumerate - let enumerate_a = generic_var(id_gen.next()); - let enumerate_b = generic_var(id_gen.next()); + let enumerate_a = Type::generic_var(id_gen.next()); + let enumerate_b = Type::generic_var(id_gen.next()); prelude.values.insert( "enumerate".to_string(), ValueConstructor::public( - function( + Type::function( vec![ - list(enumerate_a.clone()), + Type::list(enumerate_a.clone()), enumerate_b.clone(), - function( + Type::function( vec![enumerate_a.clone(), enumerate_b.clone()], enumerate_b.clone(), ), - function( + Type::function( vec![enumerate_a.clone(), enumerate_b.clone()], enumerate_b.clone(), ), @@ -305,7 +306,10 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "encode_base16".to_string(), ValueConstructor::public( - function(vec![byte_array(), int(), byte_array()], byte_array()), + Type::function( + vec![Type::byte_array(), Type::int(), Type::byte_array()], + Type::byte_array(), + ), ValueConstructorVariant::ModuleFn { name: "encode_base16".to_string(), field_map: None, @@ -321,7 +325,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "from_int".to_string(), ValueConstructor::public( - function(vec![int(), byte_array()], byte_array()), + Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array()), ValueConstructorVariant::ModuleFn { name: "from_int".to_string(), field_map: None, @@ -337,7 +341,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "do_from_int".to_string(), ValueConstructor::public( - function(vec![int(), byte_array()], byte_array()), + Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array()), ValueConstructorVariant::ModuleFn { name: "do_from_int".to_string(), field_map: None, @@ -353,7 +357,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "diagnostic".to_string(), ValueConstructor::public( - function(vec![data(), byte_array()], byte_array()), + Type::function(vec![Type::data(), Type::byte_array()], Type::byte_array()), ValueConstructorVariant::ModuleFn { name: "diagnostic".to_string(), field_map: None, @@ -366,12 +370,12 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { ); // always - let always_a_var = generic_var(id_gen.next()); - let always_b_var = generic_var(id_gen.next()); + let always_a_var = Type::generic_var(id_gen.next()); + let always_b_var = Type::generic_var(id_gen.next()); prelude.values.insert( "always".to_string(), ValueConstructor::public( - function(vec![always_a_var.clone(), always_b_var], always_a_var), + Type::function(vec![always_a_var.clone(), always_b_var], always_a_var), ValueConstructorVariant::ModuleFn { name: "always".to_string(), field_map: None, @@ -384,20 +388,21 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { ); // flip - let flip_a_var = generic_var(id_gen.next()); - let flip_b_var = generic_var(id_gen.next()); - let flip_c_var = generic_var(id_gen.next()); + let flip_a_var = Type::generic_var(id_gen.next()); + let flip_b_var = Type::generic_var(id_gen.next()); + let flip_c_var = Type::generic_var(id_gen.next()); - let input_type = function( + let input_type = Type::function( vec![flip_a_var.clone(), flip_b_var.clone()], flip_c_var.clone(), ); - let return_type = function(vec![flip_b_var, flip_a_var], flip_c_var); + + let return_type = Type::function(vec![flip_b_var, flip_a_var], flip_c_var); prelude.values.insert( "flip".to_string(), ValueConstructor::public( - function(vec![input_type], return_type), + Type::function(vec![input_type], return_type), ValueConstructorVariant::ModuleFn { name: "flip".to_string(), field_map: None, @@ -409,129 +414,6 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { ), ); - // List(a) - let list_parameter = generic_var(id_gen.next()); - prelude.types.insert( - LIST.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![list_parameter.clone()], - tipo: list(list_parameter), - module: "".to_string(), - public: true, - }, - ); - - // Pair(a, b) - let fst_parameter = generic_var(id_gen.next()); - let snd_parameter = generic_var(id_gen.next()); - prelude.types.insert( - PAIR.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![fst_parameter.clone(), snd_parameter.clone()], - tipo: pair(fst_parameter.clone(), snd_parameter.clone()), - module: "".to_string(), - public: true, - }, - ); - - prelude - .types_constructors - .insert(PAIR.to_string(), vec![PAIR.to_string()]); - - // String - prelude.types.insert( - STRING.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: string(), - module: "".to_string(), - public: true, - }, - ); - - // Void - prelude - .types_constructors - .insert(VOID.to_string(), vec![VOID.to_string()]); - - prelude.values.insert( - VOID.to_string(), - ValueConstructor::public( - void(), - ValueConstructorVariant::Record { - module: "".into(), - name: VOID.to_string(), - arity: 0, - field_map: None::, - location: Span::empty(), - constructors_count: 1, - }, - ), - ); - - prelude.types.insert( - VOID.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: void(), - module: "".to_string(), - public: true, - }, - ); - - // Option(value) - let option_value = generic_var(id_gen.next()); - - prelude.types.insert( - OPTION.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![option_value.clone()], - tipo: option(option_value.clone()), - module: "".to_string(), - public: true, - }, - ); - - prelude.types_constructors.insert( - OPTION.to_string(), - vec!["Some".to_string(), "None".to_string()], - ); - - prelude.values.insert( - "Some".to_string(), - ValueConstructor::public( - function(vec![option_value.clone()], option(option_value.clone())), - ValueConstructorVariant::Record { - module: "".into(), - name: "Some".to_string(), - field_map: None::, - arity: 1, - location: Span::empty(), - constructors_count: 2, - }, - ), - ); - - prelude.values.insert( - "None".to_string(), - ValueConstructor::public( - option(option_value), - ValueConstructorVariant::Record { - module: "".into(), - name: "None".to_string(), - field_map: None::, - arity: 0, - location: Span::empty(), - constructors_count: 2, - }, - ), - ); - // PRNG // // pub type PRNG { @@ -539,18 +421,12 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { // Replayed { cursor: Int, choices: ByteArray } // } prelude.types.insert( - PRNG.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![], - tipo: prng(), - module: "".to_string(), - public: true, - }, + well_known::PRNG.to_string(), + TypeConstructor::primitive(Type::prng()), ); prelude.types_constructors.insert( - PRNG.to_string(), + well_known::PRNG.to_string(), vec!["Seeded".to_string(), "Replayed".to_string()], ); @@ -560,7 +436,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "Seeded".to_string(), ValueConstructor::public( - function(vec![byte_array(), byte_array()], prng()), + Type::function(vec![Type::byte_array(), Type::byte_array()], Type::prng()), ValueConstructorVariant::Record { module: "".into(), name: "Seeded".to_string(), @@ -582,7 +458,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { prelude.values.insert( "Replayed".to_string(), ValueConstructor::public( - function(vec![int(), byte_array()], prng()), + Type::function(vec![Type::int(), Type::byte_array()], Type::prng()), ValueConstructorVariant::Record { module: "".into(), name: "Replayed".to_string(), @@ -602,29 +478,13 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { // // pub type Fuzzer = // fn(PRNG) -> Option<(PRNG, a)> - let fuzzer_value = generic_var(id_gen.next()); + let fuzzer_value = Type::generic_var(id_gen.next()); prelude.types.insert( - FUZZER.to_string(), + well_known::FUZZER.to_string(), TypeConstructor { location: Span::empty(), parameters: vec![fuzzer_value.clone()], - tipo: fuzzer(fuzzer_value), - module: "".to_string(), - public: true, - }, - ); - - // Map - // - // pub type Map = List> - let alist_key = generic_var(id_gen.next()); - let alist_value = generic_var(id_gen.next()); - prelude.types.insert( - PAIRS.to_string(), - TypeConstructor { - location: Span::empty(), - parameters: vec![alist_key.clone(), alist_value.clone()], - tipo: map(alist_key, alist_value), + tipo: Type::fuzzer(fuzzer_value), module: "".to_string(), public: true, }, @@ -663,47 +523,52 @@ pub fn from_default_function(builtin: DefaultFunction, id_gen: &IdGenerator) -> | DefaultFunction::QuotientInteger | DefaultFunction::RemainderInteger | DefaultFunction::ModInteger => { - let tipo = function(vec![int(), int()], int()); - + let tipo = Type::function(vec![Type::int(), Type::int()], Type::int()); (tipo, 2) } DefaultFunction::EqualsInteger | DefaultFunction::LessThanInteger | DefaultFunction::LessThanEqualsInteger => { - let tipo = function(vec![int(), int()], bool()); + let tipo = Type::function(vec![Type::int(), Type::int()], Type::bool()); (tipo, 2) } DefaultFunction::AppendByteString => { - let tipo = function(vec![byte_array(), byte_array()], byte_array()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array()], + Type::byte_array(), + ); (tipo, 2) } DefaultFunction::ConsByteString => { - let tipo = function(vec![int(), byte_array()], byte_array()); + let tipo = Type::function(vec![Type::int(), Type::byte_array()], Type::byte_array()); (tipo, 2) } DefaultFunction::SliceByteString => { - let tipo = function(vec![int(), int(), byte_array()], byte_array()); + let tipo = Type::function( + vec![Type::int(), Type::int(), Type::byte_array()], + Type::byte_array(), + ); (tipo, 3) } DefaultFunction::LengthOfByteString => { - let tipo = function(vec![byte_array()], int()); + let tipo = Type::function(vec![Type::byte_array()], Type::int()); (tipo, 1) } DefaultFunction::IndexByteString => { - let tipo = function(vec![byte_array(), int()], int()); + let tipo = Type::function(vec![Type::byte_array(), Type::int()], Type::int()); (tipo, 2) } DefaultFunction::EqualsByteString | DefaultFunction::LessThanByteString | DefaultFunction::LessThanEqualsByteString => { - let tipo = function(vec![byte_array(), byte_array()], bool()); + let tipo = Type::function(vec![Type::byte_array(), Type::byte_array()], Type::bool()); (tipo, 2) } @@ -712,141 +577,159 @@ pub fn from_default_function(builtin: DefaultFunction, id_gen: &IdGenerator) -> | DefaultFunction::Blake2b_224 | DefaultFunction::Blake2b_256 | DefaultFunction::Keccak_256 => { - let tipo = function(vec![byte_array()], byte_array()); + let tipo = Type::function(vec![Type::byte_array()], Type::byte_array()); (tipo, 1) } DefaultFunction::VerifyEd25519Signature => { - let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array(), Type::byte_array()], + Type::bool(), + ); (tipo, 3) } DefaultFunction::VerifyEcdsaSecp256k1Signature => { - let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array(), Type::byte_array()], + Type::bool(), + ); (tipo, 3) } DefaultFunction::VerifySchnorrSecp256k1Signature => { - let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array(), Type::byte_array()], + Type::bool(), + ); (tipo, 3) } DefaultFunction::AppendString => { - let tipo = function(vec![string(), string()], string()); + let tipo = Type::function(vec![Type::string(), Type::string()], Type::string()); (tipo, 2) } DefaultFunction::EqualsString => { - let tipo = function(vec![string(), string()], bool()); + let tipo = Type::function(vec![Type::string(), Type::string()], Type::bool()); (tipo, 2) } DefaultFunction::EncodeUtf8 => { - let tipo = function(vec![string()], byte_array()); + let tipo = Type::function(vec![Type::string()], Type::byte_array()); (tipo, 1) } DefaultFunction::DecodeUtf8 => { - let tipo = function(vec![byte_array()], string()); + let tipo = Type::function(vec![Type::byte_array()], Type::string()); (tipo, 1) } DefaultFunction::IfThenElse => { - let ret = generic_var(id_gen.next()); + let ret = Type::generic_var(id_gen.next()); - let tipo = function(vec![bool(), ret.clone(), ret.clone()], ret); + let tipo = Type::function(vec![Type::bool(), ret.clone(), ret.clone()], ret); (tipo, 3) } DefaultFunction::HeadList => { - let ret = generic_var(id_gen.next()); + let ret = Type::generic_var(id_gen.next()); - let tipo = function(vec![list(ret.clone())], ret); + let tipo = Type::function(vec![Type::list(ret.clone())], ret); (tipo, 1) } DefaultFunction::TailList => { - let ret = list(generic_var(id_gen.next())); + let ret = Type::list(Type::generic_var(id_gen.next())); - let tipo = function(vec![ret.clone()], ret); + let tipo = Type::function(vec![ret.clone()], ret); (tipo, 1) } DefaultFunction::NullList => { - let ret = list(generic_var(id_gen.next())); + let ret = Type::list(Type::generic_var(id_gen.next())); - let tipo = function(vec![ret], bool()); + let tipo = Type::function(vec![ret], Type::bool()); (tipo, 1) } DefaultFunction::ConstrData => { - let tipo = function(vec![int(), list(data())], data()); + let tipo = Type::function(vec![Type::int(), Type::list(Type::data())], Type::data()); (tipo, 2) } DefaultFunction::MapData => { - let tipo = function(vec![list(pair(data(), data()))], data()); + let tipo = Type::function( + vec![Type::list(Type::pair(Type::data(), Type::data()))], + Type::data(), + ); (tipo, 1) } DefaultFunction::ListData => { - let tipo = function(vec![list(data())], data()); + let tipo = Type::function(vec![Type::list(Type::data())], Type::data()); (tipo, 1) } DefaultFunction::IData => { - let tipo = function(vec![int()], data()); + let tipo = Type::function(vec![Type::int()], Type::data()); (tipo, 1) } DefaultFunction::BData => { - let tipo = function(vec![byte_array()], data()); + let tipo = Type::function(vec![Type::byte_array()], Type::data()); (tipo, 1) } DefaultFunction::UnConstrData => { - let tipo = function(vec![data()], pair(int(), list(data()))); + let tipo = Type::function( + vec![Type::data()], + Type::pair(Type::int(), Type::list(Type::data())), + ); (tipo, 1) } DefaultFunction::UnMapData => { - let tipo = function(vec![data()], list(pair(data(), data()))); + let tipo = Type::function( + vec![Type::data()], + Type::list(Type::pair(Type::data(), Type::data())), + ); (tipo, 1) } DefaultFunction::UnListData => { - let tipo = function(vec![data()], list(data())); + let tipo = Type::function(vec![Type::data()], Type::list(Type::data())); (tipo, 1) } DefaultFunction::UnIData => { - let tipo = function(vec![data()], int()); + let tipo = Type::function(vec![Type::data()], Type::int()); (tipo, 1) } DefaultFunction::UnBData => { - let tipo = function(vec![data()], byte_array()); + let tipo = Type::function(vec![Type::data()], Type::byte_array()); (tipo, 1) } DefaultFunction::EqualsData => { - let tipo = function(vec![data(), data()], bool()); + let tipo = Type::function(vec![Type::data(), Type::data()], Type::bool()); (tipo, 2) } DefaultFunction::SerialiseData => { - let tipo = function(vec![data()], byte_array()); + let tipo = Type::function(vec![Type::data()], Type::byte_array()); (tipo, 1) } DefaultFunction::ChooseData => { - let a = generic_var(id_gen.next()); - let tipo = function( + let a = Type::generic_var(id_gen.next()); + let tipo = Type::function( vec![ - data(), + Type::data(), a.clone(), a.clone(), a.clone(), @@ -858,146 +741,170 @@ pub fn from_default_function(builtin: DefaultFunction, id_gen: &IdGenerator) -> (tipo, 6) } DefaultFunction::MkPairData => { - let tipo = function(vec![data(), data()], pair(data(), data())); + let tipo = Type::function( + vec![Type::data(), Type::data()], + Type::pair(Type::data(), Type::data()), + ); (tipo, 2) } DefaultFunction::MkNilData => { - let tipo = function(vec![], list(data())); + let tipo = Type::function(vec![], Type::list(Type::data())); (tipo, 0) } DefaultFunction::MkNilPairData => { - let tipo = function(vec![], list(pair(data(), data()))); + let tipo = Type::function(vec![], Type::list(Type::pair(Type::data(), Type::data()))); (tipo, 0) } DefaultFunction::ChooseUnit => { - let a = generic_var(id_gen.next()); - let tipo = function(vec![data(), a.clone()], a); + let a = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![Type::data(), a.clone()], a); (tipo, 2) } DefaultFunction::Trace => { - let a = generic_var(id_gen.next()); - let tipo = function(vec![string(), a.clone()], a); + let a = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![Type::string(), a.clone()], a); (tipo, 2) } DefaultFunction::FstPair => { - let a = generic_var(id_gen.next()); - let b = generic_var(id_gen.next()); - let tipo = function(vec![pair(a.clone(), b)], a); + let a = Type::generic_var(id_gen.next()); + let b = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![Type::pair(a.clone(), b)], a); (tipo, 1) } DefaultFunction::SndPair => { - let a = generic_var(id_gen.next()); - let b = generic_var(id_gen.next()); - let tipo = function(vec![pair(a, b.clone())], b); + let a = Type::generic_var(id_gen.next()); + let b = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![Type::pair(a, b.clone())], b); (tipo, 1) } DefaultFunction::ChooseList => { - let a = generic_var(id_gen.next()); - let b = generic_var(id_gen.next()); - let tipo = function(vec![list(a), b.clone(), b.clone()], b); + let a = Type::generic_var(id_gen.next()); + let b = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![Type::list(a), b.clone(), b.clone()], b); (tipo, 3) } DefaultFunction::MkCons => { - let a = generic_var(id_gen.next()); - let tipo = function(vec![a.clone(), list(a.clone())], list(a)); + let a = Type::generic_var(id_gen.next()); + let tipo = Type::function(vec![a.clone(), Type::list(a.clone())], Type::list(a)); (tipo, 2) } DefaultFunction::Bls12_381_G1_Add => { - let tipo = function(vec![g1_element(), g1_element()], g1_element()); + let tipo = Type::function( + vec![Type::g1_element(), Type::g1_element()], + Type::g1_element(), + ); (tipo, 2) } DefaultFunction::Bls12_381_G1_Equal => { - let tipo = function(vec![g1_element(), g1_element()], bool()); + let tipo = Type::function(vec![Type::g1_element(), Type::g1_element()], Type::bool()); (tipo, 2) } DefaultFunction::Bls12_381_G1_Neg => { - let tipo = function(vec![g1_element()], g1_element()); + let tipo = Type::function(vec![Type::g1_element()], Type::g1_element()); (tipo, 1) } DefaultFunction::Bls12_381_G1_ScalarMul => { - let tipo = function(vec![int(), g1_element()], g1_element()); + let tipo = Type::function(vec![Type::int(), Type::g1_element()], Type::g1_element()); (tipo, 2) } DefaultFunction::Bls12_381_G1_Compress => { - let tipo = function(vec![g1_element()], byte_array()); + let tipo = Type::function(vec![Type::g1_element()], Type::byte_array()); (tipo, 1) } DefaultFunction::Bls12_381_G1_Uncompress => { - let tipo = function(vec![byte_array()], g1_element()); + let tipo = Type::function(vec![Type::byte_array()], Type::g1_element()); (tipo, 1) } DefaultFunction::Bls12_381_G1_HashToGroup => { - let tipo = function(vec![byte_array(), byte_array()], g1_element()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array()], + Type::g1_element(), + ); (tipo, 2) } DefaultFunction::Bls12_381_G2_Add => { - let tipo = function(vec![g2_element(), g2_element()], g2_element()); + let tipo = Type::function( + vec![Type::g2_element(), Type::g2_element()], + Type::g2_element(), + ); (tipo, 2) } DefaultFunction::Bls12_381_G2_Equal => { - let tipo = function(vec![g2_element(), g2_element()], bool()); + let tipo = Type::function(vec![Type::g2_element(), Type::g2_element()], Type::bool()); (tipo, 2) } DefaultFunction::Bls12_381_G2_Neg => { - let tipo = function(vec![g2_element()], g2_element()); + let tipo = Type::function(vec![Type::g2_element()], Type::g2_element()); (tipo, 1) } DefaultFunction::Bls12_381_G2_ScalarMul => { - let tipo = function(vec![int(), g2_element()], g2_element()); + let tipo = Type::function(vec![Type::int(), Type::g2_element()], Type::g2_element()); (tipo, 2) } DefaultFunction::Bls12_381_G2_Compress => { - let tipo = function(vec![g2_element()], byte_array()); + let tipo = Type::function(vec![Type::g2_element()], Type::byte_array()); (tipo, 1) } DefaultFunction::Bls12_381_G2_Uncompress => { - let tipo = function(vec![byte_array()], g2_element()); + let tipo = Type::function(vec![Type::byte_array()], Type::g2_element()); (tipo, 1) } DefaultFunction::Bls12_381_G2_HashToGroup => { - let tipo = function(vec![byte_array(), byte_array()], g2_element()); + let tipo = Type::function( + vec![Type::byte_array(), Type::byte_array()], + Type::g2_element(), + ); (tipo, 2) } DefaultFunction::Bls12_381_MillerLoop => { - let tipo = function(vec![g1_element(), g2_element()], miller_loop_result()); + let tipo = Type::function( + vec![Type::g1_element(), Type::g2_element()], + Type::miller_loop_result(), + ); (tipo, 2) } DefaultFunction::Bls12_381_MulMlResult => { - let tipo = function( - vec![miller_loop_result(), miller_loop_result()], - miller_loop_result(), + let tipo = Type::function( + vec![Type::miller_loop_result(), Type::miller_loop_result()], + Type::miller_loop_result(), ); (tipo, 2) } DefaultFunction::Bls12_381_FinalVerify => { - let tipo = function(vec![miller_loop_result(), miller_loop_result()], bool()); + let tipo = Type::function( + vec![Type::miller_loop_result(), Type::miller_loop_result()], + Type::bool(), + ); (tipo, 2) } DefaultFunction::IntegerToByteString => { - let tipo = function(vec![bool(), int(), int()], byte_array()); + let tipo = Type::function( + vec![Type::bool(), Type::int(), Type::int()], + Type::byte_array(), + ); (tipo, 3) } DefaultFunction::ByteStringToInteger => { - let tipo = function(vec![bool(), byte_array()], int()); + let tipo = Type::function(vec![Type::bool(), Type::byte_array()], Type::int()); (tipo, 2) } @@ -1042,7 +949,7 @@ pub fn prelude_functions( doc: None, location: Span::empty(), annotation: None, - tipo: bool(), + tipo: Type::bool(), }], on_test_failure: OnTestFailure::FailImmediately, doc: Some( @@ -1056,17 +963,17 @@ pub fn prelude_functions( name: "not".to_string(), public: true, return_annotation: None, - return_type: bool(), + return_type: Type::bool(), end_position: 0, body: TypedExpr::UnOp { location: Span::empty(), - tipo: bool(), + tipo: Type::bool(), op: UnOp::Not, value: Box::new(TypedExpr::Var { location: Span::empty(), constructor: ValueConstructor { public: true, - tipo: bool(), + tipo: Type::bool(), variant: ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -1081,7 +988,7 @@ pub fn prelude_functions( // pub fn identity(a: a) -> a { // a // } - let a_var = generic_var(id_gen.next()); + let a_var = Type::generic_var(id_gen.next()); functions.insert( FunctionAccessKey { @@ -1134,8 +1041,8 @@ pub fn prelude_functions( // pub fn always(a: a, b _b: b) -> a { // a // } - let a_var = generic_var(id_gen.next()); - let b_var = generic_var(id_gen.next()); + let a_var = Type::generic_var(id_gen.next()); + let b_var = Type::generic_var(id_gen.next()); functions.insert( FunctionAccessKey { @@ -1209,12 +1116,12 @@ pub fn prelude_functions( // pub fn flip(f: fn(a, b) -> c) -> fn(b, a) -> c { // fn(b, a) { f(a, b) } // } - let a_var = generic_var(id_gen.next()); - let b_var = generic_var(id_gen.next()); - let c_var = generic_var(id_gen.next()); + let a_var = Type::generic_var(id_gen.next()); + let b_var = Type::generic_var(id_gen.next()); + let c_var = Type::generic_var(id_gen.next()); - let input_type = function(vec![a_var.clone(), b_var.clone()], c_var.clone()); - let return_type = function(vec![b_var.clone(), a_var.clone()], c_var.clone()); + let input_type = Type::function(vec![a_var.clone(), b_var.clone()], c_var.clone()); + let return_type = Type::function(vec![b_var.clone(), a_var.clone()], c_var.clone()); functions.insert( FunctionAccessKey { @@ -1574,7 +1481,7 @@ pub fn prelude_data_types(id_gen: &IdGenerator) -> IndexMap IndexMap IndexMap Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - name: INT.to_string(), - module: "".to_string(), - args: vec![], - alias: None, - }) -} +// ---------------------------------------------------------------------------- +// TypedDataTypes +// +// TODO: Rewrite in terms of ValueConstructor to avoid duplication and ensure +// consistency with prelude definitions. -pub fn data() -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - name: DATA.to_string(), - module: "".to_string(), - args: vec![], - alias: None, - }) -} +impl TypedDataType { + pub fn data() -> Self { + DataType::known_enum(well_known::DATA, &[]) + } -pub fn byte_array() -> Rc { - Rc::new(Type::App { - args: vec![], - public: true, - contains_opaque: false, - name: BYTE_ARRAY.to_string(), - module: "".to_string(), - alias: None, - }) -} + pub fn bool() -> Self { + DataType::known_enum(well_known::BOOL, well_known::BOOL_CONSTRUCTORS) + } -pub fn g1_element() -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - module: "".to_string(), - name: G1_ELEMENT.to_string(), - args: vec![], - alias: None, - }) -} + pub fn script_purpose() -> Self { + DataType::known_enum( + well_known::SCRIPT_PURPOSE, + well_known::SCRIPT_PURPOSE_CONSTRUCTORS, + ) + } -pub fn g2_element() -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - module: "".to_string(), - name: G2_ELEMENT.to_string(), - args: vec![], - alias: None, - }) -} + pub fn script_context() -> Self { + DataType::known_enum( + well_known::SCRIPT_CONTEXT, + well_known::SCRIPT_CONTEXT_CONSTRUCTORS, + ) + } -pub fn miller_loop_result() -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - module: "".to_string(), - name: MILLER_LOOP_RESULT.to_string(), - args: vec![], - alias: None, - }) -} + pub fn prng() -> Self { + DataType::known_enum(well_known::PRNG, well_known::PRNG_CONSTRUCTORS) + } -pub fn tuple(elems: Vec>) -> Rc { - Rc::new(Type::Tuple { elems, alias: None }) -} + pub fn ordering() -> Self { + DataType::known_enum(well_known::ORDERING, well_known::ORDERING_CONSTRUCTORS) + } -pub fn pair(fst: Rc, snd: Rc) -> Rc { - Rc::new(Type::Pair { - fst, - snd, - alias: None, - }) -} - -pub fn bool() -> Rc { - Rc::new(Type::App { - args: vec![], - public: true, - contains_opaque: false, - name: BOOL.to_string(), - module: "".to_string(), - alias: None, - }) -} - -pub fn prng() -> Rc { - Rc::new(Type::App { - args: vec![], - public: true, - contains_opaque: false, - name: PRNG.to_string(), - module: "".to_string(), - alias: None, - }) -} - -pub fn fuzzer(a: Rc) -> Rc { - let prng_annotation = Annotation::Constructor { - location: Span::empty(), - module: None, - name: "PRNG".to_string(), - arguments: vec![], - }; - - Rc::new(Type::Fn { - args: vec![prng()], - ret: option(tuple(vec![prng(), a])), - alias: Some( - TypeAliasAnnotation { - alias: "Fuzzer".to_string(), - parameters: vec!["a".to_string()], - annotation: Annotation::Fn { + pub fn option(tipo: Rc) -> Self { + DataType { + constructors: vec![ + RecordConstructor { location: Span::empty(), - arguments: vec![prng_annotation.clone()], - ret: Annotation::Constructor { + name: well_known::OPTION_CONSTRUCTORS[0].to_string(), + arguments: vec![RecordConstructorArg { + label: None, + annotation: Annotation::Var { + location: Span::empty(), + name: "a".to_string(), + }, location: Span::empty(), - module: None, - name: "Option".to_string(), - arguments: vec![Annotation::Tuple { - location: Span::empty(), - elems: vec![ - prng_annotation, - Annotation::Var { - location: Span::empty(), - name: "a".to_string(), - }, - ], - }], - } - .into(), - }, - } - .into(), - ), - }) -} - -pub fn map(k: Rc, v: Rc) -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - module: "".to_string(), - name: LIST.to_string(), - args: vec![pair(k, v)], - alias: Some( - TypeAliasAnnotation { - alias: PAIRS.to_string(), - parameters: vec!["k".to_string(), "v".to_string()], - annotation: Annotation::Constructor { - location: Span::empty(), - module: None, - name: LIST.to_string(), - arguments: vec![Annotation::Pair { - location: Span::empty(), - fst: Box::new(Annotation::Var { - location: Span::empty(), - name: "k".to_string(), - }), - snd: Box::new(Annotation::Var { - location: Span::empty(), - name: "v".to_string(), - }), + tipo: tipo.clone(), + doc: None, }], + doc: None, + sugar: false, }, - } - .into(), - ), - }) -} - -pub fn list(t: Rc) -> Rc { - Rc::new(Type::App { - public: true, - // FIXME: We should probably have t.contains_opaque here? - contains_opaque: false, - name: LIST.to_string(), - module: "".to_string(), - args: vec![t], - alias: None, - }) -} - -pub fn string() -> Rc { - Rc::new(Type::App { - args: vec![], - public: true, - contains_opaque: false, - name: STRING.to_string(), - module: "".to_string(), - alias: None, - }) -} - -pub fn void() -> Rc { - Rc::new(Type::App { - args: vec![], - public: true, - contains_opaque: false, - name: VOID.to_string(), - module: "".to_string(), - alias: None, - }) -} - -pub fn option(a: Rc) -> Rc { - Rc::new(Type::App { - public: true, - // FIXME: We should probably have t.contains_opaque here? - contains_opaque: false, - name: OPTION.to_string(), - module: "".to_string(), - args: vec![a], - alias: None, - }) -} - -pub fn ordering() -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - name: ORDERING.to_string(), - module: "".to_string(), - args: vec![], - alias: None, - }) -} - -pub fn function(args: Vec>, ret: Rc) -> Rc { - Rc::new(Type::Fn { - ret, - args, - alias: None, - }) -} - -pub fn generic_var(id: u64) -> Rc { - let tipo = Rc::new(RefCell::new(TypeVar::Generic { id })); - - Rc::new(Type::Var { tipo, alias: None }) -} - -pub fn unbound_var(id: u64) -> Rc { - let tipo = Rc::new(RefCell::new(TypeVar::Unbound { id })); - - Rc::new(Type::Var { tipo, alias: None }) -} - -pub fn wrapped_redeemer(redeemer: Rc) -> Rc { - Rc::new(Type::App { - public: true, - contains_opaque: false, - module: "".to_string(), - name: REDEEMER_WRAPPER.to_string(), - args: vec![redeemer], - alias: None, - }) + RecordConstructor { + location: Span::empty(), + name: well_known::OPTION_CONSTRUCTORS[1].to_string(), + arguments: vec![], + doc: None, + sugar: false, + }, + ], + doc: None, + location: Span::empty(), + name: well_known::OPTION.to_string(), + opaque: false, + parameters: vec!["a".to_string()], + public: true, + typed_parameters: vec![tipo], + } + } + + pub fn never() -> Self { + DataType::known_enum(well_known::NEVER, well_known::NEVER_CONSTRUCTORS) + } } diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 2af362ea..07659b36 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -1,18 +1,17 @@ -use crate::tipo::ValueConstructorVariant; pub(crate) use crate::{ ast::{ - self, Annotation, ArgBy, ArgName, AssignmentPattern, BinOp, Bls12_381Point, + self, Annotation, ArgBy, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point, ByteArrayFormatPreference, CallArg, Curve, DataType, DataTypeKey, DefinitionLocation, Located, LogicalOpChainKind, ParsedCallArg, Pattern, RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypedArg, TypedAssignmentKind, TypedClause, - TypedDataType, TypedIfBranch, TypedRecordUpdateArg, UnOp, UntypedArg, + TypedDataType, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedIfBranch, UntypedRecordUpdateArg, }, - builtins::void, parser::token::Base, tipo::{ check_replaceable_opaque_type, convert_opaque_type, lookup_data_type_by_tipo, ModuleValueConstructor, PatternConstructor, Type, TypeVar, ValueConstructor, + ValueConstructorVariant, }, }; use indexmap::IndexMap; @@ -201,6 +200,52 @@ impl From> for Vec1 { } impl TypedExpr { + pub fn sequence(exprs: &[TypedExpr]) -> Self { + TypedExpr::Sequence { + location: Span::empty(), + expressions: exprs.to_vec(), + } + } + + pub fn let_(value: Self, pattern: TypedPattern, tipo: Rc) -> Self { + TypedExpr::Assignment { + location: Span::empty(), + tipo: tipo.clone(), + value: value.into(), + pattern, + kind: AssignmentKind::let_(), + } + } + + // Create an expect assignment, unless the target type is `Data`; then fallback to a let. + pub fn flexible_expect(value: Self, pattern: TypedPattern, tipo: Rc) -> Self { + TypedExpr::Assignment { + location: Span::empty(), + tipo: tipo.clone(), + value: value.into(), + pattern, + kind: if tipo.is_data() { + AssignmentKind::let_() + } else { + AssignmentKind::expect() + }, + } + } + + pub fn local_var(name: &str, tipo: Rc) -> Self { + TypedExpr::Var { + location: Span::empty(), + constructor: ValueConstructor { + public: true, + variant: ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + tipo: tipo.clone(), + }, + name: name.to_string(), + } + } + pub fn tipo(&self) -> Rc { match self { Self::Var { constructor, .. } => constructor.tipo.clone(), @@ -224,9 +269,10 @@ impl TypedExpr { | Self::RecordAccess { tipo, .. } | Self::RecordUpdate { tipo, .. } | Self::CurvePoint { tipo, .. } => tipo.clone(), - Self::Pipeline { expressions, .. } | Self::Sequence { expressions, .. } => { - expressions.last().map(TypedExpr::tipo).unwrap_or_else(void) - } + Self::Pipeline { expressions, .. } | Self::Sequence { expressions, .. } => expressions + .last() + .map(TypedExpr::tipo) + .unwrap_or_else(Type::void), } } @@ -241,6 +287,10 @@ impl TypedExpr { ) } + pub fn is_error_term(&self) -> bool { + matches!(self, Self::ErrorTerm { .. }) + } + /// Returns `true` if the typed expr is [`Assignment`]. pub fn is_assignment(&self) -> bool { matches!(self, Self::Assignment { .. }) @@ -487,7 +537,7 @@ impl TypedExpr { module: String::new(), constructors_count: 1, }, - tipo: void(), + tipo: Type::void(), }, location, } diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 0952e099..f3294673 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -3,10 +3,10 @@ use crate::{ Annotation, ArgBy, ArgName, ArgVia, AssignmentKind, AssignmentPattern, BinOp, ByteArrayFormatPreference, CallArg, Constant, CurveType, DataType, Definition, Function, LogicalOpChainKind, ModuleConstant, OnTestFailure, Pattern, RecordConstructor, - RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, - UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedAssignmentKind, UntypedClause, - UntypedDefinition, UntypedFunction, UntypedIfBranch, UntypedModule, UntypedPattern, - UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE, + RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, + TypedValidator, UnOp, UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedAssignmentKind, + UntypedClause, UntypedDefinition, UntypedFunction, UntypedIfBranch, UntypedModule, + UntypedPattern, UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE, }, docvec, expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR}, @@ -232,15 +232,24 @@ impl<'comments> Formatter<'comments> { return_annotation, end_position, .. - }) => self.definition_fn(public, name, args, return_annotation, body, *end_position), + }) => self.definition_fn( + public, + name, + args, + return_annotation, + body, + *end_position, + false, + ), Definition::Validator(Validator { end_position, - fun, - other_fun, + handlers, + fallback, params, + name, .. - }) => self.definition_validator(params, fun, other_fun, *end_position), + }) => self.definition_validator(name, params, handlers, fallback, *end_position), Definition::Test(Function { name, @@ -512,16 +521,29 @@ impl<'comments> Formatter<'comments> { return_annotation: &'a Option, body: &'a UntypedExpr, end_location: usize, + is_validator: bool, ) -> Document<'a> { // Fn name and args - let head = pub_(*public) - .append("fn ") - .append(name) - .append(wrap_args(args.iter().map(|e| (self.fn_arg(e), false)))); + let head = if !is_validator { + pub_(*public) + .append("fn ") + .append(name) + .append(wrap_args(args.iter().map(|e| (self.fn_arg(e), false)))) + } else { + name.to_doc() + .append(wrap_args(args.iter().map(|e| (self.fn_arg(e), false)))) + }; // Add return annotation let head = match return_annotation { - Some(anno) => head.append(" -> ").append(self.annotation(anno)), + Some(anno) => { + let is_bool = anno.is_logically_equal(&Annotation::boolean(Span::empty())); + if is_validator && is_bool { + head + } else { + head.append(" -> ").append(self.annotation(anno)) + } + } None => head, } .group(); @@ -581,57 +603,73 @@ impl<'comments> Formatter<'comments> { fn definition_validator<'a>( &mut self, + name: &'a str, params: &'a [UntypedArg], - fun: &'a UntypedFunction, - other_fun: &'a Option, + handlers: &'a [UntypedFunction], + fallback: &'a UntypedFunction, end_position: usize, ) -> Document<'a> { - // validator(params) - let v_head = "validator".to_doc().append(if !params.is_empty() { - wrap_args(params.iter().map(|e| (self.fn_arg(e), false))) - } else { - nil() - }); + // validator name(params) + let v_head = "validator" + .to_doc() + .append(" ") + .append(name) + .append(if !params.is_empty() { + wrap_args(params.iter().map(|e| (self.fn_arg(e), false))) + } else { + nil() + }); - let fun_comments = self.pop_comments(fun.location.start); - let fun_doc_comments = self.doc_comments(fun.location.start); - let first_fn = self - .definition_fn( - &fun.public, - &fun.name, - &fun.arguments, - &fun.return_annotation, - &fun.body, - fun.end_position, - ) - .group(); - let first_fn = commented(fun_doc_comments.append(first_fn).group(), fun_comments); + let mut handler_docs = vec![]; - let other_fn = match other_fun { - None => nil(), - Some(other) => { - let other_comments = self.pop_comments(other.location.start); - let other_doc_comments = self.doc_comments(other.location.start); + for handler in handlers.iter() { + let fun_comments = self.pop_comments(handler.location.start); + let fun_doc_comments = self.doc_comments(handler.location.start); - let other_fn = self - .definition_fn( - &other.public, - &other.name, - &other.arguments, - &other.return_annotation, - &other.body, - other.end_position, - ) - .group(); + let first_fn = self + .definition_fn( + &handler.public, + &handler.name, + &handler.arguments, + &handler.return_annotation, + &handler.body, + handler.end_position, + true, + ) + .group(); - commented(other_doc_comments.append(other_fn).group(), other_comments) - } - }; + let first_fn = commented(fun_doc_comments.append(first_fn).group(), fun_comments); - let v_body = line() - .append(first_fn) - .append(if other_fun.is_some() { lines(2) } else { nil() }) - .append(other_fn); + handler_docs.push(first_fn); + } + + let is_exhaustive = handlers.len() >= TypedValidator::available_handler_names().len() - 1; + + if !is_exhaustive || !fallback.is_default_fallback() { + let fallback_comments = self.pop_comments(fallback.location.start); + let fallback_doc_comments = self.doc_comments(fallback.location.start); + + let fallback_fn = self + .definition_fn( + &fallback.public, + &fallback.name, + &fallback.arguments, + &fallback.return_annotation, + &fallback.body, + fallback.end_position, + true, + ) + .group(); + + let fallback_fn = commented( + fallback_doc_comments.append(fallback_fn).group(), + fallback_comments, + ); + + handler_docs.push(fallback_fn); + } + + let v_body = line().append(join(handler_docs, lines(2))); let v_body = match printed_comments(self.pop_comments(end_position), false) { Some(comments) => v_body.append(lines(2)).append(comments).nest(INDENT), diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index e46faa39..5e8e3757 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -17,7 +17,7 @@ use crate::{ Span, TraceLevel, Tracing, TypedArg, TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp, }, - builtins::{bool, byte_array, data, int, list, pair, void, PRELUDE}, + builtins::PRELUDE, expr::TypedExpr, gen_uplc::{ air::ExpectLevel, @@ -114,66 +114,15 @@ impl<'a> CodeGenerator<'a> { } } - pub fn generate( - &mut self, - TypedValidator { - fun, - other_fun, - params, - .. - }: &TypedValidator, - module_name: &str, - ) -> Program { - let mut air_tree_fun = self.build(&fun.body, module_name, &[]); + pub fn generate(&mut self, validator: &TypedValidator, module_name: &str) -> Program { + let air_tree_fun = wrap_validator_condition( + self.build(&validator.into_script_context_handler(), module_name, &[]), + self.tracing, + ); - air_tree_fun = wrap_validator_condition(air_tree_fun, self.tracing); + let air_tree_fun = AirTree::anon_func(vec!["__context__".to_string()], air_tree_fun, true); - let (src_code, lines) = self.module_src.get(module_name).unwrap(); - - let mut validator_args_tree = - self.check_validator_args(&fun.arguments, true, air_tree_fun, src_code, lines); - - if let Some(other) = other_fun { - let mut air_tree_fun_other = self.build(&other.body, module_name, &[]); - - air_tree_fun_other = wrap_validator_condition(air_tree_fun_other, self.tracing); - - let validator_args_tree_other = self.check_validator_args( - &other.arguments, - true, - air_tree_fun_other, - src_code, - lines, - ); - - let (spend, spend_name, mint, mint_name) = - if other.arguments.len() > fun.arguments.len() { - ( - validator_args_tree_other, - other.name.clone(), - validator_args_tree, - fun.name.clone(), - ) - } else { - ( - validator_args_tree, - fun.name.clone(), - validator_args_tree_other, - other.name.clone(), - ) - }; - - validator_args_tree = AirTree::multi_validator(mint_name, mint, spend_name, spend); - - // Special Case with multi_validators - self.special_functions - .use_function_uplc(CONSTR_FIELDS_EXPOSER.to_string()); - - self.special_functions - .use_function_uplc(CONSTR_INDEX_EXPOSER.to_string()); - } - - validator_args_tree = AirTree::no_op(validator_args_tree); + let validator_args_tree = AirTree::no_op(air_tree_fun); let full_tree = self.hoist_functions_to_validator(validator_args_tree); @@ -181,9 +130,9 @@ impl<'a> CodeGenerator<'a> { let full_vec = full_tree.to_vec(); - let mut term = self.uplc_code_gen(full_vec); + let term = self.uplc_code_gen(full_vec); - term = cast_validator_args(term, params); + let term = cast_validator_args(term, &validator.params); self.finalize(term) } @@ -278,7 +227,7 @@ impl<'a> CodeGenerator<'a> { self.special_functions.insert_new_function( msg_func_name.clone(), Term::Error.delayed_trace(Term::string(msg)).delay(), - void(), + Type::void(), ); Some(self.special_functions.use_function_tree(msg_func_name)) } @@ -683,17 +632,21 @@ impl<'a> CodeGenerator<'a> { let function_name = format!("__access_index_{}", *index); if self.code_gen_functions.get(&function_name).is_none() { - let mut body = AirTree::local_var("__fields", list(data())); + let mut body = AirTree::local_var("__fields", Type::list(Type::data())); for _ in 0..*index { body = AirTree::builtin( DefaultFunction::TailList, - list(data()), + Type::list(Type::data()), vec![body], ) } - body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]); + body = AirTree::builtin( + DefaultFunction::HeadList, + Type::data(), + vec![body], + ); self.code_gen_functions.insert( function_name.clone(), @@ -707,7 +660,7 @@ impl<'a> CodeGenerator<'a> { let list_of_fields = AirTree::call( self.special_functions .use_function_tree(CONSTR_FIELDS_EXPOSER.to_string()), - list(data()), + Type::list(Type::data()), vec![self.build(record, module_build_name, &[])], ); @@ -822,17 +775,21 @@ impl<'a> CodeGenerator<'a> { let function_name = format!("__access_index_{}", *index); if self.code_gen_functions.get(&function_name).is_none() { - let mut body = AirTree::local_var("__fields", list(data())); + let mut body = AirTree::local_var("__fields", Type::list(Type::data())); for _ in 0..*index { body = AirTree::builtin( DefaultFunction::TailList, - list(data()), + Type::list(Type::data()), vec![body], ) } - body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]); + body = AirTree::builtin( + DefaultFunction::HeadList, + Type::data(), + vec![body], + ); self.code_gen_functions.insert( function_name.clone(), @@ -941,7 +898,7 @@ impl<'a> CodeGenerator<'a> { let otherwise = match &props.otherwise { Some(x) => x.clone(), // (delay (error )) - None => AirTree::anon_func(vec![], AirTree::error(void(), false), true), + None => AirTree::anon_func(vec![], AirTree::error(Type::void(), false), true), }; match pattern { @@ -957,10 +914,10 @@ impl<'a> CodeGenerator<'a> { let expect = AirTree::binop( BinOp::Eq, - bool(), + Type::bool(), AirTree::int(expected_int), - AirTree::local_var(&name, int()), - int(), + AirTree::local_var(&name, Type::int()), + Type::int(), ); assign_casted_value( @@ -979,10 +936,10 @@ impl<'a> CodeGenerator<'a> { let expect = AirTree::binop( BinOp::Eq, - bool(), + Type::bool(), AirTree::byte_array(expected_bytes.clone()), - AirTree::local_var(&name, byte_array()), - byte_array(), + AirTree::local_var(&name, Type::byte_array()), + Type::byte_array(), ); assign_casted_value( @@ -1369,7 +1326,13 @@ impl<'a> CodeGenerator<'a> { type_map.insert(index, field_type); } - assert!(type_map.len() >= arguments.len()); + assert!( + type_map.len() >= arguments.len(), + "type map len: {}, arguments len: {}; for constructor {:?}", + type_map.len(), + arguments.len(), + name, + ); let mut fields = vec![]; @@ -1471,7 +1434,9 @@ impl<'a> CodeGenerator<'a> { .unwrap_or_else(|| unreachable!("Failed to find definition for {}", name)); let then = if props.kind.is_expect() - && (data_type.constructors.len() > 1 || props.full_check) + && (data_type.constructors.len() > 1 + || props.full_check + || data_type.is_never()) { let (index, _) = data_type .constructors @@ -1484,7 +1449,7 @@ impl<'a> CodeGenerator<'a> { AirTree::when( &subject_name, - void(), + Type::void(), tipo.clone(), AirTree::local_var(&constructor_name, tipo.clone()), AirTree::assert_constr_index( @@ -1496,8 +1461,11 @@ impl<'a> CodeGenerator<'a> { ) } else { assert!( - data_type.constructors.len() == 1, - "data_type={data_type:#?}" + data_type.constructors.len() == 1 || data_type.is_never(), + "attempted let-assignment on a type with more or less than 1 constructor: \nis_expect? {}\nfull_check? {}\ndata_type={data_type:#?}\n{}", + props.kind.is_expect(), + props.full_check, + name, ); then }; @@ -1609,7 +1577,11 @@ impl<'a> CodeGenerator<'a> { otherwise: AirTree, depth: usize, ) -> AirTree { - assert!(tipo.get_generic().is_none()); + assert!( + tipo.get_generic().is_none(), + "left-hand side of expect is generic: {}", + tipo.to_pretty(0) + ); // Shouldn't be needed but still here just in case // this function is called from anywhere else besides assignment let tipo = &convert_opaque_type(tipo, &self.data_types, true); @@ -1650,11 +1622,14 @@ impl<'a> CodeGenerator<'a> { defined_data_types, location, AirTree::call( - AirTree::local_var(format!("__curried_expect_on_list_{}", depth), void()), - void(), + AirTree::local_var( + format!("__curried_expect_on_list_{}", depth), + Type::void(), + ), + Type::void(), vec![AirTree::builtin( DefaultFunction::TailList, - list(data()), + Type::list(Type::data()), vec![AirTree::local_var( format!("__list_{}", depth), tipo.clone(), @@ -1689,7 +1664,7 @@ impl<'a> CodeGenerator<'a> { &pair_name, AirTree::builtin( DefaultFunction::HeadList, - pair(data(), data()), + Type::pair(Type::data(), Type::data()), vec![AirTree::local_var( format!("__list_{}", depth), tipo.clone(), @@ -1733,7 +1708,7 @@ impl<'a> CodeGenerator<'a> { let func_call = AirTree::call( AirTree::var( ValueConstructor::public( - void(), + Type::void(), ValueConstructorVariant::ModuleFn { name: EXPECT_ON_LIST.to_string(), field_map: None, @@ -1746,7 +1721,7 @@ impl<'a> CodeGenerator<'a> { EXPECT_ON_LIST, "", ), - void(), + Type::void(), vec![AirTree::local_var(&map_name, tipo.clone()), unwrap_function], ); @@ -1826,7 +1801,7 @@ impl<'a> CodeGenerator<'a> { &item_name, AirTree::builtin( DefaultFunction::HeadList, - data(), + Type::data(), vec![AirTree::local_var( format!("__list_{}", depth), tipo.clone(), @@ -1835,7 +1810,7 @@ impl<'a> CodeGenerator<'a> { AirTree::soft_cast_assignment( &item_name, inner_list_type.clone(), - AirTree::local_var(&item_name, data()), + AirTree::local_var(&item_name, Type::data()), self.expect_type_assign( inner_list_type, AirTree::local_var(&item_name, inner_list_type.clone()), @@ -1844,12 +1819,12 @@ impl<'a> CodeGenerator<'a> { AirTree::call( AirTree::local_var( format!("__curried_expect_on_list_{}", depth), - void(), + Type::void(), ), - void(), + Type::void(), vec![AirTree::builtin( DefaultFunction::TailList, - list(data()), + Type::list(Type::data()), vec![AirTree::local_var( format!("__list_{}", depth), tipo.clone(), @@ -1893,7 +1868,7 @@ impl<'a> CodeGenerator<'a> { let func_call = AirTree::call( AirTree::var( ValueConstructor::public( - void(), + Type::void(), ValueConstructorVariant::ModuleFn { name: EXPECT_ON_LIST.to_string(), field_map: None, @@ -1906,7 +1881,7 @@ impl<'a> CodeGenerator<'a> { EXPECT_ON_LIST, "", ), - void(), + Type::void(), vec![ AirTree::local_var(&list_name, tipo.clone()), unwrap_function, @@ -1997,14 +1972,28 @@ impl<'a> CodeGenerator<'a> { let current_defined = defined_data_types.clone(); let mut diff_defined_types = vec![]; - let var_then = - AirTree::call(AirTree::local_var("then_delayed", void()), void(), vec![]); + let var_then = AirTree::call( + AirTree::local_var("then_delayed", Type::void()), + Type::void(), + vec![], + ); - let otherwise_delayed = AirTree::local_var("otherwise_delayed", void()); + let otherwise_delayed = AirTree::local_var("otherwise_delayed", Type::void()); + + let is_never = data_type.is_never(); let constr_clauses = data_type.constructors.iter().enumerate().rfold( otherwise_delayed.clone(), |acc, (index, constr)| { + // NOTE: For the Never type, we have an placeholder first constructor + // that must be ignored. The Never type is considered to have only one + // constructor starting at index 1 so it shouldn't be possible to + // cast from Data into the first constructor. There's virtually no + // constructor at index 0. + if is_never && index == 0 { + return acc; + } + let mut constr_args = vec![]; let constr_then = constr.arguments.iter().enumerate().rfold( @@ -2081,13 +2070,13 @@ impl<'a> CodeGenerator<'a> { let when_expr = AirTree::when( format!("__subject_span_{}_{}", location.start, location.end), - void(), + Type::void(), tipo.clone(), AirTree::local_var( format!("__constr_var_span_{}_{}", location.start, location.end), tipo.clone(), ), - AirTree::call(constr_clauses, void(), vec![]), + AirTree::call(constr_clauses, Type::void(), vec![]), ); let func_body = AirTree::let_assignment( @@ -2140,7 +2129,7 @@ impl<'a> CodeGenerator<'a> { "", ); - AirTree::call(func_var, void(), args) + AirTree::call(func_var, Type::void(), args) } } } @@ -2193,7 +2182,7 @@ impl<'a> CodeGenerator<'a> { ), ) } else if let Some(data_type) = data_type { - if data_type.constructors.len() > 1 { + if data_type.constructors.len() > 1 && !data_type.is_never() { AirTree::clause( &props.original_subject_name, clause_cond, @@ -2664,7 +2653,7 @@ impl<'a> CodeGenerator<'a> { // Since check_last_item is false this will never get added to the final uplc anyway ExpectLevel::None, elems_then, - AirTree::error(void(), false), + AirTree::error(Type::void(), false), ) } else { assert!(defined_tails.len() >= elems.len()); @@ -2745,7 +2734,7 @@ impl<'a> CodeGenerator<'a> { AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()), false, next_then, - AirTree::error(void(), false), + AirTree::error(Type::void(), false), ) }; @@ -2775,7 +2764,11 @@ impl<'a> CodeGenerator<'a> { ) }); - assert!(!data_type.constructors.is_empty()); + assert!( + !data_type.constructors.is_empty(), + "{}\n{constructor:#?}\n{data_type:#?}", + subject_tipo.to_pretty(0) + ); let (constr_index, _) = data_type .constructors @@ -2872,7 +2865,7 @@ impl<'a> CodeGenerator<'a> { AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()), false, next_then, - AirTree::error(void(), false), + AirTree::error(Type::void(), false), ) }; @@ -3001,7 +2994,7 @@ impl<'a> CodeGenerator<'a> { AirTree::local_var(&props.clause_var_name, subject_tipo.clone()), false, tuple_name_assigns, - AirTree::error(void(), false), + AirTree::error(Type::void(), false), ), ) } else { @@ -3029,7 +3022,7 @@ impl<'a> CodeGenerator<'a> { AirTree::clause_guard( &props.original_subject_name, AirTree::int(value), - int(), + Type::int(), then, ) } @@ -3038,7 +3031,7 @@ impl<'a> CodeGenerator<'a> { AirTree::clause_guard( &props.original_subject_name, AirTree::byte_array(value.clone()), - byte_array(), + Type::byte_array(), then, ) } @@ -3163,14 +3156,14 @@ impl<'a> CodeGenerator<'a> { AirTree::clause_guard( &props.original_subject_name, AirTree::bool(constr_name == "True"), - bool(), + Type::bool(), then, ) } else if subject_tipo.is_void() { AirTree::clause_guard( &props.original_subject_name, AirTree::void(), - void(), + Type::void(), then, ) } else { @@ -3242,7 +3235,7 @@ impl<'a> CodeGenerator<'a> { arg_names.push(arg_name.clone()); - let param = AirTree::local_var(&arg_name, data()); + let param = AirTree::local_var(&arg_name, Type::data()); let actual_type = convert_opaque_type(&arg.tipo, &self.data_types, true); @@ -3267,7 +3260,7 @@ impl<'a> CodeGenerator<'a> { self.special_functions.insert_new_function( msg_func_name.clone(), Term::Error.delayed_trace(Term::string(msg)).delay(), - void(), + Type::void(), ); Some(self.special_functions.use_function_tree(msg_func_name)) @@ -3283,7 +3276,7 @@ impl<'a> CodeGenerator<'a> { inner_then, &actual_type, AssignmentProperties { - value_type: data(), + value_type: Type::data(), kind: AssignmentKind::expect(), remove_unused: false, full_check: true, @@ -4036,9 +4029,9 @@ impl<'a> CodeGenerator<'a> { .get(&generic_function_key.function_name) .unwrap_or_else(|| { panic!( - "Missing function definition for {}. Known definitions: {:?}", + "Missing function definition for {}. Known functions: {:?}", generic_function_key.function_name, - self.code_gen_functions.keys(), + self.functions.keys(), ) }); @@ -5604,8 +5597,18 @@ impl<'a> CodeGenerator<'a> { } => { let tail_name_prefix = "__tail_index"; - let data_type = lookup_data_type_by_tipo(&self.data_types, &tipo) - .unwrap_or_else(|| panic!("HOW DID YOU DO THIS ON BOOL OR VOID")); + let data_type = + lookup_data_type_by_tipo(&self.data_types, &tipo).unwrap_or_else(|| { + panic!( + "Attempted record update on an unknown type!\ntype: {:#?}", + tipo + ) + }); + + assert!( + !data_type.is_never(), + "Attempted record update on a Never type.", + ); let constructor_field_count = data_type.constructors[0].arguments.len(); let record = arg_stack.pop().unwrap(); diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 39697b9d..d2f166ac 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -7,7 +7,6 @@ use crate::{ Constant, DataTypeKey, FunctionAccessKey, Pattern, Span, TraceLevel, TypedArg, TypedAssignmentKind, TypedClause, TypedDataType, TypedPattern, }, - builtins::{data, function, int, list, void}, expr::TypedExpr, line_numbers::{LineColumn, LineNumbers}, tipo::{ @@ -212,7 +211,7 @@ impl CodeGenSpecialFuncs { Term::snd_pair() .apply(Term::unconstr_data().apply(Term::var("__constr_var"))) .lambda("__constr_var"), - function(vec![data()], list(data())), + Type::function(vec![Type::data()], Type::list(Type::data())), ), ); @@ -222,7 +221,7 @@ impl CodeGenSpecialFuncs { Term::fst_pair() .apply(Term::unconstr_data().apply(Term::var("__constr_var"))) .lambda("__constr_var"), - function(vec![data()], int()), + Type::function(vec![Type::data()], Type::int()), ), ); @@ -784,7 +783,7 @@ pub fn rearrange_list_clauses( tipo: tipo.clone(), text: Box::new(TypedExpr::String { location: Span::empty(), - tipo: crate::builtins::string(), + tipo: Type::string(), value: format!("Clause hole found for {index} elements."), }), then: Box::new(TypedExpr::ErrorTerm { @@ -1688,15 +1687,15 @@ pub fn cast_validator_args(term: Term, arguments: &[TypedArg]) -> Term AirTree { let otherwise = match trace { - TraceLevel::Silent | TraceLevel::Compact => AirTree::error(void(), true), + TraceLevel::Silent | TraceLevel::Compact => AirTree::error(Type::void(), true), TraceLevel::Verbose => AirTree::trace( AirTree::string("Validator returned false"), - void(), - AirTree::error(void(), true), + Type::void(), + AirTree::error(Type::void(), true), ), }; - AirTree::if_branch(void(), air_tree, AirTree::void(), otherwise) + AirTree::if_branch(Type::void(), air_tree, AirTree::void(), otherwise) } pub fn extract_constant(term: &Term) -> Option> { diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index 3fd79208..3e53c750 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -1,7 +1,6 @@ use super::air::{Air, ExpectLevel}; use crate::{ ast::{BinOp, Curve, Span, UnOp}, - builtins::{bool, byte_array, data, int, list, string, void}, tipo::{Type, ValueConstructor, ValueConstructorVariant}, }; use indexmap::IndexSet; @@ -113,7 +112,7 @@ pub enum AirMsg { impl AirMsg { pub fn to_air_tree(&self) -> AirTree { match self { - AirMsg::LocalVar(name) => AirTree::local_var(name, string()), + AirMsg::LocalVar(name) => AirTree::local_var(name, Type::string()), AirMsg::Msg(msg) => AirTree::string(msg), } } @@ -862,8 +861,8 @@ impl AirTree { AirTree::var( ValueConstructor::public( Type::Fn { - args: vec![list(data())], - ret: data(), + args: vec![Type::list(Type::data())], + ret: Type::data(), alias: None, } .into(), @@ -879,7 +878,7 @@ impl AirTree { function_name, "", ), - data(), + Type::data(), vec![list_of_fields], ), tipo.clone(), @@ -984,7 +983,7 @@ impl AirTree { } else { DefaultFunction::SndPair }, - data(), + Type::data(), vec![tuple], ), tipo.clone(), @@ -1039,9 +1038,9 @@ impl AirTree { } pub fn expect_on_list2() -> AirTree { - let inner_expect_on_list = AirTree::local_var(INNER_EXPECT_ON_LIST, void()); + let inner_expect_on_list = AirTree::local_var(INNER_EXPECT_ON_LIST, Type::void()); - let list_var = AirTree::local_var("__list_to_check", list(data())); + let list_var = AirTree::local_var("__list_to_check", Type::list(Type::data())); AirTree::let_assignment( INNER_EXPECT_ON_LIST, @@ -1051,13 +1050,13 @@ impl AirTree { "__list_to_check".to_string(), ], AirTree::call( - AirTree::local_var("__check_with", void()), - void(), + AirTree::local_var("__check_with", Type::void()), + Type::void(), vec![ list_var.clone(), AirTree::call( inner_expect_on_list.clone(), - void(), + Type::void(), vec![inner_expect_on_list.clone()], ), ], @@ -1066,27 +1065,27 @@ impl AirTree { ), AirTree::call( inner_expect_on_list.clone(), - void(), + Type::void(), vec![inner_expect_on_list, list_var], ), ) } pub fn expect_on_list() -> AirTree { - let list_var = AirTree::local_var("__list_to_check", list(data())); + let list_var = AirTree::local_var("__list_to_check", Type::list(Type::data())); - let head_list = AirTree::builtin(DefaultFunction::HeadList, data(), vec![list_var]); + let head_list = AirTree::builtin(DefaultFunction::HeadList, Type::data(), vec![list_var]); let expect_on_head = AirTree::call( - AirTree::local_var("__check_with", void()), - void(), + AirTree::local_var("__check_with", Type::void()), + Type::void(), vec![head_list], ); let next_call = AirTree::call( AirTree::var( ValueConstructor::public( - void(), + Type::void(), ValueConstructorVariant::ModuleFn { name: EXPECT_ON_LIST.to_string(), field_map: None, @@ -1099,14 +1098,17 @@ impl AirTree { EXPECT_ON_LIST, "", ), - void(), + Type::void(), vec![ AirTree::builtin( DefaultFunction::TailList, - list(data()), - vec![AirTree::local_var("__list_to_check", list(data()))], + Type::list(Type::data()), + vec![AirTree::local_var( + "__list_to_check", + Type::list(Type::data()), + )], ), - AirTree::local_var("__check_with", void()), + AirTree::local_var("__check_with", Type::void()), ], ); @@ -1114,7 +1116,7 @@ impl AirTree { AirTree::list_clause( "__list_to_check", - void(), + Type::void(), AirTree::void(), assign, None, @@ -1675,10 +1677,10 @@ impl AirTree { pub fn return_type(&self) -> Rc { match self { - AirTree::Int { .. } => int(), - AirTree::String { .. } => string(), - AirTree::ByteArray { .. } => byte_array(), - AirTree::Bool { .. } => bool(), + AirTree::Int { .. } => Type::int(), + AirTree::String { .. } => Type::string(), + AirTree::ByteArray { .. } => Type::byte_array(), + AirTree::Bool { .. } => Type::bool(), AirTree::CurvePoint { point } => point.tipo(), AirTree::List { tipo, .. } | AirTree::Tuple { tipo, .. } @@ -1693,14 +1695,14 @@ impl AirTree { | AirTree::RecordUpdate { tipo, .. } | AirTree::ErrorTerm { tipo, .. } | AirTree::Trace { tipo, .. } => tipo.clone(), - AirTree::Void => void(), + AirTree::Void => Type::void(), AirTree::Var { constructor, .. } => constructor.tipo.clone(), AirTree::Fn { func_body, .. } => func_body.return_type(), AirTree::UnOp { op, .. } => match op { - UnOp::Not => bool(), - UnOp::Negate => int(), + UnOp::Not => Type::bool(), + UnOp::Negate => Type::int(), }, - AirTree::CastToData { .. } => data(), + AirTree::CastToData { .. } => Type::data(), AirTree::Clause { then, .. } | AirTree::ListClause { then, .. } | AirTree::WrapClause { then, .. } @@ -1725,7 +1727,7 @@ impl AirTree { | AirTree::FieldsEmpty { then, .. } | AirTree::ListEmpty { then, .. } | AirTree::NoOp { then } => then.return_type(), - AirTree::MultiValidator { .. } => void(), + AirTree::MultiValidator { .. } => Type::void(), } } diff --git a/crates/aiken-lang/src/parser/annotation.rs b/crates/aiken-lang/src/parser/annotation.rs index 148947e5..b149a294 100644 --- a/crates/aiken-lang/src/parser/annotation.rs +++ b/crates/aiken-lang/src/parser/annotation.rs @@ -1,7 +1,7 @@ use super::{error::ParseError, token::Token}; use crate::{ - ast, - builtins::{PAIR, PRELUDE}, + ast::{self, well_known}, + builtins::PRELUDE, }; use chumsky::prelude::*; @@ -19,7 +19,7 @@ pub fn parser() -> impl Parser { select! {Token::Name { name } if name == PRELUDE => name} .then_ignore(just(Token::Dot)) .or_not() - .then_ignore(select! {Token::UpName { name } if name == PAIR => name}) + .then_ignore(select! {Token::UpName { name } if name == well_known::PAIR => name}) .ignore_then( expression .clone() diff --git a/crates/aiken-lang/src/parser/definition/snapshots/double_validator.snap b/crates/aiken-lang/src/parser/definition/snapshots/double_validator.snap index 5235bbdb..b1b05688 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/double_validator.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/double_validator.snap @@ -1,78 +1,36 @@ --- source: crates/aiken-lang/src/parser/definition/validator.rs -description: "Code:\n\nvalidator {\n fn foo(datum, rdmr, ctx) {\n True\n }\n\n fn bar(rdmr, ctx) {\n True\n }\n}\n" +description: "Code:\n\nvalidator thing {\n spend (datum, rdmr, ctx) {\n True\n }\n\n mint (rdmr, ctx) {\n True\n }\n}\n" --- Validator( Validator { doc: None, - end_position: 90, - fun: Function { - arguments: [ - UntypedArg { - by: ByName( - Named { - name: "datum", - label: "datum", - location: 21..26, - }, - ), - location: 21..26, - annotation: None, - doc: None, - is_validator_param: false, - }, - UntypedArg { - by: ByName( - Named { - name: "rdmr", - label: "rdmr", - location: 28..32, - }, - ), - location: 28..32, - annotation: None, - doc: None, - is_validator_param: false, - }, - UntypedArg { - by: ByName( - Named { - name: "ctx", - label: "ctx", - location: 34..37, - }, - ), - location: 34..37, - annotation: None, - doc: None, - is_validator_param: false, - }, - ], - body: Var { - location: 45..49, - name: "True", - }, - doc: None, - location: 14..38, - name: "foo", - public: false, - return_annotation: None, - return_type: (), - end_position: 52, - on_test_failure: FailImmediately, - }, - other_fun: Some( + end_position: 95, + handlers: [ Function { arguments: [ UntypedArg { by: ByName( Named { - name: "rdmr", - label: "rdmr", - location: 64..68, + name: "datum", + label: "datum", + location: 27..32, }, ), - location: 64..68, + location: 27..32, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "rdmr", + label: "rdmr", + location: 34..38, + }, + ), + location: 34..38, annotation: None, doc: None, is_validator_param: false, @@ -82,30 +40,122 @@ Validator( Named { name: "ctx", label: "ctx", - location: 70..73, + location: 40..43, }, ), - location: 70..73, + location: 40..43, annotation: None, doc: None, is_validator_param: false, }, ], body: Var { - location: 81..85, + location: 51..55, name: "True", }, doc: None, - location: 57..74, - name: "bar", - public: false, - return_annotation: None, + location: 20..44, + name: "spend", + public: true, + return_annotation: Some( + Constructor { + location: 26..44, + module: None, + name: "Bool", + arguments: [], + }, + ), return_type: (), - end_position: 88, + end_position: 58, on_test_failure: FailImmediately, }, - ), + Function { + arguments: [ + UntypedArg { + by: ByName( + Named { + name: "rdmr", + label: "rdmr", + location: 69..73, + }, + ), + location: 69..73, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "ctx", + label: "ctx", + location: 75..78, + }, + ), + location: 75..78, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: Var { + location: 86..90, + name: "True", + }, + doc: None, + location: 63..79, + name: "mint", + public: true, + return_annotation: Some( + Constructor { + location: 68..79, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 93, + on_test_failure: FailImmediately, + }, + ], location: 0..9, + name: "thing", params: [], + fallback: Function { + arguments: [ + UntypedArg { + by: ByName( + Discarded { + name: "_", + label: "_", + location: 0..9, + }, + ), + location: 0..9, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: ErrorTerm { + location: 0..9, + }, + doc: None, + location: 0..9, + name: "else", + public: true, + return_annotation: Some( + Constructor { + location: 0..9, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 8, + on_test_failure: FailImmediately, + }, }, ) diff --git a/crates/aiken-lang/src/parser/definition/snapshots/fallback.snap b/crates/aiken-lang/src/parser/definition/snapshots/fallback.snap new file mode 100644 index 00000000..1a523d56 --- /dev/null +++ b/crates/aiken-lang/src/parser/definition/snapshots/fallback.snap @@ -0,0 +1,161 @@ +--- +source: crates/aiken-lang/src/parser/definition/validator.rs +description: "Code:\n\nvalidator thing {\n spend (datum, rdmr, ctx) {\n True\n }\n\n mint (rdmr, ctx) {\n True\n }\n\n else (_) {\n fail\n }\n}\n" +--- +Validator( + Validator { + doc: None, + end_position: 122, + handlers: [ + Function { + arguments: [ + UntypedArg { + by: ByName( + Named { + name: "datum", + label: "datum", + location: 27..32, + }, + ), + location: 27..32, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "rdmr", + label: "rdmr", + location: 34..38, + }, + ), + location: 34..38, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "ctx", + label: "ctx", + location: 40..43, + }, + ), + location: 40..43, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: Var { + location: 51..55, + name: "True", + }, + doc: None, + location: 20..44, + name: "spend", + public: true, + return_annotation: Some( + Constructor { + location: 26..44, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 58, + on_test_failure: FailImmediately, + }, + Function { + arguments: [ + UntypedArg { + by: ByName( + Named { + name: "rdmr", + label: "rdmr", + location: 69..73, + }, + ), + location: 69..73, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "ctx", + label: "ctx", + location: 75..78, + }, + ), + location: 75..78, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: Var { + location: 86..90, + name: "True", + }, + doc: None, + location: 63..79, + name: "mint", + public: true, + return_annotation: Some( + Constructor { + location: 68..79, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 93, + on_test_failure: FailImmediately, + }, + ], + location: 0..9, + name: "thing", + params: [], + fallback: Function { + arguments: [ + UntypedArg { + by: ByName( + Discarded { + name: "_", + label: "_", + location: 104..105, + }, + ), + location: 104..105, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: ErrorTerm { + location: 113..117, + }, + doc: None, + location: 103..106, + name: "else", + public: true, + return_annotation: Some( + Constructor { + location: 103..106, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 120, + on_test_failure: FailImmediately, + }, + }, +) diff --git a/crates/aiken-lang/src/parser/definition/snapshots/validator.snap b/crates/aiken-lang/src/parser/definition/snapshots/validator.snap index fad9a357..0c56b13e 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/validator.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/validator.snap @@ -1,68 +1,112 @@ --- source: crates/aiken-lang/src/parser/definition/validator.rs -description: "Code:\n\nvalidator {\n fn foo(datum, rdmr, ctx) {\n True\n }\n}\n" +description: "Code:\n\nvalidator hello {\n spend (datum, rdmr, ctx) {\n True\n }\n}\n" --- Validator( Validator { doc: None, - end_position: 54, - fun: Function { + end_position: 60, + handlers: [ + Function { + arguments: [ + UntypedArg { + by: ByName( + Named { + name: "datum", + label: "datum", + location: 27..32, + }, + ), + location: 27..32, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "rdmr", + label: "rdmr", + location: 34..38, + }, + ), + location: 34..38, + annotation: None, + doc: None, + is_validator_param: false, + }, + UntypedArg { + by: ByName( + Named { + name: "ctx", + label: "ctx", + location: 40..43, + }, + ), + location: 40..43, + annotation: None, + doc: None, + is_validator_param: false, + }, + ], + body: Var { + location: 51..55, + name: "True", + }, + doc: None, + location: 20..44, + name: "spend", + public: true, + return_annotation: Some( + Constructor { + location: 26..44, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 58, + on_test_failure: FailImmediately, + }, + ], + location: 0..9, + name: "hello", + params: [], + fallback: Function { arguments: [ UntypedArg { by: ByName( - Named { - name: "datum", - label: "datum", - location: 21..26, + Discarded { + name: "_", + label: "_", + location: 0..9, }, ), - location: 21..26, - annotation: None, - doc: None, - is_validator_param: false, - }, - UntypedArg { - by: ByName( - Named { - name: "rdmr", - label: "rdmr", - location: 28..32, - }, - ), - location: 28..32, - annotation: None, - doc: None, - is_validator_param: false, - }, - UntypedArg { - by: ByName( - Named { - name: "ctx", - label: "ctx", - location: 34..37, - }, - ), - location: 34..37, + location: 0..9, annotation: None, doc: None, is_validator_param: false, }, ], - body: Var { - location: 45..49, - name: "True", + body: ErrorTerm { + location: 0..9, }, doc: None, - location: 14..38, - name: "foo", - public: false, - return_annotation: None, + location: 0..9, + name: "else", + public: true, + return_annotation: Some( + Constructor { + location: 0..9, + module: None, + name: "Bool", + arguments: [], + }, + ), return_type: (), - end_position: 52, + end_position: 8, on_test_failure: FailImmediately, }, - other_fun: None, - location: 0..9, - params: [], }, ) diff --git a/crates/aiken-lang/src/parser/definition/validator.rs b/crates/aiken-lang/src/parser/definition/validator.rs index cc54dbb4..bac310a0 100644 --- a/crates/aiken-lang/src/parser/definition/validator.rs +++ b/crates/aiken-lang/src/parser/definition/validator.rs @@ -1,66 +1,112 @@ -use chumsky::prelude::*; - +use super::function::param; use crate::{ - ast, - parser::{error::ParseError, token::Token}, + ast::{self, well_known}, + expr::UntypedExpr, + parser::{annotation, error::ParseError, expr, token::Token}, }; - -use super::function; +use chumsky::prelude::*; pub fn parser() -> impl Parser { just(Token::Validator) - .ignore_then( - function::param(true) + .ignore_then(select! {Token::Name {name} => name}) + .then( + param(true) .separated_by(just(Token::Comma)) .allow_trailing() .delimited_by(just(Token::LeftParen), just(Token::RightParen)) .map_with_span(|arguments, span| (arguments, span)) .or_not(), ) + // so far: validator my_validator(arg1: Whatever) .then( - function() + select! {Token::Name {name} => name} + .then(args_and_body()) + .map_with_span(|(name, mut function), span| { + function.name = name; + function.location.start = span.start; + + function + }) .repeated() - .at_least(1) - .at_most(2) - .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)) - .map(|defs| { - defs.into_iter().map(|def| { - let ast::UntypedDefinition::Fn(fun) = def else { - unreachable!("It should be a fn definition"); - }; + .then( + just(Token::Else) + .ignore_then(args_and_body().map_with_span(|mut function, span| { + function.name = well_known::VALIDATOR_ELSE.to_string(); + function.location.start = span.start; - fun - }) - }), + function + })) + .or_not(), + ) + .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)), ) - .map_with_span(|(opt_extra_params, mut functions), span| { - let (params, params_span) = opt_extra_params.unwrap_or(( - vec![], - ast::Span { - start: 0, - end: span.start + "validator".len(), - }, - )); + .map_with_span( + |((name, opt_extra_params), (handlers, opt_catch_all)), span| { + let (params, params_span) = opt_extra_params.unwrap_or(( + vec![], + ast::Span { + start: 0, + end: span.start + "validator".len(), + }, + )); - let fun = functions - .next() - .expect("unwrapping safe because there's 'at_least(1)' function"); - - let other_fun = functions.next(); - - ast::UntypedDefinition::Validator(ast::Validator { - doc: None, - fun, - other_fun, - location: ast::Span { + let location = ast::Span { start: span.start, // capture the span from the optional params end: params_span.end, - }, - params, - end_position: span.end - 1, - }) - }) + }; + + ast::UntypedDefinition::Validator(ast::Validator { + doc: None, + name, + handlers, + location, + params, + end_position: span.end - 1, + fallback: opt_catch_all + .unwrap_or(ast::UntypedValidator::default_fallback(location)), + }) + }, + ) +} + +pub fn args_and_body() -> impl Parser { + param(false) + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by(just(Token::LeftParen), just(Token::RightParen)) + .map_with_span(|arguments, span| (arguments, span)) + .then(just(Token::RArrow).ignore_then(annotation()).or_not()) + .then( + expr::sequence() + .or_not() + .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)), + ) + .map_with_span( + |(((arguments, args_span), return_annotation), body), span| { + let location = ast::Span { + start: span.start, + end: return_annotation + .as_ref() + .map(|l| l.location().end) + .unwrap_or_else(|| args_span.end), + }; + + ast::Function { + arguments, + body: body.unwrap_or_else(|| UntypedExpr::todo(None, span)), + doc: None, + location, + end_position: span.end - 1, + name: "temp".to_string(), + public: true, + return_annotation: return_annotation + .or(Some(ast::Annotation::boolean(location))), + return_type: (), + on_test_failure: ast::OnTestFailure::FailImmediately, + } + }, + ) } #[cfg(test)] @@ -71,8 +117,8 @@ mod tests { fn validator() { assert_definition!( r#" - validator { - fn foo(datum, rdmr, ctx) { + validator hello { + spend (datum, rdmr, ctx) { True } } @@ -84,16 +130,37 @@ mod tests { fn double_validator() { assert_definition!( r#" - validator { - fn foo(datum, rdmr, ctx) { + validator thing { + spend (datum, rdmr, ctx) { True } - fn bar(rdmr, ctx) { + mint (rdmr, ctx) { True } } "# ); } + + #[test] + fn fallback() { + assert_definition!( + r#" + validator thing { + spend (datum, rdmr, ctx) { + True + } + + mint (rdmr, ctx) { + True + } + + else (_) { + fail + } + } + "# + ); + } } diff --git a/crates/aiken-lang/src/parser/expr/pair.rs b/crates/aiken-lang/src/parser/expr/pair.rs index 59359baa..aad7a04b 100644 --- a/crates/aiken-lang/src/parser/expr/pair.rs +++ b/crates/aiken-lang/src/parser/expr/pair.rs @@ -1,5 +1,6 @@ use crate::{ - builtins::{PAIR, PRELUDE}, + ast::well_known, + builtins::PRELUDE, expr::UntypedExpr, parser::{error::ParseError, token::Token}, }; @@ -11,7 +12,7 @@ pub fn parser( select! {Token::Name { name } if name == PRELUDE => name} .then_ignore(just(Token::Dot)) .or_not() - .then_ignore(select! {Token::UpName { name } if name == PAIR => name}) + .then_ignore(select! {Token::UpName { name } if name == well_known::PAIR => name}) .ignore_then( r.clone() .separated_by(just(Token::Comma)) diff --git a/crates/aiken-lang/src/parser/pattern/pair.rs b/crates/aiken-lang/src/parser/pattern/pair.rs index 58be7614..d304d6d4 100644 --- a/crates/aiken-lang/src/parser/pattern/pair.rs +++ b/crates/aiken-lang/src/parser/pattern/pair.rs @@ -1,6 +1,5 @@ use crate::{ - ast::UntypedPattern, - builtins::PAIR, + ast::{well_known, UntypedPattern}, parser::{error::ParseError, token::Token}, }; use chumsky::prelude::*; @@ -8,7 +7,7 @@ use chumsky::prelude::*; pub fn parser( pattern: Recursive<'_, Token, UntypedPattern, ParseError>, ) -> impl Parser + '_ { - select! {Token::UpName { name } if name == PAIR => name} + select! {Token::UpName { name } if name == well_known::PAIR => name} .ignore_then(choice(( just(Token::LeftParen), just(Token::NewLineLeftParen), diff --git a/crates/aiken-lang/src/parser/utils.rs b/crates/aiken-lang/src/parser/utils.rs index 49016fd3..7849e651 100644 --- a/crates/aiken-lang/src/parser/utils.rs +++ b/crates/aiken-lang/src/parser/utils.rs @@ -175,6 +175,6 @@ macro_rules! assert_format { let (module2, extra2) = $crate::parser::module(&out, $crate::ast::ModuleKind::Lib).unwrap(); let mut out2 = String::new(); $crate::format::pretty(&mut out2, module2, extra2, &out); - assert_eq!(out, out2, "formatting isn't idempotent"); + pretty_assertions::assert_eq!(out, out2, "formatting isn't idempotent"); }; } diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index 9c333fee..b6abd8f7 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -111,8 +111,8 @@ fn bls12_381_ml_result_in_data_type() { #[test] fn validator_illegal_return_type() { let source_code = r#" - validator { - fn foo(d, r, c) { + validator foo { + spend(d, r, c) -> Int { 1 } } @@ -140,8 +140,8 @@ fn implicitly_discard_void() { #[test] fn validator_illegal_arity() { let source_code = r#" - validator { - fn foo(c) { + validator foo { + mint(c) { True } } @@ -318,19 +318,17 @@ fn mark_constructors_as_used_via_field_access() { bar: Int, } - validator { - fn foo(d: Datum, _r, _c) { - when d is { - D0(params) -> params.foo == 1 - D1(_params) -> False - } + fn spend(d: Datum, _r, _c) { + when d is { + D0(params) -> params.foo == 1 + D1(_params) -> False } } "#; - let (warnings, _) = check_validator(parse(source_code)).unwrap(); + let (warnings, _) = check(parse(source_code)).unwrap(); - assert_eq!(warnings.len(), 1) + assert_eq!(warnings.len(), 2) } #[test] @@ -359,8 +357,8 @@ fn expect_multi_patterns() { #[test] fn validator_correct_form() { let source_code = r#" - validator { - fn foo(d, r, c) { + validator foo { + spend(d: Option, r, oref, c) { True } } @@ -372,8 +370,8 @@ fn validator_correct_form() { #[test] fn validator_in_lib_warning() { let source_code = r#" - validator { - fn foo(c) { + validator foo { + spend(c) { True } } @@ -390,12 +388,12 @@ fn validator_in_lib_warning() { #[test] fn multi_validator() { let source_code = r#" - validator(foo: ByteArray, bar: Int) { - fn spend(_d, _r, _c) { + validator foo(foo: ByteArray, bar: Int) { + spend(_d: Option, _r, _oref, _c) { foo == #"aabb" } - fn mint(_r, _c) { + mint(_r, _p, _c) { bar == 0 } } @@ -409,12 +407,12 @@ fn multi_validator() { #[test] fn multi_validator_warning() { let source_code = r#" - validator(foo: ByteArray, bar: Int) { - fn spend(_d, _r, _c) { + validator foo(foo: ByteArray, bar: Int) { + spend(_d: Option, _r, _oref, _c) { foo == #"aabb" } - fn mint(_r, _c) { + mint(_r, _p, _c) { True } } @@ -459,8 +457,8 @@ fn exhaustiveness_simple() { #[test] fn validator_args_no_annotation() { let source_code = r#" - validator(d) { - fn foo(a, b, c) { + validator hello(d) { + spend(a: Option, b, oref, c) { True } } @@ -477,9 +475,13 @@ fn validator_args_no_annotation() { assert!(param.tipo.is_data()); }); - validator.fun.arguments.iter().for_each(|arg| { - assert!(arg.tipo.is_data()); - }) + validator.handlers[0] + .arguments + .iter() + .skip(1) + .for_each(|arg| { + assert!(arg.tipo.is_data()); + }) }) } @@ -2472,9 +2474,11 @@ fn validator_private_type_leak() { bar: Int, } - validator { - pub fn bar(datum: Datum, redeemer: Redeemer, _ctx) { - datum.foo == redeemer.bar + validator bar { + spend(datum: Option, redeemer: Redeemer, _oref, _ctx) { + expect Some(d) = datum + + d.foo == redeemer.bar } } "#; @@ -2496,30 +2500,11 @@ fn validator_public() { bar: Int, } - validator { - pub fn bar(datum: Datum, redeemer: Redeemer, _ctx) { - datum.foo == redeemer.bar - } - } - "#; + validator bar { + spend(datum: Option, redeemer: Redeemer, _oref, _ctx) { + expect Some(d) = datum - assert!(check_validator(parse(source_code)).is_ok()) -} - -#[test] -fn validator_private_everything() { - let source_code = r#" - type Datum { - foo: Int, - } - - type Redeemer { - bar: Int, - } - - validator { - fn bar(datum: Datum, redeemer: Redeemer, _ctx) { - datum.foo == redeemer.bar + d.foo == redeemer.bar } } "#; @@ -3065,3 +3050,173 @@ fn test_return_illegal() { Err((_, Error::IllegalTestType { .. })) )) } + +#[test] +fn validator_by_name() { + let source_code = r#" + validator foo { + mint(_redeemer: Data, policy_id: ByteArray, _self: Data) { + policy_id == "foo" + } + } + + test test_1() { + foo.mint(Void, "foo", Void) + } + "#; + + assert!(check_validator(parse(source_code)).is_ok()) +} + +#[test] +fn validator_by_name_unknown_handler() { + let source_code = r#" + validator foo { + mint(_redeemer: Data, policy_id: ByteArray, _self: Data) { + policy_id == "foo" + } + } + + test foo() { + foo.bar(Void, "foo", Void) + } + "#; + + assert!(matches!( + check_validator(parse(source_code)), + Err((_, Error::UnknownValidatorHandler { .. })) + )) +} + +#[test] +fn validator_by_name_module_duplicate() { + let source_code = r#" + use aiken/builtin + + validator builtin { + mint(_redeemer: Data, _policy_id: ByteArray, _self: Data) { + True + } + } + "#; + + assert!(matches!( + check_validator(parse(source_code)), + Err((_, Error::DuplicateName { .. })) + )) +} + +#[test] +fn validator_by_name_validator_duplicate_1() { + let source_code = r#" + validator foo { + mint(_redeemer: Data, _policy_id: ByteArray, _self: Data) { + True + } + } + + validator foo { + mint(_redeemer: Data, _policy_id: ByteArray, _self: Data) { + True + } + } + "#; + + assert!(matches!( + check_validator(parse(source_code)), + Err((_, Error::DuplicateName { .. })) + )) +} + +#[test] +fn validator_by_name_validator_duplicate_2() { + let source_code = r#" + validator foo { + mint(_redeemer: Data, _policy_id: ByteArray, _self: Data) { + True + } + + mint(_redeemer: Data, _policy_id: ByteArray, _self: Data) { + True + } + } + "#; + + assert!(matches!( + check_validator(parse(source_code)), + Err((_, Error::DuplicateName { .. })) + )) +} + +#[test] +fn exhaustive_handlers() { + let source_code = r#" + validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + } + "#; + + assert!(check_validator(parse(source_code)).is_ok()) +} + +#[test] +fn extraneous_fallback_on_exhaustive_handlers() { + let source_code = r#" + validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + + else (_) -> Bool { + fail + } + } + "#; + + assert!(matches!( + check_validator(parse(source_code)), + Err((_, Error::UnexpectedValidatorFallback { .. })) + )) +} diff --git a/crates/aiken-lang/src/tests/format.rs b/crates/aiken-lang/src/tests/format.rs index d2015390..353e04ed 100644 --- a/crates/aiken-lang/src/tests/format.rs +++ b/crates/aiken-lang/src/tests/format.rs @@ -198,18 +198,18 @@ fn format_preserve_newline_after_bool_expect() { fn format_validator() { assert_format!( r#" - validator ( ) { + validator thing ( ) { // What is the purpose of life - fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { True } } // What? - validator { + validator foo { /// Some documentation for foo - fn foo() { + foo() { Void } @@ -223,12 +223,12 @@ fn format_validator() { fn format_double_validator() { assert_format!( r#" - validator ( param1 : ByteArray ) { - fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { + validator foo( param1 : ByteArray ) { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { True } /// This is bar - fn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True } + mint(r: Redeemer, ctx : ScriptContext ) -> Bool { True } } "# ); @@ -238,12 +238,12 @@ fn format_double_validator() { fn format_double_validator_public() { assert_format!( r#" - validator ( param1 : ByteArray ) { - pub fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { + validator foo ( param1 : ByteArray ) { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { True } /// This is bar - pub fn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True } + mint(r: Redeemer, ctx : ScriptContext ) -> Bool { True } } "# ); @@ -967,20 +967,20 @@ fn format_anon_fn_pattern() { fn format_validator_pattern() { assert_format!( r#" - validator(Foo { a, b, .. }) { - fn foo() { todo } + validator foo(Foo { a, b, .. }) { + spend() { todo } } - validator([Bar] : List) { - fn bar() { todo } + validator foo([Bar] : List) { + spend() { todo } } - validator((Baz, Baz) as x) { - fn baz() { todo } + validator foo((Baz, Baz) as x) { + mint() { todo } } - validator((fst, snd) as x: Pair) { - fn fiz() { todo } + validator fiz((fst, snd) as x: Pair) { + spend() { todo } } "# ); @@ -1140,3 +1140,110 @@ fn format_long_pair() { "# ); } + +#[test] +fn format_validator_exhaustive_handlers() { + assert_format!( + r#" + validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + } + "# + ); +} + +#[test] +fn format_validator_exhaustive_handlers_extra_default_fallback() { + assert_format!( + r#" + validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + + else(_) { + fail + } + } + "# + ); +} + +#[test] +fn format_validator_exhaustive_handlers_extra_non_default_fallback() { + assert_format!( + r#" + validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + + else(_) { + True + } + } + "# + ); +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap b/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap index 6a4b92c9..23b4ee39 100644 --- a/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap +++ b/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap @@ -1,14 +1,18 @@ --- source: crates/aiken-lang/src/tests/format.rs -description: "Code:\n\n validator ( param1 : ByteArray ) {\n fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\n True\n }\n /// This is bar\nfn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True }\n }\n" +description: "Code:\n\n validator foo( param1 : ByteArray ) {\n spend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\n True\n }\n /// This is bar\nmint(r: Redeemer, ctx : ScriptContext ) -> Bool { True }\n }\n" --- -validator(param1: ByteArray) { - fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { +validator foo(param1: ByteArray) { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) { True } /// This is bar - fn bar(r: Redeemer, ctx: ScriptContext) -> Bool { + mint(r: Redeemer, ctx: ScriptContext) { True } + + else(_) { + fail + } } diff --git a/crates/aiken-lang/src/tests/snapshots/format_double_validator_public.snap b/crates/aiken-lang/src/tests/snapshots/format_double_validator_public.snap index 7582c958..b98cdc6c 100644 --- a/crates/aiken-lang/src/tests/snapshots/format_double_validator_public.snap +++ b/crates/aiken-lang/src/tests/snapshots/format_double_validator_public.snap @@ -1,14 +1,18 @@ --- source: crates/aiken-lang/src/tests/format.rs -description: "Code:\n\n validator ( param1 : ByteArray ) {\n pub fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\n True\n }\n /// This is bar\npub fn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True }\n }\n" +description: "Code:\n\n validator foo ( param1 : ByteArray ) {\n spend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\n True\n }\n /// This is bar\nmint(r: Redeemer, ctx : ScriptContext ) -> Bool { True }\n }\n" --- -validator(param1: ByteArray) { - pub fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { +validator foo(param1: ByteArray) { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) { True } /// This is bar - pub fn bar(r: Redeemer, ctx: ScriptContext) -> Bool { + mint(r: Redeemer, ctx: ScriptContext) { True } + + else(_) { + fail + } } diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator.snap b/crates/aiken-lang/src/tests/snapshots/format_validator.snap index cf306c77..7ef1f77b 100644 --- a/crates/aiken-lang/src/tests/snapshots/format_validator.snap +++ b/crates/aiken-lang/src/tests/snapshots/format_validator.snap @@ -1,21 +1,29 @@ --- source: crates/aiken-lang/src/tests/format.rs -description: "Code:\n\nvalidator ( ) {\n// What is the purpose of life\n\nfn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\nTrue\n}\n}\n\n// What?\nvalidator {\n /// Some documentation for foo\n fn foo() {\n Void\n }\n\n // I am lost\n}\n" +description: "Code:\n\nvalidator thing ( ) {\n// What is the purpose of life\n\nspend(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\nTrue\n}\n}\n\n// What?\nvalidator foo {\n /// Some documentation for foo\n foo() {\n Void\n }\n\n // I am lost\n}\n" --- -validator { +validator thing { // What is the purpose of life - fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool { + spend(d: Datum, r: Redeemer, ctx: ScriptContext) { True } + + else(_) { + fail + } } // What? -validator { +validator foo { /// Some documentation for foo - fn foo() { + foo() { Void } + else(_) { + fail + } + // I am lost } diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers.snap b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers.snap new file mode 100644 index 00000000..078ea81d --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers.snap @@ -0,0 +1,29 @@ +--- +source: crates/aiken-lang/src/tests/format.rs +description: "Code:\n\nvalidator foo {\n mint(_redeemer, _policy_id, _self) {\n True\n }\n\n spend(_datum, _redeemer, _policy_id, _self) {\n True\n }\n\n withdraw(_redeemer, _account, _self) {\n True\n }\n\n publish(_redeemer, _certificate, _self) {\n True\n }\n\n vote(_redeemer, _voter, _self) {\n True\n }\n\n propose(_redeemer, _proposal, _self) {\n True\n }\n}\n" +--- +validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_default_fallback.snap b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_default_fallback.snap new file mode 100644 index 00000000..f8052bee --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_default_fallback.snap @@ -0,0 +1,29 @@ +--- +source: crates/aiken-lang/src/tests/format.rs +description: "Code:\n\nvalidator foo {\n mint(_redeemer, _policy_id, _self) {\n True\n }\n\n spend(_datum, _redeemer, _policy_id, _self) {\n True\n }\n\n withdraw(_redeemer, _account, _self) {\n True\n }\n\n publish(_redeemer, _certificate, _self) {\n True\n }\n\n vote(_redeemer, _voter, _self) {\n True\n }\n\n propose(_redeemer, _proposal, _self) {\n True\n }\n\n else(_) {\n fail\n }\n}\n" +--- +validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_non_default_fallback.snap b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_non_default_fallback.snap new file mode 100644 index 00000000..2bcb68f4 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/format_validator_exhaustive_handlers_extra_non_default_fallback.snap @@ -0,0 +1,33 @@ +--- +source: crates/aiken-lang/src/tests/format.rs +description: "Code:\n\nvalidator foo {\n mint(_redeemer, _policy_id, _self) {\n True\n }\n\n spend(_datum, _redeemer, _policy_id, _self) {\n True\n }\n\n withdraw(_redeemer, _account, _self) {\n True\n }\n\n publish(_redeemer, _certificate, _self) {\n True\n }\n\n vote(_redeemer, _voter, _self) {\n True\n }\n\n propose(_redeemer, _proposal, _self) {\n True\n }\n\n else(_) {\n True\n }\n}\n" +--- +validator foo { + mint(_redeemer, _policy_id, _self) { + True + } + + spend(_datum, _redeemer, _policy_id, _self) { + True + } + + withdraw(_redeemer, _account, _self) { + True + } + + publish(_redeemer, _certificate, _self) { + True + } + + vote(_redeemer, _voter, _self) { + True + } + + propose(_redeemer, _proposal, _self) { + True + } + + else(_) { + True + } +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator_pattern.snap b/crates/aiken-lang/src/tests/snapshots/format_validator_pattern.snap index 74023392..bad9ce7a 100644 --- a/crates/aiken-lang/src/tests/snapshots/format_validator_pattern.snap +++ b/crates/aiken-lang/src/tests/snapshots/format_validator_pattern.snap @@ -1,27 +1,43 @@ --- source: crates/aiken-lang/src/tests/format.rs -description: "Code:\n\nvalidator(Foo { a, b, .. }) {\n fn foo() { todo }\n}\n\nvalidator([Bar] : List) {\n fn bar() { todo }\n}\n\nvalidator((Baz, Baz) as x) {\n fn baz() { todo }\n}\n\nvalidator((fst, snd) as x: Pair) {\n fn fiz() { todo }\n}\n" +description: "Code:\n\nvalidator foo(Foo { a, b, .. }) {\n spend() { todo }\n}\n\nvalidator foo([Bar] : List) {\n spend() { todo }\n}\n\nvalidator foo((Baz, Baz) as x) {\n mint() { todo }\n}\n\nvalidator fiz((fst, snd) as x: Pair) {\n spend() { todo }\n}\n" --- -validator(Foo { a, b, .. }) { - fn foo() { +validator foo(Foo { a, b, .. }) { + spend() { todo } + + else(_) { + fail + } } -validator([Bar]: List) { - fn bar() { +validator foo([Bar]: List) { + spend() { todo } + + else(_) { + fail + } } -validator((Baz, Baz) as x) { - fn baz() { +validator foo((Baz, Baz) as x) { + mint() { todo } + + else(_) { + fail + } } -validator((fst, snd) as x: Pair) { - fn fiz() { +validator fiz((fst, snd) as x: Pair) { + spend() { todo } + + else(_) { + fail + } } diff --git a/crates/aiken-lang/src/tipo.rs b/crates/aiken-lang/src/tipo.rs index 6507ac09..fad2f08e 100644 --- a/crates/aiken-lang/src/tipo.rs +++ b/crates/aiken-lang/src/tipo.rs @@ -1,10 +1,9 @@ use self::{environment::Environment, pretty::Printer}; use crate::{ ast::{ - Annotation, Constant, DataType, DataTypeKey, DefinitionLocation, ModuleKind, Span, - TypedDataType, + well_known, Annotation, Constant, DataType, DataTypeKey, DefinitionLocation, ModuleKind, + Span, TypedDataType, }, - builtins::{G1_ELEMENT, G2_ELEMENT, MILLER_LOOP_RESULT}, tipo::fields::FieldMap, }; use indexmap::IndexMap; @@ -23,6 +22,8 @@ mod pattern; mod pipe; pub mod pretty; +pub use environment::collapse_links; + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct TypeAliasAnnotation { pub alias: String, @@ -304,7 +305,7 @@ impl Type { pub fn is_int(&self) -> bool { match self { - Self::App { module, name, .. } if "Int" == name && module.is_empty() => true, + Self::App { module, name, .. } if well_known::INT == name && module.is_empty() => true, Self::Var { tipo, .. } => tipo.borrow().is_int(), _ => false, } @@ -312,7 +313,11 @@ impl Type { pub fn is_bytearray(&self) -> bool { match self { - Self::App { module, name, .. } if "ByteArray" == name && module.is_empty() => true, + Self::App { module, name, .. } + if well_known::BYTE_ARRAY == name && module.is_empty() => + { + true + } Self::Var { tipo, .. } => tipo.borrow().is_bytearray(), _ => false, } @@ -320,7 +325,7 @@ impl Type { pub fn is_bls381_12_g1(&self) -> bool { match self { - Self::App { module, name, .. } => G1_ELEMENT == name && module.is_empty(), + Self::App { module, name, .. } => well_known::G1_ELEMENT == name && module.is_empty(), Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g1(), _ => false, @@ -329,7 +334,7 @@ impl Type { pub fn is_bls381_12_g2(&self) -> bool { match self { - Self::App { module, name, .. } => G2_ELEMENT == name && module.is_empty(), + Self::App { module, name, .. } => well_known::G2_ELEMENT == name && module.is_empty(), Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g2(), _ => false, @@ -338,7 +343,9 @@ impl Type { pub fn is_ml_result(&self) -> bool { match self { - Self::App { module, name, .. } => MILLER_LOOP_RESULT == name && module.is_empty(), + Self::App { module, name, .. } => { + well_known::MILLER_LOOP_RESULT == name && module.is_empty() + } Self::Var { tipo, .. } => tipo.borrow().is_ml_result(), _ => false, @@ -422,31 +429,33 @@ impl Type { } pub fn is_generic(&self) -> bool { - match self { - Self::App { args, .. } => { - let mut is_a_generic = false; - for arg in args { - is_a_generic = is_a_generic || arg.is_generic(); - } - is_a_generic - } + !self.collect_generics().is_empty() + } - Self::Var { tipo, .. } => tipo.borrow().is_generic(), - Self::Tuple { elems, .. } => { - let mut is_a_generic = false; - for elem in elems { - is_a_generic = is_a_generic || elem.is_generic(); + pub fn collect_generics(&self) -> Vec> { + match self { + Self::App { args, .. } => args.iter().flat_map(|arg| arg.collect_generics()).collect(), + Self::Var { tipo, .. } => { + if tipo.borrow().is_generic() { + vec![self.clone().into()] + } else { + Vec::new() } - is_a_generic } - Self::Fn { args, ret, .. } => { - let mut is_a_generic = false; - for arg in args { - is_a_generic = is_a_generic || arg.is_generic(); - } - is_a_generic || ret.is_generic() + Self::Tuple { elems, .. } => elems + .iter() + .flat_map(|arg| arg.collect_generics()) + .collect(), + Self::Fn { args, ret, .. } => args + .iter() + .chain(std::iter::once(ret)) + .flat_map(|arg| arg.collect_generics()) + .collect(), + Self::Pair { fst, snd, .. } => { + let mut generics = fst.collect_generics(); + generics.extend(snd.collect_generics()); + generics } - Self::Pair { fst, snd, .. } => fst.is_generic() || snd.is_generic(), } } @@ -1068,7 +1077,7 @@ impl TypeVar { match self { TypeVar::Generic { .. } => true, TypeVar::Link { tipo } => tipo.is_generic(), - _ => false, + TypeVar::Unbound { .. } => false, } } @@ -1118,6 +1127,51 @@ impl ValueConstructor { } } + pub fn known_enum( + values: &mut HashMap, + tipo: Rc, + constructors: &[&str], + ) -> Vec { + for constructor in constructors { + values.insert( + constructor.to_string(), + ValueConstructor::public( + tipo.clone(), + ValueConstructorVariant::known_enum_variant(constructor, constructors.len(), 0), + ), + ); + } + + constructors + .iter() + .map(|constructor| constructor.to_string()) + .collect() + } + + pub fn known_adt( + values: &mut HashMap, + constructors: &[(&str, Rc)], + ) -> Vec { + for (constructor, tipo) in constructors { + values.insert( + constructor.to_string(), + ValueConstructor::public( + tipo.clone(), + ValueConstructorVariant::known_enum_variant( + constructor, + constructors.len(), + tipo.fn_arity().unwrap_or(0), + ), + ), + ); + } + + constructors + .iter() + .map(|(constructor, _)| constructor.to_string()) + .collect() + } + fn field_map(&self) -> Option<&FieldMap> { match &self.variant { ValueConstructorVariant::ModuleFn { field_map, .. } @@ -1248,6 +1302,17 @@ impl ValueConstructorVariant { pub fn is_local_variable(&self) -> bool { matches!(self, Self::LocalVariable { .. }) } + + pub fn known_enum_variant(name: &str, constructors_count: usize, arity: usize) -> Self { + ValueConstructorVariant::Record { + module: "".into(), + name: name.to_string(), + field_map: None::, + arity, + location: Span::empty(), + constructors_count: constructors_count as u16, + } + } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] @@ -1271,6 +1336,18 @@ pub struct TypeConstructor { pub tipo: Rc, } +impl TypeConstructor { + pub fn primitive(tipo: Rc) -> Self { + TypeConstructor { + location: Span::empty(), + parameters: tipo.collect_generics(), + tipo, + module: "".to_string(), + public: true, + } + } +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct AccessorsMap { pub public: bool, diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index 87760a9a..a9b4c3a6 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -9,10 +9,9 @@ use crate::{ ast::{ self, Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedFunction, - TypedPattern, UnqualifiedImport, UntypedArg, UntypedDefinition, UntypedFunction, Use, - Validator, PIPE_VARIABLE, + TypedPattern, TypedValidator, UnqualifiedImport, UntypedArg, UntypedDefinition, + UntypedFunction, Use, Validator, PIPE_VARIABLE, }, - builtins::{function, generic_var, pair, tuple, unbound_var}, tipo::{fields::FieldMap, TypeAliasAnnotation}, IdGenerator, }; @@ -58,6 +57,9 @@ pub struct Environment<'a> { /// Top-level function definitions from the module pub module_functions: HashMap, + /// Top-level validator definitions from the module + pub module_validators: HashMap)>, + /// Top-level functions that have been inferred pub inferred_functions: HashMap, @@ -183,7 +185,7 @@ impl<'a> Environment<'a> { if let Some((args, ret)) = new_value { *tipo.borrow_mut() = TypeVar::Link { - tipo: function(args.clone(), ret.clone()), + tipo: Type::function(args.clone(), ret.clone()), }; return Ok((args, Type::with_alias(ret, alias.clone()))); @@ -307,32 +309,51 @@ impl<'a> Environment<'a> { Definition::Validator(Validator { doc, end_position, - fun, - other_fun, + handlers, + name, + mut fallback, location, params, }) => { - let Definition::Fn(fun) = - self.generalise_definition(Definition::Fn(fun), module_name) + let handlers = handlers + .into_iter() + .map(|mut fun| { + let handler_name = TypedValidator::handler_name(&name, &fun.name); + + let old_name = fun.name; + fun.name = handler_name; + + let Definition::Fn(mut fun) = + self.generalise_definition(Definition::Fn(fun), module_name) + else { + unreachable!() + }; + + fun.name = old_name; + + fun + }) + .collect(); + + let fallback_name = TypedValidator::handler_name(&name, &fallback.name); + + let old_name = fallback.name; + fallback.name = fallback_name; + + let Definition::Fn(mut fallback) = + self.generalise_definition(Definition::Fn(fallback), module_name) else { unreachable!() }; - let other_fun = other_fun.map(|other_fun| { - let Definition::Fn(other_fun) = - self.generalise_definition(Definition::Fn(other_fun), module_name) - else { - unreachable!() - }; - - other_fun - }); + fallback.name = old_name; Definition::Validator(Validator { doc, + name, end_position, - fun, - other_fun, + handlers, + fallback, location, params, }) @@ -671,7 +692,7 @@ impl<'a> Environment<'a> { } Type::Fn { args, ret, alias } => Type::with_alias( - function( + Type::function( args.iter() .map(|t| self.instantiate(t.clone(), ids, hydrator)) .collect(), @@ -681,7 +702,7 @@ impl<'a> Environment<'a> { ), Type::Tuple { elems, alias } => Type::with_alias( - tuple( + Type::tuple( elems .iter() .map(|t| self.instantiate(t.clone(), ids, hydrator)) @@ -690,7 +711,7 @@ impl<'a> Environment<'a> { alias.clone(), ), Type::Pair { fst, snd, alias } => Type::with_alias( - pair( + Type::pair( self.instantiate(fst.clone(), ids, hydrator), self.instantiate(snd.clone(), ids, hydrator), ), @@ -758,6 +779,7 @@ impl<'a> Environment<'a> { module_types_constructors: prelude.types_constructors.clone(), module_values: HashMap::new(), module_functions: HashMap::new(), + module_validators: HashMap::new(), imported_modules: HashMap::new(), unused_modules: HashMap::new(), unqualified_imported_names: HashMap::new(), @@ -776,13 +798,13 @@ impl<'a> Environment<'a> { /// Create a new generic type that can stand in for any type. pub fn new_generic_var(&mut self) -> Rc { - generic_var(self.next_uid()) + Type::generic_var(self.next_uid()) } /// Create a new unbound type that is a specific type, we just don't /// know which one yet. pub fn new_unbound_var(&mut self) -> Rc { - unbound_var(self.next_uid()) + Type::unbound_var(self.next_uid()) } pub fn next_uid(&mut self) -> u64 { @@ -815,9 +837,7 @@ impl<'a> Environment<'a> { let module_info = self.find_module(module, *location)?; if module_info.kind.is_validator() - && (self.current_kind.is_lib() - || self.current_kind.is_env() - || !self.current_module.starts_with("tests")) + && (self.current_kind.is_lib() || self.current_kind.is_env()) { return Err(Error::ValidatorImported { location: *location, @@ -1162,12 +1182,12 @@ impl<'a> Environment<'a> { #[allow(clippy::too_many_arguments)] fn register_function( &mut self, - name: &'a str, + name: &str, arguments: &[UntypedArg], return_annotation: &Option, module_name: &String, hydrators: &mut HashMap, - names: &mut HashMap<&'a str, &'a Span>, + names: &mut HashMap, location: &'a Span, ) -> Result<(), Error> { assert_unique_value_name(names, name, location)?; @@ -1195,7 +1215,7 @@ impl<'a> Environment<'a> { let return_type = hydrator.type_from_option_annotation(return_annotation, self)?; - let tipo = function(arg_types, return_type); + let tipo = Type::function(arg_types, return_type); // Keep track of which types we create from annotations so we can know // which generic types not to instantiate later when performing @@ -1224,7 +1244,7 @@ impl<'a> Environment<'a> { def: &'a UntypedDefinition, module_name: &String, hydrators: &mut HashMap, - names: &mut HashMap<&'a str, &'a Span>, + names: &mut HashMap, kind: ModuleKind, ) -> Result<(), Error> { match def { @@ -1247,58 +1267,104 @@ impl<'a> Environment<'a> { } Definition::Validator(Validator { - fun, - other_fun, + handlers, + fallback, params, + name, doc: _, - location: _, + location, end_position: _, }) if kind.is_validator() => { - let default_annotation = |mut arg: UntypedArg| { + let default_annotation = |mut arg: UntypedArg, ann: Annotation| { if arg.annotation.is_none() { - arg.annotation = Some(Annotation::data(arg.location)); - + arg.annotation = Some(ann); arg } else { arg } }; - let temp_params: Vec = params - .iter() - .cloned() - .chain(fun.arguments.clone()) - .map(default_annotation) - .collect(); + let mut handler_names = vec![]; - self.register_function( - &fun.name, - &temp_params, - &fun.return_annotation, - module_name, - hydrators, - names, - &fun.location, - )?; + let params_len = params.len(); - if let Some(other) = other_fun { + for handler in handlers { let temp_params: Vec = params .iter() .cloned() - .chain(other.arguments.clone()) - .map(default_annotation) + .chain(handler.arguments.clone()) + .enumerate() + .map(|(ix, arg)| { + let is_datum = handler.is_spend() && ix == params_len; + let is_mint_policy = handler.is_mint() && ix == params_len + 1; + let location = arg.location; + default_annotation( + arg, + if is_datum { + Annotation::option(Annotation::data(location)) + } else if is_mint_policy { + Annotation::bytearray(location) + } else { + Annotation::data(location) + }, + ) + }) .collect(); + handler_names.push(handler.name.clone()); + self.register_function( - &other.name, + &TypedValidator::handler_name(name.as_str(), handler.name.as_str()), &temp_params, - &other.return_annotation, + &handler.return_annotation, module_name, hydrators, names, - &other.location, + &handler.location, )?; } + + let temp_params: Vec = params + .iter() + .cloned() + .chain(fallback.arguments.clone()) + .map(|arg| { + let location = arg.location; + default_annotation(arg, Annotation::data(location)) + }) + .collect(); + + self.register_function( + &TypedValidator::handler_name(name.as_str(), fallback.name.as_str()), + &temp_params, + &fallback.return_annotation, + module_name, + hydrators, + names, + &fallback.location, + )?; + + handler_names.push(fallback.name.clone()); + + let err_duplicate_name = |previous_location: Span| { + Err(Error::DuplicateName { + name: name.to_string(), + previous_location, + location: location.map_end(|end| end + 1 + name.len()), + }) + }; + + if let Some((previous_location, _)) = self.imported_modules.get(name) { + return err_duplicate_name(*previous_location); + } + + match self + .module_validators + .insert(name.to_string(), (*location, handler_names)) + { + Some((previous_location, _)) => err_duplicate_name(previous_location), + None => Ok(()), + }? } Definition::Validator(Validator { location, .. }) => { @@ -1395,7 +1461,7 @@ impl<'a> Environment<'a> { // Insert constructor function into module scope let typ = match constructor.arguments.len() { 0 => typ.clone(), - _ => function(args_types, typ.clone()), + _ => Type::function(args_types, typ.clone()), }; let constructor_info = ValueConstructorVariant::Record { @@ -1910,11 +1976,11 @@ fn assert_unique_type_name<'a>( } fn assert_unique_value_name<'a>( - names: &mut HashMap<&'a str, &'a Span>, - name: &'a str, + names: &mut HashMap, + name: &str, location: &'a Span, ) -> Result<(), Error> { - match names.insert(name, location) { + match names.insert(name.to_string(), location) { Some(previous_location) => Err(Error::DuplicateName { name: name.to_string(), previous_location: *previous_location, @@ -1925,11 +1991,11 @@ fn assert_unique_value_name<'a>( } fn assert_unique_const_name<'a>( - names: &mut HashMap<&'a str, &'a Span>, - name: &'a str, + names: &mut HashMap, + name: &str, location: &'a Span, ) -> Result<(), Error> { - match names.insert(name, location) { + match names.insert(name.to_string(), location) { Some(previous_location) => Err(Error::DuplicateConstName { name: name.to_string(), previous_location: *previous_location, @@ -1948,7 +2014,7 @@ pub(super) fn assert_no_labeled_arguments(args: &[CallArg]) -> Option<(Spa None } -pub(super) fn collapse_links(t: Rc) -> Rc { +pub fn collapse_links(t: Rc) -> Rc { if let Type::Var { tipo, alias } = t.deref() { if let TypeVar::Link { tipo } = tipo.borrow().deref() { return Type::with_alias(tipo.clone(), alias.clone()); @@ -1993,7 +2059,7 @@ pub(crate) fn generalise(t: Rc, ctx_level: usize) -> Rc { match t.deref() { Type::Var { tipo, alias } => Type::with_alias( match tipo.borrow().deref() { - TypeVar::Unbound { id } => generic_var(*id), + TypeVar::Unbound { id } => Type::generic_var(*id), TypeVar::Link { tipo } => generalise(tipo.clone(), ctx_level), TypeVar::Generic { .. } => Rc::new(Type::Var { tipo: tipo.clone(), @@ -2027,7 +2093,7 @@ pub(crate) fn generalise(t: Rc, ctx_level: usize) -> Rc { } Type::Fn { args, ret, alias } => Type::with_alias( - function( + Type::function( args.iter() .map(|t| generalise(t.clone(), ctx_level)) .collect(), @@ -2037,7 +2103,7 @@ pub(crate) fn generalise(t: Rc, ctx_level: usize) -> Rc { ), Type::Tuple { elems, alias } => Type::with_alias( - tuple( + Type::tuple( elems .iter() .map(|t| generalise(t.clone(), ctx_level)) @@ -2046,7 +2112,7 @@ pub(crate) fn generalise(t: Rc, ctx_level: usize) -> Rc { alias.clone(), ), Type::Pair { fst, snd, alias } => Type::with_alias( - pair( + Type::pair( generalise(fst.clone(), ctx_level), generalise(snd.clone(), ctx_level), ), diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 8f4fa449..e40a6d48 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -8,6 +8,7 @@ use crate::{ pretty::Documentable, }; use indoc::formatdoc; +use itertools::Itertools; use miette::{Diagnostic, LabeledSpan}; use ordinal::Ordinal; use owo_colors::{ @@ -489,15 +490,21 @@ If you really meant to return that last expression, try to replace it with the f name: String, }, - #[error("I found a multi-validator where both take the same number of arguments.\n")] - #[diagnostic(code("illegal::multi_validator"))] - #[diagnostic(help("Multi-validators cannot take the same number of arguments. One must take 3 arguments\nand the other must take 2 arguments. Both of these take {} arguments.", count.to_string().purple()))] - MultiValidatorEqualArgs { - #[label("{} here", count)] + #[error( + "I stumbled upon an invalid (non-local) clause guard '{}'.\n", + name.if_supports_color(Stdout, |s| s.purple()) + )] + #[diagnostic(url( + "https://aiken-lang.org/language-tour/control-flow#checking-equality-and-ordering-in-patterns" + ))] + #[diagnostic(code("illegal::clause_guard"))] + #[diagnostic(help( + "There are some conditions regarding what can be used in a guard. Values must be either local to the function, or defined as module constants. You can't use functions or records in there." + ))] + NonLocalClauseGuardVariable { + #[label] location: Span, - #[label("and {} here", count)] - other_location: Span, - count: usize, + name: String, }, #[error("I tripped over an attempt to access elements on something that isn't indexable.\n")] @@ -1021,7 +1028,8 @@ The best thing to do from here is to remove it."#))] ))] IncorrectValidatorArity { count: u32, - #[label("{} arguments", if *count < 2 { "not enough" } else { "too many" })] + expected: u32, + #[label("{} arguments", if count < expected { "not enough" } else { "too many" })] location: Span, }, @@ -1063,6 +1071,46 @@ The best thing to do from here is to remove it."#))] function: UntypedFunction, location: Span, }, + + #[error("I found a validator handler referring to an unknown purpose.\n")] + #[diagnostic(code("unknown::purpose"))] + #[diagnostic(help( + "Handler must be named after a known purpose. Here is a list of available purposes:\n{}", + available_purposes + .iter() + .map(|p| format!("-> {}", p.if_supports_color(Stdout, |s| s.green()))) + .join("\n") + ))] + UnknownPurpose { + #[label("unknown purpose")] + location: Span, + available_purposes: Vec, + }, + + #[error("I could not find an appropriate handler in the validator definition\n")] + #[diagnostic(code("unknown::handler"))] + #[diagnostic(help( + "When referring to a validator handler via record access, you must refer to one of the declared handlers:\n{}", + available_handlers + .iter() + .map(|p| format!("-> {}", p.if_supports_color(Stdout, |s| s.green()))) + .join("\n") + ))] + UnknownValidatorHandler { + #[label("unknown validator handler")] + location: Span, + available_handlers: Vec, + }, + + #[error("I caught an extraneous fallback handler in an already exhaustive validator\n")] + #[diagnostic(code("extraneous::fallback"))] + #[diagnostic(help( + "Validator handlers must be exhaustive and either cover all purposes, or provide a fallback handler. Here, you have successfully covered all script purposes with your handler, but left an extraneous fallback branch. I cannot let that happen, but removing it for you would probably be deemed rude. So please, remove the fallback." + ))] + UnexpectedValidatorFallback { + #[label("redundant fallback handler")] + fallback: Span, + }, } impl ExtraData for Error { @@ -1093,7 +1141,7 @@ impl ExtraData for Error { | Error::LastExpressionIsAssignment { .. } | Error::LogicalOpChainMissingExpr { .. } | Error::MissingVarInAlternativePattern { .. } - | Error::MultiValidatorEqualArgs { .. } + | Error::NonLocalClauseGuardVariable { .. } | Error::NotIndexable { .. } | Error::NotExhaustivePatternMatch { .. } | Error::NotFn { .. } @@ -1122,6 +1170,9 @@ impl ExtraData for Error { | Error::UnexpectedMultiPatternAssignment { .. } | Error::ExpectOnOpaqueType { .. } | Error::ValidatorMustReturnBool { .. } + | Error::UnknownPurpose { .. } + | Error::UnknownValidatorHandler { .. } + | Error::UnexpectedValidatorFallback { .. } | Error::MustInferFirst { .. } => None, Error::UnknownType { name, .. } diff --git a/crates/aiken-lang/src/tipo/exhaustive.rs b/crates/aiken-lang/src/tipo/exhaustive.rs index 88df69fc..71979425 100644 --- a/crates/aiken-lang/src/tipo/exhaustive.rs +++ b/crates/aiken-lang/src/tipo/exhaustive.rs @@ -1,7 +1,6 @@ use crate::{ ast, - builtins::{self}, - tipo::{self, environment::Environment, error::Error}, + tipo::{self, environment::Environment, error::Error, Type}, }; use itertools::Itertools; use std::{collections::BTreeMap, iter, ops::Deref}; @@ -500,8 +499,8 @@ fn pretty_tail(tail: Pattern) -> String { } fn list_constructors() -> Vec { - let list_parameter = builtins::generic_var(0); - let list_type = builtins::list(list_parameter); + let list_parameter = Type::generic_var(0); + let list_type = Type::list(list_parameter); vec![ tipo::ValueConstructor { diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 1df80e83..2e2e16e0 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -14,13 +14,10 @@ use crate::{ ByteArrayFormatPreference, CallArg, Constant, Curve, Function, IfBranch, LogicalOpChainKind, Pattern, RecordUpdateSpread, Span, TraceKind, TraceLevel, Tracing, TypedArg, TypedCallArg, TypedClause, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, - UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, UntypedIfBranch, - UntypedPattern, UntypedRecordUpdateArg, - }, - builtins::{ - bool, byte_array, data, from_default_function, function, g1_element, g2_element, int, list, - pair, string, tuple, void, BUILTIN, + TypedValidator, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, + UntypedIfBranch, UntypedPattern, UntypedRecordUpdateArg, }, + builtins::{from_default_function, BUILTIN}, expr::{FnStyle, TypedExpr, UntypedExpr}, format, tipo::{fields::FieldMap, DefaultFunction, PatternConstructor, TypeVar}, @@ -163,7 +160,7 @@ pub(crate) fn infer_function( let args_types = arguments.iter().map(|a| a.tipo.clone()).collect(); - let tipo = function(args_types, return_type); + let tipo = Type::function(args_types, return_type); let safe_to_generalise = !expr_typer.ungeneralised_function_used; @@ -594,15 +591,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::ByteArray { location, bytes, - tipo: byte_array(), + tipo: Type::byte_array(), }) } fn infer_curve_point(&mut self, curve: Curve, location: Span) -> Result { let tipo = match curve { Curve::Bls12_381(point) => match point { - Bls12_381Point::G1(_) => g1_element(), - Bls12_381Point::G2(_) => g2_element(), + Bls12_381Point::G1(_) => Type::g1_element(), + Bls12_381Point::G2(_) => Type::g2_element(), }, }; @@ -631,7 +628,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { module: String::new(), constructors_count: 2, }, - tipo: bool(), + tipo: Type::bool(), }, }; @@ -648,14 +645,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { module: String::new(), constructors_count: 2, }, - tipo: bool(), + tipo: Type::bool(), }, }; let text = match self.tracing.trace_level(false) { TraceLevel::Verbose => Some(TypedExpr::String { location, - tipo: string(), + tipo: Type::string(), value: format!( "{} ? False", format::Formatter::new() @@ -668,7 +665,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let typed_value = self.infer(value)?; - self.unify(bool(), typed_value.tipo(), typed_value.location(), false)?; + self.unify( + Type::bool(), + typed_value.tipo(), + typed_value.location(), + false, + )?; match text { None => Ok(typed_value), @@ -682,11 +684,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> { }], final_else: Box::new(TypedExpr::Trace { location, - tipo: bool(), + tipo: Type::bool(), text: Box::new(text), then: Box::new(var_false), }), - tipo: bool(), + tipo: Type::bool(), }), } } @@ -714,22 +716,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> { return Ok(TypedExpr::BinOp { location, name, - tipo: bool(), + tipo: Type::bool(), left: Box::new(left), right: Box::new(right), }); } - BinOp::And => (bool(), bool()), - BinOp::Or => (bool(), bool()), - BinOp::LtInt => (int(), bool()), - BinOp::LtEqInt => (int(), bool()), - BinOp::GtEqInt => (int(), bool()), - BinOp::GtInt => (int(), bool()), - BinOp::AddInt => (int(), int()), - BinOp::SubInt => (int(), int()), - BinOp::MultInt => (int(), int()), - BinOp::DivInt => (int(), int()), - BinOp::ModInt => (int(), int()), + BinOp::And => (Type::bool(), Type::bool()), + BinOp::Or => (Type::bool(), Type::bool()), + BinOp::LtInt => (Type::int(), Type::bool()), + BinOp::LtEqInt => (Type::int(), Type::bool()), + BinOp::GtEqInt => (Type::int(), Type::bool()), + BinOp::GtInt => (Type::int(), Type::bool()), + BinOp::AddInt => (Type::int(), Type::int()), + BinOp::SubInt => (Type::int(), Type::int()), + BinOp::MultInt => (Type::int(), Type::int()), + BinOp::DivInt => (Type::int(), Type::int()), + BinOp::ModInt => (Type::int(), Type::int()), }; let left = self.infer(left)?; @@ -896,8 +898,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let value = self.infer(value)?; let tipo = match op { - UnOp::Not => bool(), - UnOp::Negate => int(), + UnOp::Not => Type::bool(), + UnOp::Negate => Type::int(), }; self.unify(tipo.clone(), value.tipo(), value.location(), false)?; @@ -916,6 +918,28 @@ impl<'a, 'b> ExprTyper<'a, 'b> { label: String, access_location: Span, ) -> Result { + if let UntypedExpr::Var { ref name, location } = container { + if let Some((_, available_handlers)) = self + .environment + .module_validators + .get(name.as_str()) + .cloned() + { + return self + .infer_var( + TypedValidator::handler_name(name.as_str(), label.as_str()), + location, + ) + .map_err(|err| match err { + Error::UnknownVariable { .. } => Error::UnknownValidatorHandler { + location: access_location.map(|_start, end| (location.end, end)), + available_handlers, + }, + _ => err, + }); + } + } + // Attempt to infer the container as a record access. If that fails, we may be shadowing the name // of an imported module, so attempt to infer the container as a module access. // TODO: Remove this cloning @@ -1603,7 +1627,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let condition = self.infer(branch.condition.clone())?; self.unify( - bool(), + Type::bool(), condition.tipo(), condition.type_defining_location(), false, @@ -1647,7 +1671,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let args_types = args.iter().map(|a| a.tipo.clone()).collect(); - let tipo = function(args_types, return_type); + let tipo = Type::function(args_types, return_type); Ok(TypedExpr::Fn { location, @@ -1745,7 +1769,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::UInt { location, value, - tipo: int(), + tipo: Type::int(), } } @@ -1772,7 +1796,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { ensure_serialisable(false, tipo.clone(), location)?; // Type check the ..tail, if there is one - let tipo = list(tipo); + let tipo = Type::list(tipo); let tail = match tail { Some(tail) => { @@ -1807,7 +1831,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { let typed_expression = self.infer(expression)?; self.unify( - bool(), + Type::bool(), typed_expression.tipo(), typed_expression.location(), false, @@ -1831,7 +1855,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .rev() .reduce(|acc, typed_expression| TypedExpr::BinOp { location, - tipo: bool(), + tipo: Type::bool(), name, left: typed_expression.into(), right: acc.into(), @@ -2151,7 +2175,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TypedExpr::String { location, value, - tipo: string(), + tipo: Type::string(), } } @@ -2169,7 +2193,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::Pair { location, - tipo: pair(typed_fst.tipo(), typed_snd.tipo()), + tipo: Type::pair(typed_fst.tipo(), typed_snd.tipo()), fst: typed_fst.into(), snd: typed_snd.into(), }) @@ -2187,7 +2211,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { typed_elems.push(typed_elem); } - let tipo = tuple(typed_elems.iter().map(|e| e.tipo()).collect()); + let tipo = Type::tuple(typed_elems.iter().map(|e| e.tipo()).collect()); Ok(TypedExpr::Tuple { location, @@ -2255,9 +2279,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { fn infer_trace_arg(&mut self, arg: UntypedExpr) -> Result { let typed_arg = self.infer(arg)?; - match self.unify(string(), typed_arg.tipo(), typed_arg.location(), false) { + match self.unify( + Type::string(), + typed_arg.tipo(), + typed_arg.location(), + false, + ) { Err(_) => { - self.unify(data(), typed_arg.tipo(), typed_arg.location(), true)?; + self.unify(Type::data(), typed_arg.tipo(), typed_arg.location(), true)?; Ok(diagnose_expr(typed_arg)) } Ok(()) => Ok(typed_arg), @@ -2291,7 +2320,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { TraceLevel::Silent => Ok(then), TraceLevel::Compact => { let text = self.infer(label)?; - self.unify(string(), text.tipo(), text.location(), false)?; + self.unify(Type::string(), text.tipo(), text.location(), false)?; Ok(TypedExpr::Trace { location, tipo, @@ -2307,7 +2336,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { } else { let delimiter = |ix| TypedExpr::String { location: Span::empty(), - tipo: string(), + tipo: Type::string(), value: if ix == 0 { ": " } else { ", " }.to_string(), }; typed_arguments @@ -2594,7 +2623,7 @@ fn assert_assignment(expr: TypedExpr) -> Result { if expr.tipo().is_void() { return Ok(TypedExpr::Assignment { location: expr.location(), - tipo: void(), + tipo: Type::void(), value: expr.clone().into(), pattern: Pattern::Constructor { is_record: false, @@ -2607,7 +2636,7 @@ fn assert_assignment(expr: TypedExpr) -> Result { arguments: vec![], module: None, spread_location: None, - tipo: void(), + tipo: Type::void(), }, kind: AssignmentKind::let_(), }); @@ -2713,7 +2742,7 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr { name: "diagnostic".to_string(), constructor: ValueConstructor { public: true, - tipo: function(vec![data(), byte_array()], byte_array()), + tipo: Type::function(vec![Type::data(), Type::byte_array()], Type::byte_array()), variant: ValueConstructorVariant::ModuleFn { name: "diagnostic".to_string(), field_map: None, @@ -2728,13 +2757,13 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr { let location = expr.location(); TypedExpr::Call { - tipo: string(), + tipo: Type::string(), fun: Box::new(decode_utf8.clone()), args: vec![CallArg { label: None, location: expr.location(), value: TypedExpr::Call { - tipo: byte_array(), + tipo: Type::byte_array(), fun: Box::new(diagnostic.clone()), args: vec![ CallArg { @@ -2746,7 +2775,7 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr { label: None, location, value: TypedExpr::ByteArray { - tipo: byte_array(), + tipo: Type::byte_array(), bytes: vec![], location, }, @@ -2785,7 +2814,7 @@ fn append_string_expr(left: TypedExpr, right: TypedExpr) -> TypedExpr { TypedExpr::Call { location: Span::empty(), - tipo: string(), + tipo: Type::string(), fun: Box::new(append_string.clone()), args: vec![ CallArg { diff --git a/crates/aiken-lang/src/tipo/hydrator.rs b/crates/aiken-lang/src/tipo/hydrator.rs index 9b66a301..8d5d2bc4 100644 --- a/crates/aiken-lang/src/tipo/hydrator.rs +++ b/crates/aiken-lang/src/tipo/hydrator.rs @@ -3,11 +3,7 @@ use super::{ error::{Error, Warning}, Type, TypeConstructor, }; -use crate::{ - ast::Annotation, - builtins::{function, pair, tuple}, - tipo::Span, -}; +use crate::{ast::Annotation, tipo::Span}; use std::{collections::HashMap, rc::Rc}; /// The Hydrator takes an AST representing a type (i.e. a type annotation @@ -201,7 +197,7 @@ impl Hydrator { let ret = self.do_type_from_annotation(ret, environment, unbounds)?; - Ok(function(args, ret)) + Ok(Type::function(args, ret)) } Annotation::Var { name, location, .. } => match self.created_type_variables.get(name) { @@ -244,13 +240,13 @@ impl Hydrator { typed_elems.push(typed_elem) } - Ok(tuple(typed_elems)) + Ok(Type::tuple(typed_elems)) } Annotation::Pair { fst, snd, .. } => { let fst = self.do_type_from_annotation(fst, environment, unbounds)?; let snd = self.do_type_from_annotation(snd, environment, unbounds)?; - Ok(pair(fst, snd)) + Ok(Type::pair(fst, snd)) } }?; diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index a3e0ef6b..1c669236 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -9,10 +9,9 @@ use crate::{ ast::{ Annotation, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant, ModuleKind, RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition, - TypedFunction, TypedModule, UntypedDefinition, UntypedModule, Use, Validator, + TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, + UntypedValidator, Use, Validator, }, - builtins, - builtins::{fuzzer, generic_var}, tipo::{expr::infer_function, Span, Type, TypeVar}, IdGenerator, }; @@ -172,138 +171,151 @@ fn infer_definition( doc, location, end_position, - mut fun, - other_fun, + handlers, + mut fallback, params, + name, }) => { let params_length = params.len(); - let temp_params = params.iter().cloned().chain(fun.arguments); - fun.arguments = temp_params.collect(); environment.in_new_scope(|environment| { - let preregistered_fn = environment - .get_variable(&fun.name) - .expect("Could not find preregistered type for function"); + let fallback_name = TypedValidator::handler_name(&name, &fallback.name); - let preregistered_type = preregistered_fn.tipo.clone(); + put_params_in_scope(&fallback_name, environment, ¶ms); - let (args_types, _return_type) = preregistered_type - .function_types() - .expect("Preregistered type for fn was not a fn"); + let mut typed_handlers = vec![]; - for (ix, (arg, t)) in params - .iter() - .zip(args_types[0..params.len()].iter()) - .enumerate() - { - match &arg.arg_name(ix) { - ArgName::Named { - name, - label: _, - location: _, - } if arg.is_validator_param => { - environment.insert_variable( - name.to_string(), - ValueConstructorVariant::LocalVariable { - location: arg.location, - }, - t.clone(), - ); + for mut handler in handlers { + let typed_fun = environment.in_new_scope(|environment| { + let temp_params = params.iter().cloned().chain(handler.arguments); + handler.arguments = temp_params.collect(); - environment.init_usage( - name.to_string(), - EntityKind::Variable, - arg.location, - ); - } - ArgName::Named { .. } | ArgName::Discarded { .. } => (), - }; - } + let handler_name = TypedValidator::handler_name(&name, &handler.name); - let mut typed_fun = - infer_function(&fun, module_name, hydrators, environment, tracing)?; + let old_name = handler.name; + handler.name = handler_name; - if !typed_fun.return_type.is_bool() { - return Err(Error::ValidatorMustReturnBool { - return_type: typed_fun.return_type.clone(), - location: typed_fun.location, - }); - } + let mut typed_fun = + infer_function(&handler, module_name, hydrators, environment, tracing)?; - let typed_params = typed_fun - .arguments - .drain(0..params_length) - .map(|mut arg| { - if arg.tipo.is_unbound() { - arg.tipo = builtins::data(); - } + typed_fun.name = old_name; - arg - }) - .collect(); - - if typed_fun.arguments.len() < 2 || typed_fun.arguments.len() > 3 { - return Err(Error::IncorrectValidatorArity { - count: typed_fun.arguments.len() as u32, - location: typed_fun.location, - }); - } - - for arg in typed_fun.arguments.iter_mut() { - if arg.tipo.is_unbound() { - arg.tipo = builtins::data(); - } - } - - let typed_other_fun = other_fun - .map(|mut other| -> Result { - let params = params.into_iter().chain(other.arguments); - other.arguments = params.collect(); - - let mut other_typed_fun = - infer_function(&other, module_name, hydrators, environment, tracing)?; - - if !other_typed_fun.return_type.is_bool() { + if !typed_fun.return_type.is_bool() { return Err(Error::ValidatorMustReturnBool { - return_type: other_typed_fun.return_type.clone(), - location: other_typed_fun.location, - }); - } - - other_typed_fun.arguments.drain(0..params_length); - - if other_typed_fun.arguments.len() < 2 - || other_typed_fun.arguments.len() > 3 - { - return Err(Error::IncorrectValidatorArity { - count: other_typed_fun.arguments.len() as u32, - location: other_typed_fun.location, - }); - } - - if typed_fun.arguments.len() == other_typed_fun.arguments.len() { - return Err(Error::MultiValidatorEqualArgs { + return_type: typed_fun.return_type.clone(), location: typed_fun.location, - other_location: other_typed_fun.location, - count: other_typed_fun.arguments.len(), }); } - for arg in other_typed_fun.arguments.iter_mut() { + typed_fun.arguments.drain(0..params_length); + + if !typed_fun.has_valid_purpose_name() { + return Err(Error::UnknownPurpose { + location: typed_fun + .location + .map(|start, _end| (start, start + typed_fun.name.len())), + available_purposes: TypedValidator::available_handler_names(), + }); + } + + if typed_fun.arguments.len() != typed_fun.validator_arity() { + return Err(Error::IncorrectValidatorArity { + count: typed_fun.arguments.len() as u32, + expected: typed_fun.validator_arity() as u32, + location: typed_fun.location, + }); + } + + if typed_fun.is_spend() && !typed_fun.arguments[0].tipo.is_option() { + return Err(Error::CouldNotUnify { + location: typed_fun.arguments[0].location, + expected: Type::option(typed_fun.arguments[0].tipo.clone()), + given: typed_fun.arguments[0].tipo.clone(), + situation: None, + rigid_type_names: Default::default(), + }); + } + + for arg in typed_fun.arguments.iter_mut() { if arg.tipo.is_unbound() { - arg.tipo = builtins::data(); + arg.tipo = Type::data(); } } - Ok(other_typed_fun) - }) - .transpose()?; + Ok(typed_fun) + })?; + + typed_handlers.push(typed_fun); + } + + // NOTE: Duplicates are handled when registering handler names. So if we have N + // typed handlers, they are different. The -1 represents takes out the fallback + // handler name. + let is_exhaustive = + typed_handlers.len() >= TypedValidator::available_handler_names().len() - 1; + + if is_exhaustive + && fallback != UntypedValidator::default_fallback(fallback.location) + { + return Err(Error::UnexpectedValidatorFallback { + fallback: fallback.location, + }); + } + + let (typed_params, typed_fallback) = environment.in_new_scope(|environment| { + let temp_params = params.iter().cloned().chain(fallback.arguments); + fallback.arguments = temp_params.collect(); + + let old_name = fallback.name; + fallback.name = fallback_name; + + let mut typed_fallback = + infer_function(&fallback, module_name, hydrators, environment, tracing)?; + + typed_fallback.name = old_name; + + if !typed_fallback.return_type.is_bool() { + return Err(Error::ValidatorMustReturnBool { + return_type: typed_fallback.return_type.clone(), + location: typed_fallback.location, + }); + } + + let typed_params = typed_fallback + .arguments + .drain(0..params_length) + .map(|mut arg| { + if arg.tipo.is_unbound() { + arg.tipo = Type::data(); + } + + arg + }) + .collect(); + + if typed_fallback.arguments.len() != 1 { + return Err(Error::IncorrectValidatorArity { + count: typed_fallback.arguments.len() as u32, + expected: 1, + location: typed_fallback.location, + }); + } + + for arg in typed_fallback.arguments.iter_mut() { + if arg.tipo.is_unbound() { + arg.tipo = Type::data(); + } + } + + Ok((typed_params, typed_fallback)) + })?; Ok(Definition::Validator(Validator { doc, end_position, - fun: typed_fun, - other_fun: typed_other_fun, + handlers: typed_handlers, + fallback: typed_fallback, + name, location, params: typed_params, })) @@ -394,14 +406,14 @@ fn infer_definition( let is_bool = environment.unify( typed_f.return_type.clone(), - builtins::bool(), + Type::bool(), typed_f.location, false, ); let is_void = environment.unify( typed_f.return_type.clone(), - builtins::void(), + Type::void(), typed_f.location, false, ); @@ -653,10 +665,10 @@ fn infer_fuzzer( ) -> Result<(Annotation, Rc), Error> { let could_not_unify = || Error::CouldNotUnify { location: *location, - expected: fuzzer( + expected: Type::fuzzer( expected_inner_type .clone() - .unwrap_or_else(|| generic_var(0)), + .unwrap_or_else(|| Type::generic_var(0)), ), given: tipo.clone(), situation: None, @@ -692,7 +704,7 @@ fn infer_fuzzer( // `unify` now that we have figured out the type carried by the fuzzer. environment.unify( tipo.clone(), - fuzzer(wrapped.clone()), + Type::fuzzer(wrapped.clone()), *location, false, )?; @@ -779,3 +791,40 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result { } } } + +fn put_params_in_scope(name: &str, environment: &mut Environment, params: &[UntypedArg]) { + let preregistered_fn = environment + .get_variable(name) + .expect("Could not find preregistered type for function"); + + let preregistered_type = preregistered_fn.tipo.clone(); + + let (args_types, _return_type) = preregistered_type + .function_types() + .expect("Preregistered type for fn was not a fn"); + + for (ix, (arg, t)) in params + .iter() + .zip(args_types[0..params.len()].iter()) + .enumerate() + { + match &arg.arg_name(ix) { + ArgName::Named { + name, + label: _, + location: _, + } if arg.is_validator_param => { + environment.insert_variable( + name.to_string(), + ValueConstructorVariant::LocalVariable { + location: arg.location, + }, + t.clone(), + ); + + environment.init_usage(name.to_string(), EntityKind::Variable, arg.location); + } + ArgName::Named { .. } | ArgName::Discarded { .. } => (), + }; + } +} diff --git a/crates/aiken-lang/src/tipo/pattern.rs b/crates/aiken-lang/src/tipo/pattern.rs index 4a3064a6..c27e050e 100644 --- a/crates/aiken-lang/src/tipo/pattern.rs +++ b/crates/aiken-lang/src/tipo/pattern.rs @@ -6,10 +6,7 @@ use super::{ hydrator::Hydrator, PatternConstructor, Type, ValueConstructorVariant, }; -use crate::{ - ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern}, - builtins::{byte_array, int, list, pair, tuple}, -}; +use crate::ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern}; use itertools::Itertools; use std::{ collections::{HashMap, HashSet}, @@ -190,7 +187,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { value, base, } => { - self.environment.unify(tipo, int(), location, false)?; + self.environment.unify(tipo, Type::int(), location, false)?; Ok(Pattern::Int { location, @@ -205,7 +202,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { preferred_format, } => { self.environment - .unify(tipo, byte_array(), location, false)?; + .unify(tipo, Type::byte_array(), location, false)?; Ok(Pattern::ByteArray { location, @@ -231,7 +228,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> { .try_collect()?; let tail = match tail { - Some(tail) => Some(Box::new(self.unify(*tail, list(tipo), None, false)?)), + Some(tail) => Some(Box::new(self.unify( + *tail, + Type::list(tipo), + None, + false, + )?)), None => None, }; @@ -243,7 +245,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { } None => Err(Error::CouldNotUnify { - given: list(self.environment.new_unbound_var()), + given: Type::list(self.environment.new_unbound_var()), expected: tipo.clone(), situation: None, location, @@ -267,7 +269,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { let t_snd = self.environment.new_unbound_var(); self.environment.unify( - pair(t_fst.clone(), t_snd.clone()), + Type::pair(t_fst.clone(), t_snd.clone()), tipo, location, false, @@ -280,7 +282,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { } _ => Err(Error::CouldNotUnify { - given: pair( + given: Type::pair( self.environment.new_unbound_var(), self.environment.new_unbound_var(), ), @@ -322,8 +324,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> { .map(|_| self.environment.new_unbound_var()) .collect(); - self.environment - .unify(tuple(elems_types.clone()), tipo, location, false)?; + self.environment.unify( + Type::tuple(elems_types.clone()), + tipo, + location, + false, + )?; let mut patterns = vec![]; @@ -345,7 +351,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> { .collect(); Err(Error::CouldNotUnify { - given: tuple(elems_types), + given: Type::tuple(elems_types), expected: tipo, situation: None, location, diff --git a/crates/aiken-lang/src/tipo/pipe.rs b/crates/aiken-lang/src/tipo/pipe.rs index dc2e21b1..15692010 100644 --- a/crates/aiken-lang/src/tipo/pipe.rs +++ b/crates/aiken-lang/src/tipo/pipe.rs @@ -5,7 +5,6 @@ use super::{ }; use crate::{ ast::{AssignmentKind, CallArg, Pattern, Span, PIPE_VARIABLE}, - builtins::function, expr::{TypedExpr, UntypedExpr}, }; use std::{ops::Deref, rc::Rc}; @@ -257,7 +256,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> { .environment .unify( func.tipo(), - function(vec![self.argument_type.clone()], return_type.clone()), + Type::function(vec![self.argument_type.clone()], return_type.clone()), func.location(), if let Type::Fn { args, .. } = func.tipo().deref() { if let Some(typ) = args.first() { diff --git a/crates/aiken-lang/src/tipo/pretty.rs b/crates/aiken-lang/src/tipo/pretty.rs index ea89924d..a38b899f 100644 --- a/crates/aiken-lang/src/tipo/pretty.rs +++ b/crates/aiken-lang/src/tipo/pretty.rs @@ -296,10 +296,7 @@ fn resolve_alias( #[cfg(test)] mod tests { use super::*; - use crate::{ - builtins::{function, int}, - tipo::Span, - }; + use crate::tipo::{Span, Type}; use pretty_assertions::assert_eq; use std::cell::RefCell; @@ -490,7 +487,7 @@ mod tests { "?", ); assert_string!( - function( + Type::function( vec![Rc::new(Type::Var { tipo: Rc::new(RefCell::new(TypeVar::Unbound { id: 78 })), alias: None, @@ -503,7 +500,7 @@ mod tests { "fn(?) -> ?", ); assert_string!( - function( + Type::function( vec![Rc::new(Type::Var { tipo: Rc::new(RefCell::new(TypeVar::Generic { id: 78 })), alias: None, @@ -692,10 +689,16 @@ mod tests { #[test] fn function_test() { - assert_eq!(pretty_print(function(vec![], int())), "fn() -> Int"); + assert_eq!( + pretty_print(Type::function(vec![], Type::int())), + "fn() -> Int" + ); assert_eq!( - pretty_print(function(vec![int(), int(), int()], int())), + pretty_print(Type::function( + vec![Type::int(), Type::int(), Type::int()], + Type::int() + )), "fn(Int, Int, Int) -> Int" ); } diff --git a/crates/aiken-project/src/blueprint/mod.rs b/crates/aiken-project/src/blueprint/mod.rs index 86369656..7417bcc2 100644 --- a/crates/aiken-project/src/blueprint/mod.rs +++ b/crates/aiken-project/src/blueprint/mod.rs @@ -153,7 +153,7 @@ impl From<&Config> for Preamble { #[cfg(test)] mod tests { use super::*; - use aiken_lang::builtins; + use aiken_lang::tipo::Type; use schema::{Data, Declaration, Items, Schema}; use serde_json::{self, json}; use std::collections::HashMap; @@ -225,17 +225,17 @@ mod tests { fn serialize_with_definitions() { let mut definitions = Definitions::new(); definitions - .register::<_, Error>(&builtins::int(), &HashMap::new(), |_| { + .register::<_, Error>(&Type::int(), &HashMap::new(), |_| { Ok(Schema::Data(Data::Integer).into()) }) .unwrap(); definitions .register::<_, Error>( - &builtins::list(builtins::byte_array()), + &Type::list(Type::byte_array()), &HashMap::new(), |definitions| { let ref_bytes = definitions.register::<_, Error>( - &builtins::byte_array(), + &Type::byte_array(), &HashMap::new(), |_| Ok(Schema::Data(Data::Bytes).into()), )?; diff --git a/crates/aiken-project/src/blueprint/schema.rs b/crates/aiken-project/src/blueprint/schema.rs index be762017..88f391ce 100644 --- a/crates/aiken-project/src/blueprint/schema.rs +++ b/crates/aiken-project/src/blueprint/schema.rs @@ -4,7 +4,6 @@ use crate::{ }; use aiken_lang::{ ast::{Definition, TypedDataType, TypedDefinition}, - builtins::wrapped_redeemer, tipo::{pretty, Type, TypeVar}, }; use owo_colors::{OwoColorize, Stream::Stdout}; @@ -142,7 +141,7 @@ impl Annotated { ) -> Reference { definitions .register( - &wrapped_redeemer(type_info), + &Type::wrapped_redeemer(type_info), &HashMap::new(), |_| { Ok::<_, Error>(Annotated { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__annotated_data.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__annotated_data.snap index 3877b76f..3b94614b 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__annotated_data.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__annotated_data.snap @@ -1,9 +1,9 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\npub type Foo {\n foo: Int\n}\n\nvalidator {\n fn annotated_data(datum: Data, redeemer: Data, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type Foo {\n foo: Int\n}\n\nvalidator annotated_data {\n spend(datum: Option>, redeemer: Data, output_reference: Data, transpose: Data) {\n True\n }\n}\n" --- { - "title": "test_module.annotated_data", + "title": "test_module.annotated_data.spend", "datum": { "title": "datum", "schema": { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__free_vars.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__free_vars.snap index 708547f5..f0ee948d 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__free_vars.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__free_vars.snap @@ -1,6 +1,6 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\nvalidator {\n fn generics(redeemer: a, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\nvalidator generics {\n mint(redeemer: a, policy_id: ByteArray, transaction: Data) {\n True\n }\n}\n" --- Schema { error: Error { @@ -16,7 +16,7 @@ Schema { }, ], }, - location: 26..37, + location: 28..39, source_code: NamedSource { name: "", source: "", diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__generics.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__generics.snap index 55ac598c..35d47c7e 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__generics.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__generics.snap @@ -1,9 +1,15 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\ntype Either {\n Left(left)\n Right(right)\n}\n\ntype Interval {\n Finite(a)\n Infinite\n}\n\nvalidator {\n fn generics(redeemer: Either>, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type Either {\n Left(left)\n Right(right)\n}\n\npub type Interval {\n Finite(a)\n Infinite\n}\n\nvalidator generics {\n spend(datum: Option, redeemer: Either>, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.generics", + "title": "test_module.generics.spend", + "datum": { + "title": "datum", + "schema": { + "$ref": "#/definitions/Data" + } + }, "redeemer": { "title": "redeemer", "schema": { @@ -16,6 +22,10 @@ description: "Code:\n\ntype Either {\n Left(left)\n Right(rig "ByteArray": { "dataType": "bytes" }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, "Int": { "dataType": "integer" }, diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_2_tuples_as_list.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_2_tuples_as_list.snap index ed44c249..9bb8d0d0 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_2_tuples_as_list.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_2_tuples_as_list.snap @@ -1,9 +1,9 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\ntype Dict {\n inner: List<(ByteArray, value)>\n}\n\ntype UUID { UUID }\n\nvalidator {\n fn list_2_tuples_as_list(redeemer: Dict, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type Dict {\n inner: List<(ByteArray, value)>\n}\n\npub type UUID { UUID }\n\nvalidator list_2_tuples_as_list {\n mint(redeemer: Dict, policy_id: ByteArray, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.list_2_tuples_as_list", + "title": "test_module.list_2_tuples_as_list.mint", "redeemer": { "title": "redeemer", "schema": { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_pairs_as_map.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_pairs_as_map.snap index ab44d436..cd463992 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_pairs_as_map.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__list_pairs_as_map.snap @@ -1,9 +1,15 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\ntype Dict {\n inner: List>\n}\n\ntype UUID { UUID }\n\nvalidator {\n fn list_pairs_as_map(redeemer: Dict, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type Dict {\n inner: List>\n}\n\npub type UUID { UUID }\n\nvalidator list_pairs_as_map {\n spend(datum: Option, redeemer: Dict, _output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.list_pairs_as_map", + "title": "test_module.list_pairs_as_map.spend", + "datum": { + "title": "datum", + "schema": { + "$ref": "#/definitions/Data" + } + }, "redeemer": { "title": "redeemer", "schema": { @@ -16,6 +22,10 @@ description: "Code:\n\ntype Dict {\n inner: List, redeemer: Int, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.nested_data", + "title": "test_module.nested_data.spend", "datum": { "title": "datum", "schema": { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap index 0b14e043..247a3abe 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap @@ -1,6 +1,6 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\npub opaque type Rational {\n numerator: Int,\n denominator: Int,\n}\n\nvalidator {\n fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub opaque type Rational {\n numerator: Int,\n denominator: Int,\n}\n\nvalidator opaque_singleton_multi_variants {\n spend(datum: Option, redeemer: Rational, oref: Data, transaction: Data) {\n True\n }\n}\n" --- Schema { error: Error { @@ -16,7 +16,7 @@ Schema { }, ], }, - location: 117..135, + location: 141..159, source_code: NamedSource { name: "", source: "", diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap index ba397f99..e95c90f6 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap @@ -1,6 +1,6 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\npub opaque type Dict {\n inner: List<(ByteArray, value)>\n}\n\ntype UUID { UUID }\n\nvalidator {\n fn opaque_singleton_variants(redeemer: Dict, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub opaque type Dict {\n inner: List<(ByteArray, value)>\n}\n\npub type UUID { UUID }\n\nvalidator opaque_singleton_variants {\n spend(datum: Option, redeemer: Dict, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- Schema { error: Error { @@ -16,7 +16,7 @@ Schema { tipo: RefCell { value: Link { tipo: App { - public: false, + public: true, contains_opaque: false, module: "test_module", name: "UUID", @@ -47,7 +47,7 @@ Schema { }, ], }, - location: 137..162, + location: 165..190, source_code: NamedSource { name: "", source: "", diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_generic_types.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_generic_types.snap index 6b20e160..d30c8719 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_generic_types.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_generic_types.snap @@ -1,9 +1,9 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\npub type LinkedList {\n Cons(a, LinkedList)\n Nil\n}\n\npub type Foo {\n Foo {\n foo: LinkedList,\n }\n Bar {\n bar: Int,\n baz: (ByteArray, List>)\n }\n}\n\nvalidator {\n fn recursive_generic_types(datum: Foo, redeemer: LinkedList, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type LinkedList {\n Cons(a, LinkedList)\n Nil\n}\n\npub type Foo {\n Foo {\n foo: LinkedList,\n }\n Bar {\n bar: Int,\n baz: (ByteArray, List>)\n }\n}\n\nvalidator recursive_generic_types {\n spend(datum: Option, redeemer: LinkedList, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.recursive_generic_types", + "title": "test_module.recursive_generic_types.spend", "datum": { "title": "datum", "schema": { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_types.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_types.snap index 9a931f7f..b94b9723 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_types.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__recursive_types.snap @@ -1,9 +1,15 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\npub type Expr {\n Val(Int)\n Sum(Expr, Expr)\n Mul(Expr, Expr)\n}\n\nvalidator {\n fn recursive_types(redeemer: Expr, ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\npub type Expr {\n Val(Int)\n Sum(Expr, Expr)\n Mul(Expr, Expr)\n}\n\nvalidator recursive_types {\n spend(datum: Option, redeemer: Expr, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.recursive_types", + "title": "test_module.recursive_types.spend", + "datum": { + "title": "datum", + "schema": { + "$ref": "#/definitions/Data" + } + }, "redeemer": { "title": "redeemer", "schema": { @@ -13,6 +19,10 @@ description: "Code:\n\npub type Expr {\n Val(Int)\n Sum(Expr, Expr)\n Mul(Exp "compiledCode": "", "hash": "", "definitions": { + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, "Int": { "dataType": "integer" }, diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__simplified_hydra.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__simplified_hydra.snap index 0fefe40f..144c582d 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__simplified_hydra.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__simplified_hydra.snap @@ -1,9 +1,9 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\n/// On-chain state\ntype State {\n /// The contestation period as a number of seconds\n contestationPeriod: ContestationPeriod,\n /// List of public key hashes of all participants\n parties: List,\n utxoHash: Hash,\n}\n\n/// A Hash digest for a given algorithm.\ntype Hash = ByteArray\n\ntype Blake2b_256 { Blake2b_256 }\n\n/// Whatever\ntype ContestationPeriod {\n /// A positive, non-zero number of seconds.\n ContestationPeriod(Int)\n}\n\ntype Party =\n ByteArray\n\ntype Input {\n CollectCom\n Close\n /// Abort a transaction\n Abort\n}\n\nvalidator {\n fn simplified_hydra(datum: State, redeemer: Input, ctx: Data) {\n True\n }\n}\n" +description: "Code:\n\n/// On-chain state\npub type State {\n /// The contestation period as a number of seconds\n contestationPeriod: ContestationPeriod,\n /// List of public key hashes of all participants\n parties: List,\n utxoHash: Hash,\n}\n\n/// A Hash digest for a given algorithm.\npub type Hash = ByteArray\n\npub type Blake2b_256 { Blake2b_256 }\n\n/// Whatever\npub type ContestationPeriod {\n /// A positive, non-zero number of seconds.\n ContestationPeriod(Int)\n}\n\npub type Party =\n ByteArray\n\npub type Input {\n CollectCom\n Close\n /// Abort a transaction\n Abort\n}\n\nvalidator simplified_hydra {\n spend(datum: Option, redeemer: Input, output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.simplified_hydra", + "title": "test_module.simplified_hydra.spend", "datum": { "title": "datum", "schema": { diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__tuples.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__tuples.snap index 309e9c7b..1c92766e 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__tuples.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__tuples.snap @@ -1,9 +1,9 @@ --- source: crates/aiken-project/src/blueprint/validator.rs -description: "Code:\n\nvalidator {\n fn tuples(datum: (Int, ByteArray), redeemer: (Int, Int, Int), ctx: Void) {\n True\n }\n}\n" +description: "Code:\n\nvalidator tuples {\n spend(datum: Option<(Int, ByteArray)>, redeemer: (Int, Int, Int), output_reference: Data, transaction: Data) {\n True\n }\n}\n" --- { - "title": "test_module.tuples", + "title": "test_module.tuples.spend", "datum": { "title": "datum", "schema": { diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index 61db8c5f..1be58a9b 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -7,10 +7,10 @@ use super::{ }; use crate::module::{CheckedModule, CheckedModules}; use aiken_lang::{ - ast::{Annotation, TypedArg, TypedFunction, TypedValidator}, + ast::{well_known, Annotation, TypedArg, TypedFunction, TypedValidator}, gen_uplc::CodeGenerator, plutus_version::PlutusVersion, - tipo::Type, + tipo::{collapse_links, Type}, }; use miette::NamedSource; use serde; @@ -30,7 +30,8 @@ pub struct Validator { #[serde(skip_serializing_if = "Option::is_none")] pub datum: Option, - pub redeemer: Parameter, + #[serde(skip_serializing_if = "Option::is_none")] + pub redeemer: Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] @@ -52,29 +53,33 @@ impl Validator { def: &TypedValidator, plutus_version: &PlutusVersion, ) -> Vec> { - let is_multi_validator = def.other_fun.is_some(); - let mut program = MemoProgram::new(); - let mut validators = vec![Validator::create_validator_blueprint( - generator, - modules, - module, - def, - &def.fun, - is_multi_validator, - &mut program, - plutus_version, - )]; + let mut validators = vec![]; - if let Some(ref other_func) = def.other_fun { + for handler in &def.handlers { validators.push(Validator::create_validator_blueprint( generator, modules, module, def, - other_func, - is_multi_validator, + handler, + &mut program, + plutus_version, + )); + } + + // NOTE: Only push the fallback if all other validators have been successfully + // generated. Otherwise, we may fall into scenarios where we cannot generate validators + // (e.g. due to the presence of generics in datum/redeemer), which won't be caught by + // the else branch since it lacks arguments. + if validators.iter().all(|v| v.is_ok()) { + validators.push(Validator::create_validator_blueprint( + generator, + modules, + module, + def, + &def.fallback, &mut program, plutus_version, )); @@ -90,13 +95,9 @@ impl Validator { module: &CheckedModule, def: &TypedValidator, func: &TypedFunction, - is_multi_validator: bool, program: &mut MemoProgram, plutus_version: &PlutusVersion, ) -> Result { - let mut args = func.arguments.iter().rev(); - let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next()); - let mut definitions = Definitions::new(); let parameters = def @@ -123,53 +124,81 @@ impl Validator { }) .collect::>()?; - let datum = datum - .map(|datum| { - Annotated::from_type( - modules.into(), - tipo_or_annotation(module, datum), - &mut definitions, - ) - .map_err(|error| Error::Schema { - error, - location: datum.location, - source_code: NamedSource::new( - module.input_path.display().to_string(), - module.code.clone(), - ), - }) - }) - .transpose()? - .map(|schema| Parameter { - title: datum.map(|datum| datum.arg_name.get_label()), - schema, - }); + let (datum, redeemer) = if func.name == well_known::VALIDATOR_ELSE { + (None, None) + } else { + let mut args = func.arguments.iter().rev(); - let redeemer = Annotated::from_type( - modules.into(), - tipo_or_annotation(module, redeemer), - &mut definitions, - ) - .map_err(|error| Error::Schema { - error, - location: redeemer.location, - source_code: NamedSource::new( - module.input_path.display().to_string(), - module.code.clone(), - ), - }) - .map(|schema| Parameter { - title: Some(redeemer.arg_name.get_label()), - schema: match datum { - Some(..) if is_multi_validator => { - Annotated::as_wrapped_redeemer(&mut definitions, schema, redeemer.tipo.clone()) - } - _ => schema, - }, - })?; + let (_, _, redeemer, datum) = ( + args.next(), + args.next(), + args.next().expect("redeemer is always present"), + args.next(), + ); + + let datum = datum + .map(|datum| { + match datum.tipo.as_ref() { + Type::App { module: module_name, name, args, .. } if module_name.is_empty() && name == well_known::OPTION => { + let annotation = if let Some(Annotation::Constructor { arguments, .. }) = datum.annotation.as_ref() { + arguments.first().cloned().expect("Datum isn't an option but should be; this should have been caught by the type-checker!") + } else { + Annotation::data(datum.location) + }; + + Annotated::from_type( + modules.into(), + tipo_or_annotation(module, &TypedArg { + arg_name: datum.arg_name.clone(), + location: datum.location, + annotation: Some(annotation), + doc: datum.doc.clone(), + is_validator_param: datum.is_validator_param, + tipo: args.first().expect("Option always have a single type argument.").clone() + }), + &mut definitions, + ) + .map_err(|error| Error::Schema { + error, + location: datum.location, + source_code: NamedSource::new( + module.input_path.display().to_string(), + module.code.clone(), + ), + }) + }, + _ => panic!("Datum isn't an option but should be; this should have been caught by the type-checker!"), + } + }) + .transpose()? + .map(|schema| Parameter { + title: datum.map(|datum| datum.arg_name.get_label()), + schema, + }); + + let redeemer = Annotated::from_type( + modules.into(), + tipo_or_annotation(module, redeemer), + &mut definitions, + ) + .map_err(|error| Error::Schema { + error, + location: redeemer.location, + source_code: NamedSource::new( + module.input_path.display().to_string(), + module.code.clone(), + ), + }) + .map(|schema| Parameter { + title: Some(redeemer.arg_name.get_label()), + schema, + })?; + + (datum, Some(redeemer)) + }; Ok(Validator { - title: format!("{}.{}", &module.name, &func.name), + title: format!("{}.{}.{}", &module.name, &def.name, &func.name,), description: func.doc.clone(), parameters, datum, @@ -185,7 +214,7 @@ impl Validator { } pub fn tipo_or_annotation<'a>(module: &'a CheckedModule, arg: &'a TypedArg) -> &'a Type { - match *arg.tipo.borrow() { + match collapse_links(arg.tipo.clone()).borrow() { Type::App { module: ref module_name, name: ref type_name, @@ -274,7 +303,7 @@ mod tests { use aiken_lang::{ self, ast::{TraceLevel, Tracing}, - builtins, + tipo::Type, }; use std::collections::HashMap; use uplc::ast as uplc_ast; @@ -296,7 +325,7 @@ mod tests { let validators = Validator::from_checked_module(&modules, &mut generator, validator, def, &PlutusVersion::default()); - if validators.len() > 1 { + if validators.len() > 2 { panic!("Multi-validator given to test bench. Don't do that.") } @@ -338,7 +367,7 @@ mod tests { // "dataType": "integer" // } definitions - .register::<_, Error>(&builtins::int(), &HashMap::new(), |_| { + .register::<_, Error>(&Type::int(), &HashMap::new(), |_| { Ok(Schema::Data(Data::Integer).into()) }) .unwrap(); @@ -349,7 +378,7 @@ mod tests { // "dataType": "bytes" // } definitions - .register::<_, Error>(&builtins::byte_array(), &HashMap::new(), |_| { + .register::<_, Error>(&Type::byte_array(), &HashMap::new(), |_| { Ok(Schema::Data(Data::Bytes).into()) }) .unwrap(); @@ -396,8 +425,8 @@ mod tests { fn mint_basic() { assert_validator!( r#" - validator { - fn mint(redeemer: Data, ctx: Data) { + validator thing { + mint(redeemer: Data, policy_id: ByteArray, transaction: Data) { True } } @@ -409,8 +438,8 @@ mod tests { fn mint_parameterized() { assert_validator!( r#" - validator(utxo_ref: Int) { - fn mint(redeemer: Data, ctx: Data) { + validator thing(utxo_ref: Int) { + mint(redeemer: Data, policy_id: ByteArray, transaction: Data) { True } } @@ -423,7 +452,7 @@ mod tests { assert_validator!( r#" /// On-chain state - type State { + pub type State { /// The contestation period as a number of seconds contestationPeriod: ContestationPeriod, /// List of public key hashes of all participants @@ -432,28 +461,28 @@ mod tests { } /// A Hash digest for a given algorithm. - type Hash = ByteArray + pub type Hash = ByteArray - type Blake2b_256 { Blake2b_256 } + pub type Blake2b_256 { Blake2b_256 } /// Whatever - type ContestationPeriod { + pub type ContestationPeriod { /// A positive, non-zero number of seconds. ContestationPeriod(Int) } - type Party = + pub type Party = ByteArray - type Input { + pub type Input { CollectCom Close /// Abort a transaction Abort } - validator { - fn simplified_hydra(datum: State, redeemer: Input, ctx: Data) { + validator simplified_hydra { + spend(datum: Option, redeemer: Input, output_reference: Data, transaction: Data) { True } } @@ -465,8 +494,8 @@ mod tests { fn tuples() { assert_validator!( r#" - validator { - fn tuples(datum: (Int, ByteArray), redeemer: (Int, Int, Int), ctx: Void) { + validator tuples { + spend(datum: Option<(Int, ByteArray)>, redeemer: (Int, Int, Int), output_reference: Data, transaction: Data) { True } } @@ -478,18 +507,18 @@ mod tests { fn generics() { assert_validator!( r#" - type Either { + pub type Either { Left(left) Right(right) } - type Interval { + pub type Interval { Finite(a) Infinite } - validator { - fn generics(redeemer: Either>, ctx: Void) { + validator generics { + spend(datum: Option, redeemer: Either>, output_reference: Data, transaction: Data) { True } } @@ -501,8 +530,8 @@ mod tests { fn free_vars() { assert_validator!( r#" - validator { - fn generics(redeemer: a, ctx: Void) { + validator generics { + mint(redeemer: a, policy_id: ByteArray, transaction: Data) { True } } @@ -514,14 +543,14 @@ mod tests { fn list_2_tuples_as_list() { assert_validator!( r#" - type Dict { + pub type Dict { inner: List<(ByteArray, value)> } - type UUID { UUID } + pub type UUID { UUID } - validator { - fn list_2_tuples_as_list(redeemer: Dict, ctx: Void) { + validator list_2_tuples_as_list { + mint(redeemer: Dict, policy_id: ByteArray, transaction: Data) { True } } @@ -533,14 +562,14 @@ mod tests { fn list_pairs_as_map() { assert_validator!( r#" - type Dict { + pub type Dict { inner: List> } - type UUID { UUID } + pub type UUID { UUID } - validator { - fn list_pairs_as_map(redeemer: Dict, ctx: Void) { + validator list_pairs_as_map { + spend(datum: Option, redeemer: Dict, _output_reference: Data, transaction: Data) { True } } @@ -556,10 +585,10 @@ mod tests { inner: List<(ByteArray, value)> } - type UUID { UUID } + pub type UUID { UUID } - validator { - fn opaque_singleton_variants(redeemer: Dict, ctx: Void) { + validator opaque_singleton_variants { + spend(datum: Option, redeemer: Dict, output_reference: Data, transaction: Data) { True } } @@ -576,8 +605,8 @@ mod tests { denominator: Int, } - validator { - fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) { + validator opaque_singleton_multi_variants { + spend(datum: Option, redeemer: Rational, oref: Data, transaction: Data) { True } } @@ -593,8 +622,8 @@ mod tests { foo: Data } - validator { - fn nested_data(datum: Foo, redeemer: Int, ctx: Void) { + validator nested_data { + spend(datum: Option, redeemer: Int, output_reference: Data, transaction: Data) { True } } @@ -612,8 +641,8 @@ mod tests { Mul(Expr, Expr) } - validator { - fn recursive_types(redeemer: Expr, ctx: Void) { + validator recursive_types { + spend(datum: Option, redeemer: Expr, output_reference: Data, transaction: Data) { True } } @@ -640,8 +669,8 @@ mod tests { } } - validator { - fn recursive_generic_types(datum: Foo, redeemer: LinkedList, ctx: Void) { + validator recursive_generic_types { + spend(datum: Option, redeemer: LinkedList, output_reference: Data, transaction: Data) { True } } @@ -657,8 +686,8 @@ mod tests { foo: Int } - validator { - fn annotated_data(datum: Data, redeemer: Data, ctx: Void) { + validator annotated_data { + spend(datum: Option>, redeemer: Data, output_reference: Data, transpose: Data) { True } } diff --git a/crates/aiken-project/src/module.rs b/crates/aiken-project/src/module.rs index cb28ff5c..d7e245e0 100644 --- a/crates/aiken-project/src/module.rs +++ b/crates/aiken-project/src/module.rs @@ -390,8 +390,8 @@ impl CheckedModule { } Definition::Validator(Validator { params, - fun, - other_fun, + handlers, + fallback, .. }) => { for param in params { @@ -404,18 +404,8 @@ impl CheckedModule { } } - for argument in fun.arguments.iter_mut() { - let docs: Vec<&str> = - comments_before(&mut doc_comments, argument.location.start, &self.code); - - if !docs.is_empty() { - let doc = docs.join("\n"); - argument.put_doc(doc); - } - } - - if let Some(fun) = other_fun { - for argument in fun.arguments.iter_mut() { + for handler in handlers.iter_mut() { + for argument in handler.arguments.iter_mut() { let docs: Vec<&str> = comments_before( &mut doc_comments, argument.location.start, @@ -428,6 +418,16 @@ impl CheckedModule { } } } + + for argument in fallback.arguments.iter_mut() { + let docs: Vec<&str> = + comments_before(&mut doc_comments, argument.location.start, &self.code); + + if !docs.is_empty() { + let doc = docs.join("\n"); + argument.put_doc(doc); + } + } } _ => (), } @@ -463,6 +463,7 @@ impl CheckedModules { modules } + // todo: this might need fixing pub fn validators(&self) -> impl Iterator { let mut items = vec![]; @@ -478,12 +479,12 @@ impl CheckedModules { ( left.0.package.to_string(), left.0.name.to_string(), - left.1.fun.name.to_string(), + left.1.name.to_string(), ) .cmp(&( right.0.package.to_string(), right.0.name.to_string(), - right.1.fun.name.to_string(), + right.1.name.to_string(), )) }); diff --git a/crates/aiken-project/src/test_framework.rs b/crates/aiken-project/src/test_framework.rs index cac3d445..884a3595 100644 --- a/crates/aiken-project/src/test_framework.rs +++ b/crates/aiken-project/src/test_framework.rs @@ -1,7 +1,6 @@ use aiken_lang::ast::OnTestFailure; pub(crate) use aiken_lang::{ ast::{BinOp, DataTypeKey, IfBranch, Span, TypedArg, TypedDataType, TypedTest}, - builtins::bool, expr::{TypedExpr, UntypedExpr}, format::Formatter, gen_uplc::CodeGenerator, @@ -1056,7 +1055,7 @@ impl TryFrom for Assertion { left, right, .. - } if tipo == bool() => { + } if tipo == Type::bool() => { // 'and' and 'or' are left-associative operators. match (*right).clone().try_into() { Ok(Assertion { @@ -1094,7 +1093,7 @@ impl TryFrom for Assertion { let then_is_true = match body { TypedExpr::Var { name, constructor, .. - } => name == "True" && constructor.tipo == bool(), + } => name == "True" && constructor.tipo == Type::bool(), _ => false, }; @@ -1102,7 +1101,7 @@ impl TryFrom for Assertion { TypedExpr::Trace { then, .. } => match *then { TypedExpr::Var { name, constructor, .. - } => name == "False" && constructor.tipo == bool(), + } => name == "False" && constructor.tipo == Type::bool(), _ => false, }, _ => false, diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index cc1a914b..a8b5ef29 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -1,14 +1,13 @@ -use std::rc::Rc; - use super::TestProject; use crate::module::CheckedModules; use aiken_lang::ast::{Definition, Function, TraceLevel, Tracing, TypedTest, TypedValidator}; use pretty_assertions::assert_eq; +use std::rc::Rc; use uplc::{ ast::{Constant, Data, DeBruijn, Name, Program, Term, Type}, builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER, EXPECT_ON_LIST}, machine::{cost_model::ExBudget, runtime::Compressable}, - optimize::{self, shrinker::NO_INLINE}, + optimize::{self}, }; enum TestType { @@ -84,9 +83,11 @@ fn assert_uplc(source_code: &str, expected: Term, should_fail: bool) { format!("{:#?}", eval.logs()) ); - if !should_fail { - assert_eq!(eval.result().unwrap(), Term::bool(true)); - } + assert!(if should_fail { + eval.failed(false) + } else { + !eval.failed(false) + }); } TestType::Validator(func) => { let program = generator.generate(func, &script.1); @@ -3670,293 +3671,166 @@ fn when_bool_is_false() { ); } +#[test] +fn always_true_validator() { + let src = r#" + validator foo { + mint(_redeemer: Data, _policy_id: ByteArray, _transaction: Data) { + True + } + } + + "#; + + let mint = |purpose: Rc| { + Term::bool(true).lambda("__purpose_arg__").apply( + Term::un_b_data() + .apply(Term::head_list().apply( + Term::snd_pair().apply(Term::unconstr_data().apply(Term::Var(purpose))), + )), + ) + }; + + let when = |purpose: Rc| { + Term::equals_integer() + .apply(Term::integer(0.into())) + .apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::Var(purpose)))) + }; + + let validator = { + let context = "__context__"; + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::var(context))) + .as_var("tail_id_2", |tail_id_2| { + Term::head_list() + .apply(Term::Var(tail_id_2.clone())) + .as_var("__transaction__", |_transaction| { + Term::tail_list().apply(Term::Var(tail_id_2)).as_var( + "tail_id_3", + |tail_id_3| { + Term::head_list() + .apply(Term::Var(tail_id_3.clone())) + .as_var("__redeemer__", |_redeemer| { + Term::head_list() + .apply(Term::tail_list().apply(Term::Var(tail_id_3))) + .as_var("__purpose__", |purpose| { + when(purpose.clone()).delayed_if_then_else( + mint(purpose), + Term::Error, + ) + }) + }) + }, + ) + }) + }) + .delayed_if_then_else( + Term::unit(), + Term::Error + .apply(Term::Error.force()) + .delayed_trace(Term::string("Validator returned false")), + ) + .lambda(context) + }; + + assert_uplc(src, validator, false); +} + #[test] fn when_tuple_deconstruction() { let src = r#" - type Thing { + pub type Thing { idx: Int, } - type Datum { + pub type Datum { A(Thing) B } - type RedSpend { + pub type RedSpend { Spend(Int) Buy } - validator { - fn spend(dat: Datum, red: RedSpend, ctx: Data) { - when (dat, red) is { - (A(a), Spend(x)) -> - (a.idx == x)? - (_, _) -> - True - } + test foo() { + when (A(Thing { idx: 42 }), Buy) is { + (A(a), Spend(x)) -> + (a.idx == x)? + (_, _) -> + True } } "#; - let delayed_then = Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("dat"))) - .delay_true_if_then_else( - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("red"))) - .delay_true_if_then_else( + let first_clause = |tuple_index_0: Rc, tuple_index_1: Rc, otherwise: Rc| { + let match_a = Term::equals_integer().apply(Term::integer(0.into())).apply( + Term::fst_pair().apply(Term::unconstr_data().apply(Term::Var(tuple_index_0.clone()))), + ); + + let extract_a = Term::head_list() + .apply(Term::snd_pair().apply(Term::unconstr_data().apply(Term::Var(tuple_index_0)))); + + match_a.delay_true_if_then_else( + extract_a.as_var("a", |a| { + let match_spend = Term::equals_integer().apply(Term::integer(0.into())).apply( + Term::fst_pair() + .apply(Term::unconstr_data().apply(Term::Var(tuple_index_1.clone()))), + ); + + match_spend.delay_true_if_then_else( Term::equals_integer() + .apply(Term::un_i_data().apply(Term::head_list().apply( + Term::snd_pair().apply(Term::unconstr_data().apply(Term::Var(a))), + ))) .apply( Term::un_i_data().apply( - Term::head_list() - .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("a"))), + Term::head_list().apply( + Term::snd_pair().apply( + Term::unconstr_data().apply(Term::Var(tuple_index_1)), + ), + ), ), ) - .apply(Term::var("x")) .delayed_if_then_else( Term::bool(true), Term::bool(false).delayed_trace(Term::string("a.idx == x ? False")), - ) - .lambda("x") - .apply( - Term::un_i_data() - .apply(Term::head_list().apply(Term::var("red_constr_fields"))), - ) - .lambda("red_constr_fields") - .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("red"))), - Term::var("other_clauses"), - ) - .lambda("a") - .apply(Term::head_list().apply(Term::var("dat_constr_fields"))) - .lambda("dat_constr_fields") - .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("dat"))), - Term::var("other_clauses"), - ) - .lambda("other_clauses") - .apply(Term::bool(true).delay()) - .lambda("dat") - .apply(Term::head_list().apply(Term::var("pair_subject"))) - .lambda("red") - .apply(Term::head_list().apply(Term::tail_list().apply(Term::var("pair_subject")))) - .lambda("pair_subject") - .apply( - Term::mk_cons().apply(Term::var("dat")).apply( - Term::mk_cons() - .apply(Term::var("red")) - .apply(Term::empty_list()), - ), - ) - .delayed_if_then_else( - Term::unit(), - Term::Error - .apply(Term::Error.force()) - .delayed_trace(Term::string("Validator returned false")), - ) - .lambda("ctx") - .delay(); - - let otherwise_delay = &Term::var("otherwise_delayed"); - - let red_spend = Term::var(CONSTR_INDEX_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("subject", |subject| { - let subject_second_constr = Term::equals_integer() - .apply(Term::integer(1.into())) - .apply(Term::Var(subject.clone())) - .delay_true_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .delay_empty_choose_list( - Term::var("then_delayed").force(), - otherwise_delay.clone(), ), - otherwise_delay.clone(), - ); - - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::Var(subject.clone())) - .delayed_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("fields", |fields| { - Term::unwrap_tail_or( - fields.clone(), - |after_fields| { - Term::head_list().apply(Term::Var(fields)).as_var( - "head", - |head| { - Term::choose_data_integer( - head, - |field_0| { - after_fields - .delay_empty_choose_list( - Term::var("then_delayed").force(), - otherwise_delay.clone(), - ) - .lambda("field_0") - .apply(field_0) - }, - otherwise_delay, - ) - }, - ) - }, - otherwise_delay, - ) - }), - subject_second_constr, + Term::Var(otherwise.clone()), ) - }) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0") - .lambda(NO_INLINE); - - let thing = Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__param_0"))) - .delay_true_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("fields", |fields| { - Term::unwrap_tail_or( - fields.clone(), - |tail| { - Term::head_list() - .apply(Term::Var(fields)) - .as_var("head", |head| { - Term::choose_data_integer( - head, - |head_field| { - tail.delay_empty_choose_list( - Term::var("then_delayed").force(), - otherwise_delay.clone(), - ) - .lambda("idx") - .apply(head_field) - }, - otherwise_delay, - ) - }) - }, - otherwise_delay, - ) - }), - otherwise_delay.clone(), + }), + Term::Var(otherwise), ) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0") - .lambda(NO_INLINE); + }; - let datum = Term::var(CONSTR_INDEX_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("subject", |subject| { - let subject_second_constr = Term::equals_integer() - .apply(Term::integer(1.into())) - .apply(Term::Var(subject.clone())) - .delay_true_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .delay_empty_choose_list( - Term::var("then_delayed").force(), - otherwise_delay.clone(), - ), - otherwise_delay.clone(), - ); + let snd_clause = Term::bool(true); - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::Var(subject.clone())) - .delayed_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("fields", |fields| { - Term::unwrap_tail_or( - fields.clone(), - |after_fields| { - Term::head_list().apply(Term::Var(fields)).as_var( - "head", - |head| { - Term::choose_data_constr( - head, - |field_0| { - after_fields - .delay_empty_choose_list( - thing - .apply(Term::var("field_0")) - .apply( - Term::var("then_delayed") - .force() - .delay(), - ) - .apply(otherwise_delay.clone()), - otherwise_delay.clone(), - ) - .lambda("field_0") - .apply(field_0) - }, - otherwise_delay, - ) - }, - ) - }, - otherwise_delay, - ) - }), - subject_second_constr, - ) - }) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0") - .lambda(NO_INLINE); + let subject = || { + Term::list_values(vec![ + Constant::Data(Data::constr( + 0, + vec![Data::constr(0, vec![Data::integer(42.into())])], + )), + Constant::Data(Data::constr(1, vec![])), + ]) + }; - assert_uplc( - src, - Term::choose_data_constr( - Name::text("dat").into(), - |dat| { - datum - .apply(dat) - .apply( - Term::choose_data_constr( - Name::text("red").into(), - |red| { - red_spend - .apply(red) - .apply(delayed_then) - .apply(Term::var("red:RedSpend")) - }, - &Term::var("red:RedSpend"), - ) - .lambda("red") - .delay(), - ) - .apply(Term::var("dat:Datum")) - }, - &Term::var("dat:Datum"), - ) - .lambda("dat") - .constr_fields_exposer() - .lambda("red:RedSpend") - .apply( - Term::Error - .delayed_trace(Term::string("red: RedSpend")) - .delay(), - ) - .lambda("dat:Datum") - .apply( - Term::Error - .delayed_trace(Term::string("dat: Datum")) - .delay(), - ) - .constr_index_exposer(), - false, - ); + let test = Term::head_list() + .apply(Term::tail_list().apply(subject())) + .as_var("tuple_index_1_span_258_266", |tuple_index_1| { + Term::head_list().apply(subject()).as_var( + "__tuple_index_0_span_252_256", + |tuple_index_0| { + snd_clause + .delay() + .as_var("__other_clause_delayed", |other_clause| { + first_clause(tuple_index_0, tuple_index_1, other_clause) + }) + }, + ) + }); + + assert_uplc(src, test, false); } #[test] @@ -4037,17 +3911,17 @@ fn when_tuple_empty_lists() { #[test] fn generic_validator_type_test() { let src = r#" - type A { + pub type A { NoA SomeA(Void, x) } - type B { + pub type B { something: Void, } - validator { - fn err_example(r: A, _ctx: Data) -> Bool { + validator err_example { + spend(_datum: Option, r: A, _output_ref: Data, _transaction: Data) -> Bool { when r is { NoA -> False @@ -4058,200 +3932,220 @@ fn generic_validator_type_test() { } "#; - let otherwise_r_a_b = Term::Error.delayed_trace(Term::string("r: A")).delay(); - - let otherwise_var = &Term::var("otherwise_delayed"); - - let then_delayed = Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::var("subject")) - .delayed_if_then_else( - Term::bool(false), - Term::choose_unit( - Term::var("something"), - Term::choose_unit(Term::unit(), Term::bool(true)), + let body = |redeemer: Rc| { + Term::equals_integer() + .apply(Term::integer(0.into())) + .apply(Term::var("subject")) + .delayed_if_then_else( + Term::bool(false), + Term::choose_unit( + Term::var("something"), + Term::choose_unit(Term::unit(), Term::bool(true)), + ) + .lambda("something") + .apply( + Term::unit() + .lambda("_") + .apply(Term::head_list().apply(Term::var("B_fields"))), + ) + .lambda("B_fields") + .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("field_B"))) + .lambda("field_B") + .apply(Term::head_list().apply(Term::var("tail_1"))) + .lambda("tail_1") + .apply(Term::tail_list().apply(Term::var("r_fields"))) + .lambda("r_fields") + .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::Var(redeemer.clone()))), ) - .lambda("something") - .apply( - Term::unit() - .lambda("_") - .apply(Term::head_list().apply(Term::var("B_fields"))), - ) - .lambda("B_fields") - .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("field_B"))) - .lambda("field_B") - .apply(Term::head_list().apply(Term::var("tail_1"))) - .lambda("tail_1") - .apply(Term::tail_list().apply(Term::var("r_fields"))) - .lambda("r_fields") - .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("r"))), - ) - .lambda("subject") - .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("r"))) - // Validator level if then else - // which is why you have [(error) (force (error))] - .delayed_if_then_else( - Term::unit(), - Term::Error - .apply(Term::Error.force()) - .delayed_trace(Term::string("Validator returned false")), - ) - .lambda("_") - .delay(); + .lambda("subject") + .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::Var(redeemer))) + }; - let call_expect_b = |tail_2: Term, field_1| { - tail_2.delay_empty_choose_list( - Term::var("__expect_B_") - .apply(field_1) - .apply(Term::var("then_delayed")) - .apply(otherwise_var.clone()), - otherwise_var.clone(), + let expect_void = |target: Rc, then: Term| { + Term::choose_data_constr( + target.clone(), + |_| { + Term::equals_integer() + .apply(Term::integer(0.into())) + .apply( + Term::fst_pair() + .apply(Term::unconstr_data().apply(Term::Var(target.clone()))), + ) + .delayed_if_then_else( + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::Var(target))) + .delayed_choose_list(then, Term::Error), + Term::Error, + ) + }, + &Term::Error.delay(), ) }; - let some_a_fields_check = Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("tail_id_5", |fields| { - Term::unwrap_tail_or( - fields.clone(), - |tail| { - Term::head_list() - .apply(Term::Var(fields)) - .as_var("__val", |val| { - Term::choose_data_constr( - val, - |val| { - val.unwrap_void_or( - |unit| { - unit.as_var("__field_0", |_| { - tail.as_var("tail_id_6", |other_field| { - Term::unwrap_tail_or( - other_field.clone(), - |tail_2| { - Term::head_list() - .apply(Term::Var(other_field)) - .as_var("__val", |val_2| { - Term::choose_data_constr( - val_2, - |field_1| { - call_expect_b( - tail_2, field_1, - ) - }, - otherwise_var, - ) - }) - }, - otherwise_var, - ) - }) - }) - }, - otherwise_var, + let expect_no_a = |redeemer: Rc, then_delayed: Rc| { + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::Var(redeemer))) + .delayed_choose_list(Term::Var(then_delayed.clone()).force(), Term::Error) + }; + + let expect_b = |target: Rc, then: Term| { + Term::equals_integer() + .apply(Term::integer(0.into())) + .apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::Var(target.clone())))) + .delayed_if_then_else( + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::Var(target))) + .as_var("tail_id_8", |tail_id_8| { + Term::Var(tail_id_8.clone()).delayed_choose_list( + Term::Error, + Term::head_list() + .apply(Term::Var(tail_id_8.clone())) + .as_var("__val", |val| { + expect_void( + val, + Term::tail_list() + .apply(Term::Var(tail_id_8)) + .delayed_choose_list(then.force(), Term::Error), ) - }, - otherwise_var, - ) - }) - }, - otherwise_var, + }), + ) + }), + Term::Error, ) - }); + }; - let expect_a_b = Term::var(CONSTR_INDEX_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("subject", |subject| { - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::Var(subject.clone())) - .delayed_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .delay_empty_choose_list( - Term::var("then_delayed").force(), - otherwise_var.clone(), - ), - Term::equals_integer() - .apply(Term::integer(1.into())) - .apply(Term::Var(subject)) - .delay_true_if_then_else(some_a_fields_check, otherwise_var.clone()), - ) - }) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0"); - - let expect_b = Term::var(CONSTR_INDEX_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("subject", |subject| { - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::Var(subject.clone())) - .delay_true_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("fields", |fields| { - Term::unwrap_tail_or( - fields.clone(), - |tail| { - Term::head_list().apply(Term::Var(fields)).as_var( - "field_void", - |field_void| { - Term::choose_data_constr( - field_void, - |void| { - void.unwrap_void_or( - |unit| { - unit.as_var("something", |_| { - tail.delay_empty_choose_list( - Term::var("then_delayed") - .force(), - otherwise_var.clone(), + let expect_some_a = |redeemer: Rc, then_delayed: Rc| { + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::Var(redeemer))) + .as_var("tail_id_5", |tail_id_5| { + Term::Var(tail_id_5.clone()).delayed_choose_list( + Term::Error, + Term::head_list() + .apply(Term::Var(tail_id_5.clone())) + .as_var("__val", |val| { + expect_void( + val, + Term::tail_list().apply(Term::Var(tail_id_5)).as_var( + "tail_id_6", + |tail_id_6| { + Term::Var(tail_id_6.clone()).delayed_choose_list( + Term::Error, + Term::head_list() + .apply(Term::Var(tail_id_6.clone())) + .as_var("__val", |val| { + Term::choose_data_constr( + val.clone(), + |_| { + Term::tail_list() + .apply(Term::Var(tail_id_6)) + .delayed_choose_list( + expect_b( + val, + Term::Var(then_delayed), + ), + Term::Error, ) - }) }, - otherwise_var, + &Term::Error.delay(), ) - }, - otherwise_var, - ) - }, - ) - }, - otherwise_var, + }), + ) + }, + ), ) }), - otherwise_var.clone(), - ) - }) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0"); - - assert_uplc( - src, - Term::var("r") - .as_var("__val", |r| { - Term::choose_data_constr( - r, - |val| { - Term::var("__expect_A_B_") - .lambda("__expect_A_B_") - .apply(expect_a_b) - .lambda("__expect_B_") - .apply(expect_b) - .apply(val) - .apply(then_delayed) - .apply(Term::var("r:A")) - }, - &Term::var("r:A"), ) }) - .lambda("r") - .lambda("r:A") - .apply(otherwise_r_a_b), - false, - ); + }; + + let when_constr_arity_2 = |redeemer: Rc, then_1st: Term, then_2nd: Term| { + Term::fst_pair() + .apply(Term::unconstr_data().apply(Term::Var(redeemer.clone()))) + .as_var("__subject_span_0_0", |subject_span_0_0| { + let when_constructor = |ix: usize| { + Term::equals_integer() + .apply(Term::integer(ix.into())) + .apply(Term::Var(subject_span_0_0.clone())) + }; + + when_constructor(0).delayed_if_then_else( + then_1st, + when_constructor(1).delayed_if_then_else(then_2nd, Term::Error), + ) + }) + }; + + let choose_purpose = |redeemer: Rc, purpose: Rc| { + Term::equals_integer() + .apply(Term::integer(1.into())) + .apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::Var(purpose.clone())))) + .delayed_if_then_else( + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::Var(purpose))) + .as_var("tail_id_10", |tail_id_10| { + Term::head_list() + .apply(Term::Var(tail_id_10.clone())) + .as_var("__purpose_arg__", |_purpose_arg| { + Term::head_list() + .apply(Term::tail_list().apply(Term::Var(tail_id_10.clone()))) + .as_var("__datum__", |_datum| { + body(redeemer.clone()).delay().as_var( + "then_delayed", + |then_delayed| { + when_constr_arity_2( + redeemer.clone(), + expect_no_a( + redeemer.clone(), + then_delayed.clone(), + ), + expect_some_a( + redeemer.clone(), + then_delayed.clone(), + ), + ) + }, + ) + }) + }) + }), + Term::Error, + ) + }; + + let validator = { + let context = "__context__"; + Term::snd_pair() + .apply(Term::unconstr_data().apply(Term::var(context))) + .as_var("tail_id_13", |tail_id_13| { + Term::head_list() + .apply(Term::Var(tail_id_13.clone())) + .as_var("__transaction__", |_transaction| { + Term::tail_list().apply(Term::Var(tail_id_13)).as_var( + "tail_id_14", + |tail_id_14| { + Term::head_list() + .apply(Term::Var(tail_id_14.clone())) + .as_var("__redeemer__", |redeemer| { + Term::head_list() + .apply(Term::tail_list().apply(Term::Var(tail_id_14))) + .as_var("__purpose__", |purpose| { + choose_purpose(redeemer, purpose) + }) + }) + }, + ) + }) + }) + .delayed_if_then_else( + Term::unit(), + Term::Error + .apply(Term::Error.force()) + .delayed_trace(Term::string("Validator returned false")), + ) + .lambda(context) + }; + + assert_uplc(src, validator, false); } #[test] @@ -5545,296 +5439,6 @@ fn list_clause_with_assign() { ); } -#[test] -fn opaque_value_in_datum() { - let src = r#" - opaque type Value { - inner: Dict> - } - - opaque type Dict { - inner: List> - } - - type Dat { - c: Int, - a: Value - } - - - validator { - fn spend(dat: Dat, red: Data, ctx: Data) { - let val = dat.a - - expect [Pair(_, amount)] = val.inner.inner - - let final_amount = [Pair(#"AA", 4)] |> Dict - - final_amount == amount - - } - } - "#; - - let expect_on_list = Term::var(EXPECT_ON_LIST) - .apply(Term::var(EXPECT_ON_LIST)) - .apply(Term::var("__list")) - .lambda(EXPECT_ON_LIST) - .apply( - Term::var("check_with") - .apply(Term::var("__list")) - .apply(Term::var(EXPECT_ON_LIST).apply(Term::var(EXPECT_ON_LIST))) - .lambda("__list") - .lambda(EXPECT_ON_LIST) - .lambda("__no_inline__"), - ) - .lambda("check_with") - .lambda("__list") - .lambda("__no_inline__"); - - let expect_otherwise = &Term::var("expect[Pair(_,amount)]=val.inner.inner"); - let expect_delay_error: Term = Term::Error - .delayed_trace(Term::string("expect [Pair(_, amount)] = val.inner.inner")) - .delay(); - - let final_comparison = Term::equals_data() - .apply(Term::map_data().apply(Term::var("final_amount"))) - .apply(Term::map_data().apply(Term::var("amount"))); - - let assignments_body = Term::unmap_data() - .apply(Term::head_list().apply( - Term::tail_list().apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("dat"))), - )) - .as_var("val", |val| { - Term::unwrap_tail_or( - val.clone(), - |tail| { - Term::head_list() - .apply(Term::Var(val)) - .as_var("elem_0", |elem| { - tail.delay_empty_choose_list( - Term::unmap_data() - .apply(Term::snd_pair().apply(Term::Var(elem))) - .as_var("amount", |_| { - Term::map_values(vec![Constant::ProtoPair( - Type::Data, - Type::Data, - Constant::Data(Data::bytestring(vec![170])).into(), - Constant::Data(Data::integer(4.into())).into(), - )]) - .as_var("final_amount", |_| final_comparison) - }), - expect_otherwise.clone(), - ) - }) - }, - expect_otherwise, - ) - }) - .delayed_if_then_else( - Term::unit(), - Term::Error - .apply(Term::Error.force()) - .delayed_trace(Term::string("Validator returned false")), - ) - .lambda("ctx") - .lambda("red"); - - let otherwise_dat = &Term::var("otherwise_delayed"); - - let else_dat = &Term::var("dat:Dat"); - - let curried_2 = Term::var("__curried_expect_on_list_2"); - - let expect_inner_pair = |pair| { - Term::snd_pair() - .apply(Term::Var(pair)) - .as_var("__val", |val| { - Term::choose_data_map( - val, - |map_val| { - map_val.as_var("map_span", |map_span| { - Term::var(EXPECT_ON_LIST).apply(Term::Var(map_span)).apply( - Term::var("__list_2") - .delayed_choose_list( - Term::var("__curried_expect_on_list_1") - .apply(Term::tail_list().apply(Term::var("__list_1"))), - Term::head_list().apply(Term::var("__list_2")).as_var( - "pair", - |pair| { - let val = - Term::fst_pair().apply(Term::Var(pair.clone())); - - val.as_var("__val", |val| { - Term::choose_data_bytearray( - val, - |v| { - let other_val = Term::snd_pair() - .apply(Term::Var(pair)); - - other_val - .as_var("__val", |other| { - Term::choose_data_integer( - other, - |v2| { - let arg = - Term::tail_list() - .apply( - Term::var( - "__list_2", - ), - ); - - curried_2 - .apply(arg) - .lambda("snd_pair") - .apply(v2) - }, - otherwise_dat, - ) - }) - .lambda("fst_pair") - .apply(v) - }, - otherwise_dat, - ) - }) - }, - ), - ) - .lambda("__curried_expect_on_list_2") - .lambda("__list_2"), - ) - }) - }, - otherwise_dat, - ) - }) - }; - - let expect_dat_value = |tail_id2: Rc| { - Term::unwrap_tail_or( - tail_id2.clone(), - |next_tail| { - Term::head_list() - .apply(Term::Var(tail_id2)) - .as_var("__val", |val| { - Term::choose_data_map( - val, - |a| { - a.as_var("a", |a| { - next_tail.delay_empty_choose_list( - Term::var(EXPECT_ON_LIST) - .apply(Term::Var(a.clone())) - .apply( - Term::var("__list_1") - .delayed_choose_list( - Term::var("then_delayed").force(), - Term::head_list() - .apply(Term::var("__list_1")) - .as_var("pair", |pair| { - Term::fst_pair() - .apply(Term::Var(pair.clone())) - .as_var("fst", |fst| { - Term::choose_data_bytearray( - fst, - |bytearray_fst| { - bytearray_fst.as_var( - "pair_fst_span", - |_| { - expect_inner_pair( - pair, - ) - }, - ) - }, - otherwise_dat, - ) - }) - }), - ) - .lambda("__curried_expect_on_list_1") - .lambda("__list_1"), - ), - otherwise_dat.clone(), - ) - }) - }, - otherwise_dat, - ) - }) - }, - otherwise_dat, - ) - }; - - let expect_dat = Term::var(CONSTR_INDEX_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("subject", |subject| { - Term::equals_integer() - .apply(Term::integer(0.into())) - .apply(Term::Var(subject)) - .delay_true_if_then_else( - Term::var(CONSTR_FIELDS_EXPOSER) - .apply(Term::var("__param_0")) - .as_var("tail_id_5", |tail_id| { - Term::unwrap_tail_or( - tail_id.clone(), - |next_tail| { - Term::head_list().apply(Term::Var(tail_id)).as_var( - "__val", - |val| { - Term::choose_data_integer( - val, - |c| { - c.as_var("c", |_| { - next_tail.as_var("tail_id_6", |tail_id2| { - expect_dat_value(tail_id2) - }) - }) - }, - otherwise_dat, - ) - }, - ) - }, - otherwise_dat, - ) - }), - otherwise_dat.clone(), - ) - }) - .lambda("otherwise_delayed") - .lambda("then_delayed") - .lambda("__param_0") - .lambda(NO_INLINE); - - assert_uplc( - src, - Term::choose_data_constr( - Name::text("dat").into(), - |_| { - expect_on_list - .as_var(EXPECT_ON_LIST, |_| { - expect_dat.as_var("__expect_Dat_", Term::Var) - }) - .apply(Term::var("dat")) - .apply(assignments_body.delay()) - .apply(else_dat.clone()) - }, - else_dat, - ) - .lambda("dat") - .constr_fields_exposer() - .lambda("expect[Pair(_,amount)]=val.inner.inner") - .apply(expect_delay_error) - .lambda("dat:Dat") - .apply(Term::Error.delayed_trace(Term::string("dat: Dat")).delay()) - .constr_index_exposer(), - false, - ); -} - #[test] fn opaque_value_in_test() { let src = r#" @@ -6535,3 +6139,51 @@ fn pattern_bytearray() { assert_uplc(src, program, false) } + +#[test] +fn cast_never() { + let src = r#" + test never_ok_cast() { + let none: Option = None + let data: Data = none + expect _: Never = data + } + "#; + + let none_or_never = || Term::Constant(Constant::Data(Data::constr(1, vec![])).into()); + + let expect_otherwise = Term::Error + .delayed_trace(Term::string("expect _: Never = data")) + .delay(); + + let assert_constr_index = Term::equals_integer() + .apply(Term::integer(1.into())) + .apply(Term::fst_pair().apply(Term::unconstr_data().apply(none_or_never()))); + + let assert_empty_fields = |then: Term, expect_otherwise: Rc| { + Term::snd_pair() + .apply(Term::unconstr_data().apply(none_or_never())) + .delay_empty_choose_list(then, Term::Var(expect_otherwise)) + }; + + let program = expect_otherwise.as_var("expect_:Never=data", |expect_otherwise| { + let otherwise = Term::Var(expect_otherwise.clone()); + + let when_constr = assert_constr_index.delay_true_if_then_else( + assert_empty_fields(Term::unit(), expect_otherwise.clone()), + Term::Var(expect_otherwise), + ); + + none_or_never() + .choose_data( + when_constr.delay(), + otherwise.clone(), + otherwise.clone(), + otherwise.clone(), + otherwise, + ) + .force() + }); + + assert_uplc(src, program, false) +} diff --git a/crates/uplc/src/machine/error.rs b/crates/uplc/src/machine/error.rs index b25b29df..ae306240 100644 --- a/crates/uplc/src/machine/error.rs +++ b/crates/uplc/src/machine/error.rs @@ -5,78 +5,120 @@ use std::string::FromUtf8Error; #[derive(Debug, Clone, PartialEq, thiserror::Error, miette::Diagnostic)] pub enum Error { - #[error("Over budget mem: {} & cpu: {}", .0.mem, .0.cpu)] + #[error("execution went over budget\n{:>13} {}\n{:>13} {}", "Mem", .0.mem, "CPU", .0.cpu)] OutOfExError(ExBudget), - #[error("Invalid Stepkind: {0}")] + #[error("invalid step kind: {0}")] InvalidStepKind(u8), - #[error("Cannot evaluate an open term:\\n\\n{}", .0.to_pretty())] + #[error( + "cannot evaluate an open term:\n{:>13} {}", + "Term", + indent(redacted(.0.to_pretty(), 10)), + )] OpenTermEvaluated(Term), - #[error("The validator crashed / exited prematurely")] + #[error("the validator crashed / exited prematurely")] EvaluationFailure, #[error( - "Attempted to instantiate a non-polymorphic term\n{:>13} {}", + "attempted to instantiate a non-polymorphic term\n{:>13} {}", "Term", indent(redacted(format!("{:#?}", .0), 10)), )] NonPolymorphicInstantiation(Value), #[error( - "Attempted to apply an argument to a non-function\n{:>13} {}\n{:>13} {}", + "attempted to apply an argument to a non-function\n{:>13} {}\n{:>13} {}", "Thing", indent(redacted(format!("{:#?}", .0), 5)), "Argument", indent(redacted(format!("{:#?}", .1), 5)), )] NonFunctionalApplication(Value, Value), - #[error("Attempted to case a non-const:\n\n{0:#?}")] + #[error( + "attempted to case a non-const\n{:>13} {}", + "Value", + indent(redacted(format!("{:#?}", .0), 10)), + )] NonConstrScrutinized(Value), #[error("Cases: {0:#?}\n\n are missing branch for constr:\n\n{1:#?}")] MissingCaseBranch(Vec>, Value), - #[error("Type mismatch expected '{0}' got '{1}'")] + #[error("type mismatch\n{:>13} {0}\n{:>13} {1}", "Expected", "Got")] TypeMismatch(Type, Type), - #[error("Type mismatch expected '(list a)' got '{0}'")] + #[error("type mismatch\n{:>13} (list a)\n{:>13} {0}", "Expected", "Got")] ListTypeMismatch(Type), - #[error("Type mismatch expected '(pair a b)' got '{0}'")] + #[error("type mismatch\n{:>13}(pair a b)\n{:>13} {0}", "Expected", "Got")] PairTypeMismatch(Type), - #[error("Empty List:\n\n{0:#?}")] + #[error( + "unexpected empty list\n{:>13} {}", + "List", + indent(redacted(format!("{:#?}", .0), 10)), + )] EmptyList(Value), #[error( - "A builtin received a term argument when something else was expected:\n\n{0}\n\nYou probably forgot to wrap the builtin with a force." + "a builtin received a term argument when something else was expected\n{:>13} {}\n{:>13} You probably forgot to wrap the builtin with a force.", + "Term", + indent(redacted(format!("{:#?}", .0), 10)), + "Hint" )] UnexpectedBuiltinTermArgument(Term), #[error( - "A builtin expected a term argument, but something else was received:\n\n{0}\n\nYou probably have an extra force wrapped around a builtin" + "a builtin expected a term argument, but something else was received:\n{:>13} {}\n{:>13} You probably have an extra force wrapped around a builtin", + "Term", + indent(redacted(format!("{:#?}", .0), 10)), + "Hint" )] BuiltinTermArgumentExpected(Term), - #[error("Unable to unlift value because it is not a constant:\n\n{0:#?}")] + #[error( + "Unable to unlift value because it is not a constant\n{:>13} {}", + "Value", + indent(redacted(format!("{:#?}", .0), 10)), + )] NotAConstant(Value), #[error("The evaluation never reached a final state")] MachineNeverReachedDone, - #[error("integerToByteString encountered negative size {0}")] + #[error("integerToByteString encountered negative size\n{:>13} {0}", "Size")] IntegerToByteStringNegativeSize(BigInt), - #[error("integerToByteString encountered negative input {0}")] + #[error("integerToByteString encountered negative input\n{:>13} {0}", "Input")] IntegerToByteStringNegativeInput(BigInt), - #[error("integerToByteString encountered size {0} which is bigger than the max size of {1}")] + #[error( + "bytes size beyond limit when converting from integer\n{:>13} {0}\n{:>13} {1}", + "Size", + "Maximum" + )] IntegerToByteStringSizeTooBig(BigInt, i64), - #[error("integerToByteString encountered size {0} which is not enough space for {1} bytes")] + #[error( + "bytes size below limit when converting from integer\n{:>13} {0}\n{:>13} {1}", + "Size", + "Minimum" + )] IntegerToByteStringSizeTooSmall(BigInt, usize), #[error("Decoding utf8")] Utf8(#[from] FromUtf8Error), - #[error("Out of Bounds\n\nindex: {}\nbytestring: {}\npossible: 0 - {}", .0, hex::encode(.1), .1.len() - 1)] + #[error( + "Out of Bounds\n{:>13} {}\nb{:>13} {}\n{:>13} 0 - {}", + "Index", + .0, + "ByteArray", + hex::encode(.1), + "Allowed", + .1.len() - 1 + )] ByteStringOutOfBounds(BigInt, Vec), - #[error("Attempt to consByteString something than isn't a byte between [0-255]: {0}")] + #[error( + "attempt to consByteString something than isn't a byte between [0-255]\n{:>13} {0}", + "Found" + )] ByteStringConsNotAByte(BigInt), - #[error("Divide By Zero\n\n{0} / {1}")] + #[error("divide By Zero: {0} / {1}")] DivideByZero(BigInt, BigInt), #[error("Ed25519S PublicKey should be 32 bytes but it was {0}")] UnexpectedEd25519PublicKeyLength(usize), #[error("Ed25519S Signature should be 64 bytes but it was {0}")] UnexpectedEd25519SignatureLength(usize), #[error( - "Failed to deserialise PlutusData using {0}:\n\n{}", - redacted(format!("{:#?}", .1), 10), + "failed to deserialise PlutusData using {0}\n{:>13} {}", + "Value", + indent(redacted(format!("{:#?}", .1), 10)), )] DeserialisationError(String, Value), - #[error("Integer overflow")] + #[error("integer overflow")] OverflowError, #[error("blst error {0:?}")] Blst(blst::BLST_ERROR), diff --git a/crates/uplc/src/tx.rs b/crates/uplc/src/tx.rs index 925440f2..068da3a9 100644 --- a/crates/uplc/src/tx.rs +++ b/crates/uplc/src/tx.rs @@ -100,7 +100,7 @@ pub fn eval_phase_two_raw( .or_else(|_| MultiEraTx::decode_for_era(Era::Babbage, tx_bytes)) .or_else(|_| MultiEraTx::decode_for_era(Era::Alonzo, tx_bytes))?; - let cost_mdls = cost_mdls_bytes.map(|x| CostMdls::decode_fragment(x)).transpose()?; + let cost_mdls = cost_mdls_bytes.map(CostMdls::decode_fragment).transpose()?; let budget = ExBudget { cpu: initial_budget.0 as i64, diff --git a/crates/uplc/src/tx/eval.rs b/crates/uplc/src/tx/eval.rs index fecc78a4..c02771c4 100644 --- a/crates/uplc/src/tx/eval.rs +++ b/crates/uplc/src/tx/eval.rs @@ -46,15 +46,7 @@ pub fn eval_redeemer( .apply_data(redeemer.data.clone()) .apply_data(script_context.to_plutus_data()), - // FIXME: Temporary, but needed until https://github.com/aiken-lang/aiken/pull/977 - // is implemented. - ScriptContext::V3 { .. } => if let Some(datum) = datum { - program.apply_data(datum) - } else { - program - } - .apply_data(redeemer.data.clone()) - .apply_data(script_context.to_plutus_data()), + ScriptContext::V3 { .. } => program.apply_data(script_context.to_plutus_data()), }; let mut eval_result = if let Some(costs) = cost_mdl_opt { diff --git a/crates/uplc/src/tx/snapshots/uplc__tx__script_context__tests__script_context_certificates.snap b/crates/uplc/src/tx/snapshots/uplc__tx__script_context__tests__script_context_certificates.snap index 5349e185..e59033d1 100644 --- a/crates/uplc/src/tx/snapshots/uplc__tx__script_context__tests__script_context_certificates.snap +++ b/crates/uplc/src/tx/snapshots/uplc__tx__script_context__tests__script_context_certificates.snap @@ -570,20 +570,9 @@ Constr( ), Constr( Constr { - tag: 121, + tag: 122, any_constructor: None, - fields: [ - BigInt( - Int( - Int( - Int { - neg: false, - val: 3000000, - }, - ), - ), - ), - ], + fields: [], }, ), ], @@ -638,20 +627,9 @@ Constr( ), Constr( Constr { - tag: 121, + tag: 122, any_constructor: None, - fields: [ - BigInt( - Int( - Int( - Int { - neg: false, - val: 3000000, - }, - ), - ), - ), - ], + fields: [], }, ), ], diff --git a/crates/uplc/src/tx/to_plutus_data.rs b/crates/uplc/src/tx/to_plutus_data.rs index 670f8654..aab60880 100644 --- a/crates/uplc/src/tx/to_plutus_data.rs +++ b/crates/uplc/src/tx/to_plutus_data.rs @@ -52,6 +52,8 @@ struct WithArrayRational<'a, T>(&'a T); struct WithPartialCertificates<'a, T>(&'a T); +struct WithNeverRegistrationDeposit<'a, T>(&'a T); + pub trait ToPlutusData { fn to_plutus_data(&self) -> PlutusData; } @@ -203,6 +205,29 @@ impl<'a> ToPlutusData for WithWrappedTransactionId<'a, KeyValuePairs ToPlutusData for WithNeverRegistrationDeposit<'a, Vec> { + fn to_plutus_data(&self) -> PlutusData { + self.0 + .iter() + .map(WithNeverRegistrationDeposit) + .collect::>() + .to_plutus_data() + } +} + +impl<'a> ToPlutusData for WithNeverRegistrationDeposit<'a, KeyValuePairs> { + fn to_plutus_data(&self) -> PlutusData { + let mut data_vec: Vec<(PlutusData, PlutusData)> = vec![]; + for (key, value) in self.0.iter() { + data_vec.push(( + WithNeverRegistrationDeposit(key).to_plutus_data(), + value.to_plutus_data(), + )) + } + PlutusData::Map(KeyValuePairs::Def(data_vec)) + } +} + impl ToPlutusData for Option { fn to_plutus_data(&self) -> PlutusData { match self { @@ -549,14 +574,16 @@ impl<'a> ToPlutusData for WithPartialCertificates<'a, Certificate> { vec![pool_keyhash.to_plutus_data(), epoch.to_plutus_data()], ), - certificate => unreachable!("unexpected in V1/V2 script context: {certificate:?}"), + certificate => { + unreachable!("unexpected certificate type in V1/V2 script context: {certificate:?}") + } } } } -impl ToPlutusData for Certificate { +impl<'a> ToPlutusData for WithNeverRegistrationDeposit<'a, Certificate> { fn to_plutus_data(&self) -> PlutusData { - match self { + match self.0 { Certificate::StakeRegistration(stake_credential) => wrap_multiple_with_constr( 0, vec![ @@ -565,11 +592,11 @@ impl ToPlutusData for Certificate { ], ), - Certificate::Reg(stake_credential, deposit) => wrap_multiple_with_constr( + Certificate::Reg(stake_credential, _) => wrap_multiple_with_constr( 0, vec![ stake_credential.to_plutus_data(), - Some(*deposit).to_plutus_data(), + None::.to_plutus_data(), ], ), @@ -581,11 +608,11 @@ impl ToPlutusData for Certificate { ], ), - Certificate::UnReg(stake_credential, deposit) => wrap_multiple_with_constr( + Certificate::UnReg(stake_credential, _) => wrap_multiple_with_constr( 1, vec![ stake_credential.to_plutus_data(), - Some(*deposit).to_plutus_data(), + None::.to_plutus_data(), ], ), @@ -835,32 +862,44 @@ impl ToPlutusData for TxInInfo { } } +// NOTE: This is a _small_ abuse of the 'WithWrappedTransactionId'. We know the wrapped +// is needed for V1 and V2, and it also appears that for V1 and V2, the certifying +// purpose mustn't include the certificate index. So, we also short-circuit it here. impl<'a> ToPlutusData for WithWrappedTransactionId<'a, ScriptPurpose> { fn to_plutus_data(&self) -> PlutusData { match self.0 { + ScriptPurpose::Minting(policy_id) => wrap_with_constr(0, policy_id.to_plutus_data()), ScriptPurpose::Spending(out_ref, ()) => { wrap_with_constr(1, WithWrappedTransactionId(out_ref).to_plutus_data()) } - // NOTE: This is a _small_ abuse of the 'WithWrappedTransactionId'. We know the wrapped - // is needed for V1 and V2, and it also appears that for V1 and V2, the certifying - // purpose mustn't include the certificate index. So, we also short-circuit it here. - ScriptPurpose::Certifying(_, dcert) => wrap_with_constr(3, dcert.to_plutus_data()), - otherwise => otherwise.to_plutus_data(), + ScriptPurpose::Rewarding(stake_credential) => { + wrap_with_constr(2, stake_credential.to_plutus_data()) + } + ScriptPurpose::Certifying(_, dcert) => { + wrap_with_constr(3, WithPartialCertificates(dcert).to_plutus_data()) + } + purpose => { + unreachable!("unsupported purpose for V1 or V2 script context: {purpose:?}") + } } } } -impl ToPlutusData for ScriptPurpose { +impl<'a> ToPlutusData for WithNeverRegistrationDeposit<'a, ScriptPurpose> { fn to_plutus_data(&self) -> PlutusData { - match self { + match self.0 { ScriptPurpose::Minting(policy_id) => wrap_with_constr(0, policy_id.to_plutus_data()), ScriptPurpose::Spending(out_ref, ()) => wrap_with_constr(1, out_ref.to_plutus_data()), ScriptPurpose::Rewarding(stake_credential) => { wrap_with_constr(2, stake_credential.to_plutus_data()) } - ScriptPurpose::Certifying(ix, dcert) => { - wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()]) - } + ScriptPurpose::Certifying(ix, dcert) => wrap_multiple_with_constr( + 3, + vec![ + ix.to_plutus_data(), + WithNeverRegistrationDeposit(dcert).to_plutus_data(), + ], + ), ScriptPurpose::Voting(voter) => { wrap_multiple_with_constr(4, vec![voter.to_plutus_data()]) } @@ -1240,12 +1279,12 @@ impl ToPlutusData for Vote { } } -impl ToPlutusData for ScriptInfo +impl<'a, T> ToPlutusData for WithNeverRegistrationDeposit<'a, ScriptInfo> where T: ToPlutusData, { fn to_plutus_data(&self) -> PlutusData { - match self { + match self.0 { ScriptInfo::Minting(policy_id) => wrap_with_constr(0, policy_id.to_plutus_data()), ScriptInfo::Spending(out_ref, datum) => { wrap_multiple_with_constr(1, vec![out_ref.to_plutus_data(), datum.to_plutus_data()]) @@ -1253,9 +1292,13 @@ where ScriptInfo::Rewarding(stake_credential) => { wrap_with_constr(2, stake_credential.to_plutus_data()) } - ScriptInfo::Certifying(ix, dcert) => { - wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()]) - } + ScriptInfo::Certifying(ix, dcert) => wrap_multiple_with_constr( + 3, + vec![ + ix.to_plutus_data(), + WithNeverRegistrationDeposit(dcert).to_plutus_data(), + ], + ), ScriptInfo::Voting(voter) => wrap_multiple_with_constr(4, vec![voter.to_plutus_data()]), ScriptInfo::Proposing(ix, procedure) => { wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()]) @@ -1311,11 +1354,11 @@ impl ToPlutusData for TxInfo { tx_info.outputs.to_plutus_data(), tx_info.fee.to_plutus_data(), tx_info.mint.to_plutus_data(), - tx_info.certificates.to_plutus_data(), + WithNeverRegistrationDeposit(&tx_info.certificates).to_plutus_data(), tx_info.withdrawals.to_plutus_data(), tx_info.valid_range.to_plutus_data(), tx_info.signatories.to_plutus_data(), - tx_info.redeemers.to_plutus_data(), + WithNeverRegistrationDeposit(&tx_info.redeemers).to_plutus_data(), tx_info.data.to_plutus_data(), tx_info.id.to_plutus_data(), tx_info.votes.to_plutus_data(), @@ -1347,7 +1390,7 @@ impl ToPlutusData for ScriptContext { vec![ tx_info.to_plutus_data(), redeemer.to_plutus_data(), - purpose.to_plutus_data(), + WithNeverRegistrationDeposit(purpose).to_plutus_data(), ], ), } diff --git a/examples/acceptance_tests/012/lib/tests.ak b/examples/acceptance_tests/012/lib/tests.ak index 78e5360b..77cd95ef 100644 --- a/examples/acceptance_tests/012/lib/tests.ak +++ b/examples/acceptance_tests/012/lib/tests.ak @@ -14,6 +14,7 @@ pub fn filter(xs: List, f: fn(a) -> Bool) -> List { } test filter_1() { - filter([1, - 2, 3, 4, 5, 6], fn(x) { builtin.mod_integer(x, 2) == 0 }) == [2, 4, 6] + filter([1, 2, 3, 4, 5, 6], fn(x) { builtin.mod_integer(x, 2) == 0 }) == [ + 2, 4, 6, + ] } diff --git a/examples/acceptance_tests/036/aiken.lock b/examples/acceptance_tests/036/aiken.lock index 2658f9e4..0b889661 100644 --- a/examples/acceptance_tests/036/aiken.lock +++ b/examples/acceptance_tests/036/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158432, nanos_since_epoch = 10066000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724777134, nanos_since_epoch = 232157000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/036/aiken.toml b/examples/acceptance_tests/036/aiken.toml index 8147c157..9ab33a02 100644 --- a/examples/acceptance_tests/036/aiken.toml +++ b/examples/acceptance_tests/036/aiken.toml @@ -3,5 +3,5 @@ version = "0.0.0" [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/acceptance_tests/036/plutus.json b/examples/acceptance_tests/036/plutus.json index a91e2dcc..515258cd 100644 --- a/examples/acceptance_tests/036/plutus.json +++ b/examples/acceptance_tests/036/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "spend.mint", + "title": "spend.bar.mint", "redeemer": { "title": "_redeemer", "schema": { @@ -21,15 +21,28 @@ { "title": "output_reference", "schema": { - "$ref": "#/definitions/aiken~1transaction~1OutputReference" + "$ref": "#/definitions/cardano~1transaction~1OutputReference" } } ], - "compiledCode": "589e0100003232323232323222322533300553330053370e900018031baa3232330010013758600460126ea8c008c024dd50019129998058008a6103d87a800013232533300a3375e600a60186ea80080244cdd2a40006601c00497ae0133004004001300f002300d0012300b00114a229405261365653330033370e900018021baa00115333006300537540022930b0b2b9a5573aaae7955cfaba05742ae881", - "hash": "0241f73ef186e53566d1b5a81eca50049b0d86833e6b88fe26b1e4bc" + "compiledCode": "58c90100003232323232323222533300332323232325332330093001300a375400426464a666016600660186ea8c8c8cc004004dd6180118079baa00922533301100114c0103d87a80001323253330103375e600a60246ea800803c4cdd2a40006602800497ae0133004004001301500230130012301100114a229414ccc028c008c02cdd50020a99980698061baa00414985858dd7180718059baa002370e90000b1806180680118058009805801180480098029baa00114984d9595cd2ab9d5573caae7d5d02ba157441", + "hash": "2edaecec5a072cd65b12395410ce6da7cafaffdf70506cbcb40b4df8" }, { - "title": "spend.spend", + "title": "spend.bar.else", + "parameters": [ + { + "title": "output_reference", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "58c90100003232323232323222533300332323232325332330093001300a375400426464a666016600660186ea8c8c8cc004004dd6180118079baa00922533301100114c0103d87a80001323253330103375e600a60246ea800803c4cdd2a40006602800497ae0133004004001301500230130012301100114a229414ccc028c008c02cdd50020a99980698061baa00414985858dd7180718059baa002370e90000b1806180680118058009805801180480098029baa00114984d9595cd2ab9d5573caae7d5d02ba157441", + "hash": "2edaecec5a072cd65b12395410ce6da7cafaffdf70506cbcb40b4df8" + }, + { + "title": "spend.foo.spend", "datum": { "title": "_datum", "schema": { @@ -42,8 +55,13 @@ "$ref": "#/definitions/Data" } }, - "compiledCode": "58ef01000032323232323232222533300432330010013758601460166016600e6ea8c028c01cdd50011129998048008a501325333007333007533300a3253330083370e900118049baa00114bd6f7b63009bab300d300a375400264660020026eacc034c038c028dd518068019129998060008a60103d87a8000132323232533300d33722911050000000000000021533300d3371e91010500000000000000213374a9000198089ba60014bd700a6103d87a80001330060060033756601c0066eb8c030008c040008c0380045288a504a094452889980180180098060008a4c26cacae6955ceaab9e5573eae815d0aba21", - "hash": "f56561e01063b11146809755d9907147e79d3166aa5c65fba4040fd1" + "compiledCode": "5901230100003232323232323225333002323232323253330073370e900118041baa001132323232330010013758602060226022601a6ea8020894ccc03c0045280992999806999806a99980819299980719b8748008c03cdd50008a5eb7bdb1804dd5980998081baa001323300100137566026602860206ea8c04c00c894ccc048004530103d87a800013232323253330133372291105000000000000002153330133371e91010500000000000000213374a90001980b9ba60014bd700a6103d87a8000133006006003375660280066eb8c048008c058008c0500045288a504a0944528899801801800980900098071807801180680098049baa00116300b300c002300a001300a00230080013004375400229309b2b2b9a5573aaae7955cfaba05742ae881", + "hash": "cf024265a1ff4ab129cef178c64b8c4cab25d62129242e01e29bb3d1" + }, + { + "title": "spend.foo.else", + "compiledCode": "5901230100003232323232323225333002323232323253330073370e900118041baa001132323232330010013758602060226022601a6ea8020894ccc03c0045280992999806999806a99980819299980719b8748008c03cdd50008a5eb7bdb1804dd5980998081baa001323300100137566026602860206ea8c04c00c894ccc048004530103d87a800013232323253330133372291105000000000000002153330133371e91010500000000000000213374a90001980b9ba60014bd700a6103d87a8000133006006003375660280066eb8c048008c058008c0500045288a504a0944528899801801800980900098071807801180680098049baa00116300b300c002300a001300a00230080013004375400229309b2b2b9a5573aaae7955cfaba05742ae881", + "hash": "cf024265a1ff4ab129cef178c64b8c4cab25d62129242e01e29bb3d1" } ], "definitions": { @@ -68,7 +86,7 @@ } ] }, - "aiken/transaction/OutputReference": { + "cardano/transaction/OutputReference": { "title": "OutputReference", "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", "anyOf": [ @@ -79,7 +97,7 @@ "fields": [ { "title": "transaction_id", - "$ref": "#/definitions/aiken~1transaction~1TransactionId" + "$ref": "#/definitions/ByteArray" }, { "title": "output_index", @@ -88,23 +106,6 @@ ] } ] - }, - "aiken/transaction/TransactionId": { - "title": "TransactionId", - "description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.", - "anyOf": [ - { - "title": "TransactionId", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "hash", - "$ref": "#/definitions/ByteArray" - } - ] - } - ] } } } \ No newline at end of file diff --git a/examples/acceptance_tests/036/validators/spend.ak b/examples/acceptance_tests/036/validators/spend.ak index a75c1c17..d02a89a4 100644 --- a/examples/acceptance_tests/036/validators/spend.ak +++ b/examples/acceptance_tests/036/validators/spend.ak @@ -1,29 +1,33 @@ -use aiken/dict -use aiken/list -use aiken/transaction.{Output, OutputReference, ScriptContext} -use aiken/transaction/value.{PolicyId} +use aiken/collection/dict +use aiken/collection/list +use cardano/assets.{PolicyId} +use cardano/transaction.{Output, OutputReference, Transaction} const my_policy_id: PolicyId = #"0000000000" pub fn has_policy_id(self: Output, policy_id: PolicyId) -> Bool { self.value - |> value.tokens(policy_id) + |> assets.tokens(policy_id) |> dict.is_empty |> not } -validator { - fn spend(_datum: Data, _redeemer: Data, ctx: ScriptContext) -> Bool { - ctx.transaction.outputs +validator foo { + spend(_datum: Option, _redeemer: Data, _o_ref: Data, self: Transaction) { + self.outputs |> list.any(has_policy_id(_, my_policy_id)) } + + else(_) { + fail + } } -validator(output_reference: OutputReference) { - fn mint(_redeemer: Void, ctx: ScriptContext) -> Bool { +validator bar(output_reference: OutputReference) { + mint(_redeemer: Void, _policy_id, self: Transaction) { when list.find( - ctx.transaction.inputs, + self.inputs, fn(input) { input.output_reference == output_reference }, ) is { @@ -31,4 +35,8 @@ validator(output_reference: OutputReference) { None -> False } } + + else(_) { + fail + } } diff --git a/examples/acceptance_tests/040/lib/tests.ak b/examples/acceptance_tests/040/lib/tests.ak index 1522eec0..c2067068 100644 --- a/examples/acceptance_tests/040/lib/tests.ak +++ b/examples/acceptance_tests/040/lib/tests.ak @@ -29,7 +29,7 @@ test expect_ford1() { ], ) expect Ford { owner, wheels, truck_bed_limit, .. }: Car = initial_car - owner == #"" && ( wheels == 4 && truck_bed_limit == 10000 ) + owner == #"" && wheels == 4 && truck_bed_limit == 10000 } test expect_ford2() { @@ -42,14 +42,14 @@ test expect_ford2() { car_doors: [], } expect Ford { owner, wheels, remote_connect, .. } = initial_car - owner == #"2222222222" && ( wheels == 6 && remote_connect == #"" ) + owner == #"2222222222" && wheels == 6 && remote_connect == #"" } test expect_list1() { let initial_car = [5, 6, 7] expect [a, b, c] = initial_car - a == 5 && ( b == 6 && c == 7 ) + a == 5 && b == 6 && c == 7 } test expect_list2() { diff --git a/examples/acceptance_tests/047/plutus.json b/examples/acceptance_tests/047/plutus.json index 9a9241cf..9dfc4a4f 100644 --- a/examples/acceptance_tests/047/plutus.json +++ b/examples/acceptance_tests/047/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "foo.spend", + "title": "foo.foo.spend", "datum": { "title": "_datum", "schema": { @@ -23,8 +23,13 @@ "$ref": "#/definitions/Void" } }, - "compiledCode": "585201000032323232232232253330064a229309b2b299980219b8748000c014dd50008a99980398031baa001149858594ccc008cdc3a400060066ea800454ccc014c010dd50008a4c2c2cae6955ceaab9e5573f", - "hash": "84a516ff1f146f698164b5e64ff813e4e22ba2fa35491f2dc3d70935" + "compiledCode": "587601000032323232323225333002323232323253330073370e900118041baa0011323232324a2a66601466e1d2000300b375400a2a66601a60186ea80145261616300d300e002300c001300937540022c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae89", + "hash": "c613c8326fea00dff179b7108f248b60c155881bbce544d84fe573e1" + }, + { + "title": "foo.foo.else", + "compiledCode": "587601000032323232323225333002323232323253330073370e900118041baa0011323232324a2a66601466e1d2000300b375400a2a66601a60186ea80145261616300d300e002300c001300937540022c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae89", + "hash": "c613c8326fea00dff179b7108f248b60c155881bbce544d84fe573e1" } ], "definitions": { diff --git a/examples/acceptance_tests/047/validators/foo.ak b/examples/acceptance_tests/047/validators/foo.ak index 4b750f78..c8d490e7 100644 --- a/examples/acceptance_tests/047/validators/foo.ak +++ b/examples/acceptance_tests/047/validators/foo.ak @@ -1,7 +1,11 @@ -validator { - fn spend(_datum: Void, _redeemer: Void, _ctx: Void) -> Bool { +validator foo { + spend(_datum: Option, _redeemer: Void, oref: Data, _tx: Void) { True } + + else(_) { + fail + } } test foo() { diff --git a/examples/acceptance_tests/054/aiken.lock b/examples/acceptance_tests/054/aiken.lock index ab10346d..59f3e01b 100644 --- a/examples/acceptance_tests/054/aiken.lock +++ b/examples/acceptance_tests/054/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158433, nanos_since_epoch = 380614000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776969, nanos_since_epoch = 835808000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/055/aiken.lock b/examples/acceptance_tests/055/aiken.lock index ea1d982e..472e63d4 100644 --- a/examples/acceptance_tests/055/aiken.lock +++ b/examples/acceptance_tests/055/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 363713000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776974, nanos_since_epoch = 866167000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/061/aiken.lock b/examples/acceptance_tests/061/aiken.lock index e97629d8..3e15749b 100644 --- a/examples/acceptance_tests/061/aiken.lock +++ b/examples/acceptance_tests/061/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158434, nanos_since_epoch = 837171000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776995, nanos_since_epoch = 750600000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/063/aiken.lock b/examples/acceptance_tests/063/aiken.lock index dfc444cc..2cec8363 100644 --- a/examples/acceptance_tests/063/aiken.lock +++ b/examples/acceptance_tests/063/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 367316000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776974, nanos_since_epoch = 455232000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/067/aiken.lock b/examples/acceptance_tests/067/aiken.lock index 7025114f..37bf10bf 100644 --- a/examples/acceptance_tests/067/aiken.lock +++ b/examples/acceptance_tests/067/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158436, nanos_since_epoch = 571367000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724777001, nanos_since_epoch = 587403000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/067/lib/tests.ak b/examples/acceptance_tests/067/lib/tests.ak index 5ed56bd3..c4a66f5c 100644 --- a/examples/acceptance_tests/067/lib/tests.ak +++ b/examples/acceptance_tests/067/lib/tests.ak @@ -322,7 +322,7 @@ test get_proof_4() { let h1: ByteArray = get_proof_item_value(p1) let h2: ByteArray = get_proof_item_value(p2) - size_match && ( h1 == hash_fn(cat) && h2 == right_node_hash ) + size_match && h1 == hash_fn(cat) && h2 == right_node_hash } fn do_from_list( diff --git a/examples/acceptance_tests/068/aiken.lock b/examples/acceptance_tests/068/aiken.lock index 673e5077..3731aa41 100644 --- a/examples/acceptance_tests/068/aiken.lock +++ b/examples/acceptance_tests/068/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158436, nanos_since_epoch = 551807000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776997, nanos_since_epoch = 900786000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/069/aiken.lock b/examples/acceptance_tests/069/aiken.lock index bef9546a..d9630391 100644 --- a/examples/acceptance_tests/069/aiken.lock +++ b/examples/acceptance_tests/069/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 941669000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724777000, nanos_since_epoch = 47370000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/070/aiken.lock b/examples/acceptance_tests/070/aiken.lock index de287192..10526fde 100644 --- a/examples/acceptance_tests/070/aiken.lock +++ b/examples/acceptance_tests/070/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158437, nanos_since_epoch = 43333000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776959, nanos_since_epoch = 949879000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/071/aiken.lock b/examples/acceptance_tests/071/aiken.lock index 57177e6b..2e59bd68 100644 --- a/examples/acceptance_tests/071/aiken.lock +++ b/examples/acceptance_tests/071/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158434, nanos_since_epoch = 487166000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724776963, nanos_since_epoch = 265617000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/071/aiken.toml b/examples/acceptance_tests/071/aiken.toml index 1acf73dc..f6bcb889 100644 --- a/examples/acceptance_tests/071/aiken.toml +++ b/examples/acceptance_tests/071/aiken.toml @@ -1,7 +1,8 @@ name = "aiken-lang/acceptance_test_071" +plutusVersion = "v3" version = "0.0.0" [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/acceptance_tests/071/plutus.json b/examples/acceptance_tests/071/plutus.json index 1405ea1c..f2ad08e5 100644 --- a/examples/acceptance_tests/071/plutus.json +++ b/examples/acceptance_tests/071/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "spend.pool_contract", + "title": "spend.foo.spend", "datum": { "title": "datum", "schema": { @@ -23,8 +23,13 @@ "$ref": "#/definitions/spend~1PoolRedeemer" } }, - "compiledCode": "5904170100003232323232323232232325333004300230053754006264a6660100022c264a66666601a002264a6660140022c264a66666601e0022c2c2c26464a66601a0022c264a6666660240022c2c2c264a66601e6024006266601200e24a66601a6016601c6ea80044c94ccc044004584c94cccccc05800454ccc048c0540084c8c8c94ccc048c0400044c94ccc058004584c94cccccc06c0045858584c94ccc060c06c00c5401458dd68008b180c000980a1baa004153330123003001132533301600116132533333301b00115333017301a00215333014301230153754002264a6660300022c264a66666603a002264a6660340022c264a66666603e0022c2c2c264a666038603e006266602c0082a0122c2c6eb400458c070004c07000858585858c068004c058dd50008b0b0b0b0b0b180c000980a1baa004153330123370e9002000899299980b0008b099299999980d8008a99980b980d0010a99980a1809180a9baa001132533301800116132533333301d001132533301a00116132533333301f001161616132533301c301f0031333016004150091616375a0022c603800260380042c2c2c2c6034002602c6ea8004585858585858c060004c050dd50020b18091baa0031253330113232325333014301200114a226464646464a666032601400c26464a666036601860386ea80044c8c8c94ccc078c070c07cdd5000899192999810180f18109baa0011324a2604a60446ea800458cc01c03c00cc08cc080dd50008b198038068009804244101ff003020301d37540022940c00cc070dd5005180f180d9baa00713232533301b300c301c37540022646464a66603c6038603e6ea80044c8c94ccc080c078c084dd50008992513025302237540022c6600e01e006604660406ea800458cc01c034004c021220101ff003020301d37540022940c00cc070dd5005180f180d9baa00722330053758601260386ea8c024c070dd5001119baf300a301d37546008603a6ea80040088c074c07800488cc00cdd6180e980f180f180d1baa3007301a3754004466ebcc020c06cdd500080111191980080080191299980e0008a6103d87a800013232533301b300500213374a90001980f80125eb804cc010010004c080008c0780048cdd2a40006603266e95200233019375200297ae0330194c103d87a80004bd70180a1baa00130013014375400c4602e00229309b2b1b87480085858585858c04c004c03cdd50008b0b0b1bad00116300f001300f003375a0022c601800260180042c2c2c2c6014002600c6ea800c588894ccc018c010c01cdd5001899299980500080109929999998078008018018018018991929998068008028992999999809000803003003003099299980798090018a8040039bae001300f001300f003375c002601800260106ea800c004dc3a4000ae6955ceaab9e5573eae815d0aba25749", - "hash": "640debfa5063d2e3fd7f23e9777aaf3a0f575a99972ccda8748a49c0" + "compiledCode": "5903a2010000323232323232323225333002323232323253323300830013009375400426464646464a66601a6004601c6ea80204c94ccc044004584c94cccccc05800454ccc048c0540084c8c94ccc044c0180044c94ccc054004584c94cccccc0680045858584c94ccc05cc06800c5401458dd68008b180b80098099baa00315333011300a001132533301500116132533333301a00115333016301900215333013300830143754002264a66602e0022c264a666666038002264a6660320022c264a66666603c0022c2c2c264a666036603c00626660180082a0122c2c6eb400458c06c004c06c00858585858c064004c054dd50008b0b0b0b0b0b180b80098099baa003153330113370e9002000899299980a8008b099299999980d0008a99980b180c8010a9998099804180a1baa001132533301700116132533333301c001132533301900116132533333301e001161616132533301b301e003133300c004150091616375a0022c603600260360042c2c2c2c6032002602a6ea8004585858585858c05c004c04cdd50018b18089baa0021533300f30043010375400a264646464a666026601000229444c8c8c8c94ccc05cc0400144c8c8c94ccc068c03cc06cdd500089919299980e1808980e9baa0011324a26042603c6ea800458cc01406000cc07cc070dd50008b1980200b0009802a44101ff00301c3019375400c2646464a666034601e60366ea80044c8c94ccc070c044c074dd50008992513021301e37540022c6600a030006603e60386ea800458cc010058004c015220101ff00301c3019375400c44660086eb0c020c068dd5001119baf3009301b3754603c603e60366ea800400888cc00cdd6180e180e980e980c9baa00223375e601060346ea800400888c8cc00400400c894ccc06c004530103d87a800013232533301a300500213374a90001980f00125eb804cc010010004c07c008c0740048cdd2a40006603066e95200233018375200297ae0330184c103d87a80004bd7018099baa0013001301337540184602c002602860226ea8014585858585858c04c004c03cdd50040b1112999807980218081baa00313253330130010021325333333018001003003003003132325333016001005132533333301b0010060060060061325333018301b00315008007375c002603000260300066eb8004c054004c044dd50018009b8748000c03cc040008c038004c028dd50011b874800858c02cc030008c028004c028008c020004c010dd50008a4c26cacae6955ceaab9e5573eae815d0aba257481", + "hash": "10e8faa163e7c7699b978c2df5f2b1fadc9796e866d67b88799def6e" + }, + { + "title": "spend.foo.else", + "compiledCode": "5903a2010000323232323232323225333002323232323253323300830013009375400426464646464a66601a6004601c6ea80204c94ccc044004584c94cccccc05800454ccc048c0540084c8c94ccc044c0180044c94ccc054004584c94cccccc0680045858584c94ccc05cc06800c5401458dd68008b180b80098099baa00315333011300a001132533301500116132533333301a00115333016301900215333013300830143754002264a66602e0022c264a666666038002264a6660320022c264a66666603c0022c2c2c264a666036603c00626660180082a0122c2c6eb400458c06c004c06c00858585858c064004c054dd50008b0b0b0b0b0b180b80098099baa003153330113370e9002000899299980a8008b099299999980d0008a99980b180c8010a9998099804180a1baa001132533301700116132533333301c001132533301900116132533333301e001161616132533301b301e003133300c004150091616375a0022c603600260360042c2c2c2c6032002602a6ea8004585858585858c05c004c04cdd50018b18089baa0021533300f30043010375400a264646464a666026601000229444c8c8c8c94ccc05cc0400144c8c8c94ccc068c03cc06cdd500089919299980e1808980e9baa0011324a26042603c6ea800458cc01406000cc07cc070dd50008b1980200b0009802a44101ff00301c3019375400c2646464a666034601e60366ea80044c8c94ccc070c044c074dd50008992513021301e37540022c6600a030006603e60386ea800458cc010058004c015220101ff00301c3019375400c44660086eb0c020c068dd5001119baf3009301b3754603c603e60366ea800400888cc00cdd6180e180e980e980c9baa00223375e601060346ea800400888c8cc00400400c894ccc06c004530103d87a800013232533301a300500213374a90001980f00125eb804cc010010004c07c008c0740048cdd2a40006603066e95200233018375200297ae0330184c103d87a80004bd7018099baa0013001301337540184602c002602860226ea8014585858585858c04c004c03cdd50040b1112999807980218081baa00313253330130010021325333333018001003003003003132325333016001005132533333301b0010060060060061325333018301b00315008007375c002603000260300066eb8004c054004c044dd50018009b8748000c03cc040008c038004c028dd50011b874800858c02cc030008c028004c028008c020004c010dd50008a4c26cacae6955ceaab9e5573eae815d0aba257481", + "hash": "10e8faa163e7c7699b978c2df5f2b1fadc9796e866d67b88799def6e" } ], "definitions": { diff --git a/examples/acceptance_tests/071/validators/spend.ak b/examples/acceptance_tests/071/validators/spend.ak index 368a2d5a..2d80e083 100644 --- a/examples/acceptance_tests/071/validators/spend.ak +++ b/examples/acceptance_tests/071/validators/spend.ak @@ -1,17 +1,15 @@ +use aiken/collection/list use aiken/hash.{Blake2b_224, Hash} use aiken/interval.{Finite} -use aiken/list use aiken/option -use aiken/transaction.{ - Datum, InlineDatum, Input, Mint, Output, OutputReference, ScriptContext, Spend, - Transaction, TransactionId, ValidityRange, -} -use aiken/transaction/credential.{ - Address, Script, ScriptCredential, VerificationKey, VerificationKeyCredential, -} -use aiken/transaction/value.{ +use cardano/assets.{ AssetName, PolicyId, Value, add, flatten, from_asset, negate, quantity_of, } +use cardano/credential.{Address, Script, VerificationKey} +use cardano/transaction.{ + Datum, InlineDatum, Input, Output, OutputReference, Transaction, TransactionId, + ValidityRange, +} // Datum/Redeemer pool pub type PoolDatum { @@ -20,7 +18,7 @@ pub type PoolDatum { lent_out: Int, } -type PoolRedeemer { +pub type PoolRedeemer { action: PoolRedeemerType, } @@ -45,67 +43,73 @@ pub type CurrencySymbol { asset_name: AssetName, } -pub fn get_output(ctx: ScriptContext, address: Address) -> Option { - list.find(ctx.transaction.outputs, fn(output) { output.address == address }) +pub fn get_output(transaction: Transaction, address: Address) -> Option { + list.find(transaction.outputs, fn(output) { output.address == address }) } -pub fn get_input(ctx: ScriptContext, address: Address) -> Option { - list.find( - ctx.transaction.inputs, - fn(input) { input.output.address == address }, - ) +pub fn get_input(transaction: Transaction, address: Address) -> Option { + list.find(transaction.inputs, fn(input) { input.output.address == address }) } pub fn scripthash_address(scripthash: ByteArray) { - Address { - payment_credential: ScriptCredential(scripthash), - stake_credential: None, - } + Address { payment_credential: Script(scripthash), stake_credential: None } } pub fn validate_pool_deposit( - ctx: ScriptContext, + transaction: Transaction, output_reference: OutputReference, datum: PoolDatum, redeemer: PoolDepositRedeemer, ) -> Bool { let validator_address = scripthash_address(#"ff") - expect Some(pool_output) = get_output(ctx, validator_address) - expect Some(pool_input) = get_input(ctx, validator_address) + expect Some(pool_output) = get_output(transaction, validator_address) + expect Some(pool_input) = get_input(transaction, validator_address) True } pub fn validate_pool_borrow( - ctx: ScriptContext, + transaction: Transaction, output_reference: OutputReference, datum: PoolDatum, redeemer: PoolBorrowRedeemer, ) -> Bool { let validator_address = scripthash_address(#"ff") - expect Some(pool_output) = get_output(ctx, validator_address) - expect Some(pool_input) = get_input(ctx, validator_address) + expect Some(pool_output) = get_output(transaction, validator_address) + expect Some(pool_input) = get_input(transaction, validator_address) True } -validator { - fn pool_contract(datum: PoolDatum, redeemer: PoolRedeemer, ctx: ScriptContext) { +validator foo { + spend( + datum: Option, + redeemer: PoolRedeemer, + output_ref: OutputReference, + transaction: Transaction, + ) { + expect Some(datum) = datum when redeemer.action is { PoolWithdraw(_) -> True PoolDeposit(pool_deposit_redeemer) -> - when ctx.purpose is { - Spend(output_ref) -> - validate_pool_deposit(ctx, output_ref, datum, pool_deposit_redeemer) - _ -> False - } + validate_pool_deposit( + transaction, + output_ref, + datum, + pool_deposit_redeemer, + ) PoolBorrow(pool_borrow_redeemer) -> - when ctx.purpose is { - Spend(output_ref) -> - validate_pool_borrow(ctx, output_ref, datum, pool_borrow_redeemer) - _ -> False - } + validate_pool_borrow( + transaction, + output_ref, + datum, + pool_borrow_redeemer, + ) } } + + else(_) { + fail + } } diff --git a/examples/acceptance_tests/072/aiken.lock b/examples/acceptance_tests/072/aiken.lock index a26c777c..b056341f 100644 --- a/examples/acceptance_tests/072/aiken.lock +++ b/examples/acceptance_tests/072/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158434, nanos_since_epoch = 466737000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776989, nanos_since_epoch = 656788000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/073/aiken.lock b/examples/acceptance_tests/073/aiken.lock index ebd1a468..ab783864 100644 --- a/examples/acceptance_tests/073/aiken.lock +++ b/examples/acceptance_tests/073/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158432, nanos_since_epoch = 54533000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776984, nanos_since_epoch = 618944000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/074/aiken.lock b/examples/acceptance_tests/074/aiken.lock index 71a198e4..be4a2579 100644 --- a/examples/acceptance_tests/074/aiken.lock +++ b/examples/acceptance_tests/074/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158437, nanos_since_epoch = 127361000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776985, nanos_since_epoch = 375340000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/077/aiken.lock b/examples/acceptance_tests/077/aiken.lock index 0687e2d9..b2de77b0 100644 --- a/examples/acceptance_tests/077/aiken.lock +++ b/examples/acceptance_tests/077/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 59914000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724776958, nanos_since_epoch = 450634000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/077/aiken.toml b/examples/acceptance_tests/077/aiken.toml index 2175d45e..f9f4ad3c 100644 --- a/examples/acceptance_tests/077/aiken.toml +++ b/examples/acceptance_tests/077/aiken.toml @@ -1,7 +1,8 @@ name = "aiken-lang/acceptance_test_077" +plutusVersion = "v3" version = "0.0.0" [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/acceptance_tests/077/plutus.json b/examples/acceptance_tests/077/plutus.json index 9e1b743c..e3aeb65f 100644 --- a/examples/acceptance_tests/077/plutus.json +++ b/examples/acceptance_tests/077/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "spend.gift_card", + "title": "spend.foo.mint", "redeemer": { "title": "rdmr", "schema": { @@ -27,15 +27,34 @@ { "title": "utxo_ref", "schema": { - "$ref": "#/definitions/aiken~1transaction~1OutputReference" + "$ref": "#/definitions/cardano~1transaction~1OutputReference" } } ], - "compiledCode": "5901ce010000323232323232322322232323232533300930040011533300c300b375400a2a0042c2a66601260060022a66601860166ea8014540085858c024dd50020929998041919192999805980318061baa00113232323253330123015002132325333011300c3012375401a2a666022646600200200c44a66602c00229404c94ccc050cdd7980c980b1baa301900201114a226600600600260320022a6660226016002266e3c00803c5280b0b1bad3012002375c60200022c602600264a66601c6010601e6ea800452f5bded8c026eacc04cc040dd500099191980080099198008009bab3015301630163016301600522533301400114bd6f7b630099191919299980a99b9148900002153330153371e91010000210031005133019337606ea4008dd3000998030030019bab3016003375c60280046030004602c00244a666026002298103d87a800013232323253330143372200e0042a66602866e3c01c0084cdd2a4000660306e980052f5c02980103d87a80001330060060033756602a0066eb8c04c008c05c008c054004dd7180918079baa00337586022002601a6ea800858c03cc040008c038004c028dd50008a4c26cac6e1d2002370e90001bae0015734aae7555cf2ab9f5740ae855d11", - "hash": "4ef9bf69c108d6abd0a5af057a519df56d7fb333de428563810495a0" + "compiledCode": "59018501000032323232323232232225333005323232323253323300b3001300c3754004264646464a66601e600a0022a66602460226ea801c540085854ccc03cc00c00454ccc048c044dd50038a8010b0b18079baa006132323232533301430170021323253330133009301437540162a666026646600200200c44a66603000229404c94ccc058cdd7980d980c1baa301b00201314a226600600600260360022a666026600e002266e3c0080445280b0b1bad3014002375c60240022c602a00264a666020600860226ea800452f5bded8c026eacc054c048dd500099198008009bab3015301630163016301600322533301400114c103d87a80001323232325333015337220140042a66602a66e3c0280084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd6180980098079baa007370e90011bae3010300d37540046e1d200016300e300f002300d001300d002300b0013007375400229309b2b1bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "784b2caa5e99b3d37361e3c3d51e7fd39f616025037eee525b73c5da" }, { - "title": "spend2.backtrace", + "title": "spend.foo.else", + "parameters": [ + { + "title": "token_name", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "59018501000032323232323232232225333005323232323253323300b3001300c3754004264646464a66601e600a0022a66602460226ea801c540085854ccc03cc00c00454ccc048c044dd50038a8010b0b18079baa006132323232533301430170021323253330133009301437540162a666026646600200200c44a66603000229404c94ccc058cdd7980d980c1baa301b00201314a226600600600260360022a666026600e002266e3c0080445280b0b1bad3014002375c60240022c602a00264a666020600860226ea800452f5bded8c026eacc054c048dd500099198008009bab3015301630163016301600322533301400114c103d87a80001323232325333015337220140042a66602a66e3c0280084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd6180980098079baa007370e90011bae3010300d37540046e1d200016300e300f002300d001300d002300b0013007375400229309b2b1bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "784b2caa5e99b3d37361e3c3d51e7fd39f616025037eee525b73c5da" + }, + { + "title": "spend2.foo.spend", "datum": { "title": "_datum", "schema": { @@ -48,8 +67,13 @@ "$ref": "#/definitions/Void" } }, - "compiledCode": "58ac010000323232323232322323223225333007533300730053008375464660020026eb0c034c038c038c028dd5180698051baa00222533300c00114c0103d87a800013232533300b4a2266e9520003300f0024bd70099802002000980800118070008a511614984d9594ccc014c00cc018dd50008a99980418039baa001149858594ccc00cc004c010dd50010a99980318029baa00214985858dc3a4000ae6955ceaab9e5573eae815d0aba201", - "hash": "c58d31e63ad2d807c2188dfb1deafc433fe0f6a867e5cf8df68f068f" + "compiledCode": "58c70100003232323232323225333002323232323253330073370e900118041baa001132323232533300b3370e900018061baa32330010013758602260246024601c6ea8024894ccc0400045300103d87a800013232533300f4a2266e952000330130024bd70099802002000980a00118090008a5116533300a3370e900018059baa0051533300d300c375400a2930b0b18071807801180680098049baa00116300b300c002300a001300a00230080013004375400229309b2b2b9a5573aaae7955cfaba05742ae881", + "hash": "c4700bfdb383c890d2a4c4505d3fc6d4b51e1998c3f33dd83e12ba44" + }, + { + "title": "spend2.foo.else", + "compiledCode": "58c70100003232323232323225333002323232323253330073370e900118041baa001132323232533300b3370e900018061baa32330010013758602260246024601c6ea8024894ccc0400045300103d87a800013232533300f4a2266e952000330130024bd70099802002000980a00118090008a5116533300a3370e900018059baa0051533300d300c375400a2930b0b18071807801180680098049baa00116300b300c002300a001300a00230080013004375400229309b2b2b9a5573aaae7955cfaba05742ae881", + "hash": "c4700bfdb383c890d2a4c4505d3fc6d4b51e1998c3f33dd83e12ba44" } ], "definitions": { @@ -70,7 +94,7 @@ } ] }, - "aiken/transaction/OutputReference": { + "cardano/transaction/OutputReference": { "title": "OutputReference", "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", "anyOf": [ @@ -81,7 +105,7 @@ "fields": [ { "title": "transaction_id", - "$ref": "#/definitions/aiken~1transaction~1TransactionId" + "$ref": "#/definitions/ByteArray" }, { "title": "output_index", @@ -91,23 +115,6 @@ } ] }, - "aiken/transaction/TransactionId": { - "title": "TransactionId", - "description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.", - "anyOf": [ - { - "title": "TransactionId", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "hash", - "$ref": "#/definitions/ByteArray" - } - ] - } - ] - }, "spend/Action": { "title": "Action", "anyOf": [ diff --git a/examples/acceptance_tests/077/validators/spend.ak b/examples/acceptance_tests/077/validators/spend.ak index 0902e6a9..c61924e1 100644 --- a/examples/acceptance_tests/077/validators/spend.ak +++ b/examples/acceptance_tests/077/validators/spend.ak @@ -1,23 +1,19 @@ -use aiken/dict -use aiken/list.{find, foldr} -use aiken/transaction.{Input, - OutputReference, ScriptContext, Spend, Transaction} as tx -use aiken/transaction/value.{add, zero} +use aiken/collection/dict +use aiken/collection/list.{find, foldr} +use cardano/assets.{PolicyId, add, zero} +use cardano/transaction.{Input, OutputReference, Transaction} as tx -type Action { +pub type Action { Mint Burn } -validator(token_name: ByteArray, utxo_ref: OutputReference) { - fn gift_card(rdmr: Action, ctx: ScriptContext) -> Bool { - let ScriptContext { transaction, purpose } = ctx - expect tx.Mint(policy_id) = purpose +validator foo(token_name: ByteArray, utxo_ref: OutputReference) { + mint(rdmr: Action, policy_id: PolicyId, transaction: Transaction) { let Transaction { inputs, mint, .. } = transaction expect [Pair(asset_name, amount)] = mint - |> value.from_minted_value - |> value.tokens(policy_id) + |> assets.tokens(policy_id) |> dict.to_pairs() when rdmr is { Mint -> { @@ -28,4 +24,8 @@ validator(token_name: ByteArray, utxo_ref: OutputReference) { Burn -> todo @"burn" } } + + else(_) { + fail + } } diff --git a/examples/acceptance_tests/077/validators/spend2.ak b/examples/acceptance_tests/077/validators/spend2.ak index 1e84d996..0e9028d3 100644 --- a/examples/acceptance_tests/077/validators/spend2.ak +++ b/examples/acceptance_tests/077/validators/spend2.ak @@ -1,15 +1,24 @@ -use aiken/list -use aiken/transaction.{Output, ScriptContext} +use aiken/collection/list +use cardano/transaction.{Output, Transaction} -validator { - fn backtrace(_datum: Void, _redeemer: Void, context: ScriptContext) -> Bool { - expect Some(_) = list.find(context.transaction.outputs, fn(_) { True }) - let _ = find_stuff(context) +validator foo { + spend( + _datum: Option, + _redeemer: Void, + _ref: Data, + transaction: Transaction, + ) { + expect Some(_) = list.find(transaction.outputs, fn(_) { True }) + let _ = find_stuff(transaction) True } + + else(_) { + fail + } } -fn find_stuff(context: ScriptContext) -> Output { - expect Some(stuff) = list.find(context.transaction.outputs, fn(_) { True }) +fn find_stuff(transaction: Transaction) -> Output { + expect Some(stuff) = list.find(transaction.outputs, fn(_) { True }) stuff } diff --git a/examples/acceptance_tests/079/plutus.json b/examples/acceptance_tests/079/plutus.json index ffb53e6f..15d13ffe 100644 --- a/examples/acceptance_tests/079/plutus.json +++ b/examples/acceptance_tests/079/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "foo.spend", + "title": "foo.foo.spend", "datum": { "title": "datum", "schema": { @@ -20,42 +20,32 @@ "redeemer": { "title": "redeemer", "schema": { - "$ref": "#/definitions/RedeemerWrapper$Int" + "$ref": "#/definitions/Int" } }, - "compiledCode": "5850010000323232322253330033370e900018021baa001153330033370e6eb4009205414984d9584c8c894ccc018cdc399b800030024815052613656375a600e600c6ea8008dd68012b9a5573aaae795d09", - "hash": "dcac7ebcaf29721b4b48cc73775fa91939ad9015ea267b697e92b051" + "compiledCode": "589a01000032323232322533300232323232323253330083370e9001000899191919299980619b8748000c034dd5001099b87337006eb4c03cc038dd5001000a40a82c6eb4018c034c038008c030004c028dd50010a99980419b87480000044c8cdc39bad00448150dd7180598051baa00216300837540026012601400460100026010004600c00260086ea8004526136565734aae7555cf2ba15745", + "hash": "86f0253dd8dd836d6588f5794eb8f08edd4476df28b607553126846e" }, { - "title": "foo.mint", + "title": "foo.foo.mint", "redeemer": { "title": "redeemer", "schema": { "$ref": "#/definitions/Int" } }, - "compiledCode": "5850010000323232322253330033370e900018021baa001153330033370e6eb4009205414984d9584c8c894ccc018cdc399b800030024815052613656375a600e600c6ea8008dd68012b9a5573aaae795d09", - "hash": "dcac7ebcaf29721b4b48cc73775fa91939ad9015ea267b697e92b051" + "compiledCode": "589a01000032323232322533300232323232323253330083370e9001000899191919299980619b8748000c034dd5001099b87337006eb4c03cc038dd5001000a40a82c6eb4018c034c038008c030004c028dd50010a99980419b87480000044c8cdc39bad00448150dd7180598051baa00216300837540026012601400460100026010004600c00260086ea8004526136565734aae7555cf2ba15745", + "hash": "86f0253dd8dd836d6588f5794eb8f08edd4476df28b607553126846e" + }, + { + "title": "foo.foo.else", + "compiledCode": "589a01000032323232322533300232323232323253330083370e9001000899191919299980619b8748000c034dd5001099b87337006eb4c03cc038dd5001000a40a82c6eb4018c034c038008c030004c028dd50010a99980419b87480000044c8cdc39bad00448150dd7180598051baa00216300837540026012601400460100026010004600c00260086ea8004526136565734aae7555cf2ba15745", + "hash": "86f0253dd8dd836d6588f5794eb8f08edd4476df28b607553126846e" } ], "definitions": { "Int": { "dataType": "integer" - }, - "RedeemerWrapper$Int": { - "title": "Wrapped Redeemer", - "description": "A redeemer wrapped in an extra constructor to make multi-validator detection possible on-chain.", - "anyOf": [ - { - "dataType": "constructor", - "index": 1, - "fields": [ - { - "$ref": "#/definitions/Int" - } - ] - } - ] } } } \ No newline at end of file diff --git a/examples/acceptance_tests/079/validators/foo.ak b/examples/acceptance_tests/079/validators/foo.ak index 0889e994..9dcb19f0 100644 --- a/examples/acceptance_tests/079/validators/foo.ak +++ b/examples/acceptance_tests/079/validators/foo.ak @@ -1,9 +1,14 @@ -validator { - fn spend(datum: Int, redeemer: Int, _context: Data) { +validator foo { + spend(datum: Option, redeemer: Int, _ref: Data, _transaction: Data) { + expect Some(datum) = datum datum + redeemer == 42 } - fn mint(redeemer: Int, _context: Data) { + mint(redeemer: Int, _policy: ByteArray, _transaction: Data) { redeemer == 42 } + + else(_) { + fail + } } diff --git a/examples/acceptance_tests/082/aiken.lock b/examples/acceptance_tests/082/aiken.lock index 46af44a9..ccd0fa07 100644 --- a/examples/acceptance_tests/082/aiken.lock +++ b/examples/acceptance_tests/082/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158431, nanos_since_epoch = 785683000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776965, nanos_since_epoch = 937696000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/083/aiken.lock b/examples/acceptance_tests/083/aiken.lock index 55a88468..0301487c 100644 --- a/examples/acceptance_tests/083/aiken.lock +++ b/examples/acceptance_tests/083/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158433, nanos_since_epoch = 377116000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776958, nanos_since_epoch = 302886000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/084/aiken.lock b/examples/acceptance_tests/084/aiken.lock index 3df326f9..434074d3 100644 --- a/examples/acceptance_tests/084/aiken.lock +++ b/examples/acceptance_tests/084/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158433, nanos_since_epoch = 339674000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776958, nanos_since_epoch = 249560000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/086/aiken.lock b/examples/acceptance_tests/086/aiken.lock index fb9b4ac9..10464475 100644 --- a/examples/acceptance_tests/086/aiken.lock +++ b/examples/acceptance_tests/086/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158437, nanos_since_epoch = 77334000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724776991, nanos_since_epoch = 269398000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/086/aiken.toml b/examples/acceptance_tests/086/aiken.toml index 914a1b5a..8da7a4ab 100644 --- a/examples/acceptance_tests/086/aiken.toml +++ b/examples/acceptance_tests/086/aiken.toml @@ -4,5 +4,5 @@ description = "" [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/acceptance_tests/086/plutus.json b/examples/acceptance_tests/086/plutus.json index a5177998..d2546429 100644 --- a/examples/acceptance_tests/086/plutus.json +++ b/examples/acceptance_tests/086/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "other.validate", + "title": "other.validate.spend", "datum": { "title": "raw_datum", "schema": { @@ -23,8 +23,13 @@ "$ref": "#/definitions/Data" } }, - "compiledCode": "5902b1010000323232323232322225333004323232533300730033008375400c264a6660160022c264a66666601e0022a666018601c00426464a666016600e002264a66601e0022c264a6666660260022a66602060240042a66601a6012601c6ea80044c94ccc044004584c94cccccc05400454ccc048c05000854ccc03cc02cc040dd500089929998098008b099299999980b800899299980a8008b099299999980c8008a99980b180c001099980680189919299980a9808800899299980c8008b099299999980e8008a99980d180e00109919299980c980a800899299980e8008b09929999998108008a99980f1810001099980a8008a8020b0b0b0b0b0b180f000980d9baa003153330193014001132533301d001161325333333021001161616132325333020001161325333333024001161616132325333023001161325333333027001161616132533302530270031500b16375a0022c604800260480066eb400458c084004c08400cdd68008b180f000980d9baa00316301937540042a0082c2c2c2c2c6034002602e6ea800c54ccc054c04000454ccc060c05cdd50018a8010b0b180a9baa0021500a16161616161630160013016002161616163014001301137540022c2c2c2c2c2c6024002601e6ea8004585858585858c040004c034dd50018a99980598030008a99980718069baa003150021616300b37540042a666012600a60146ea8c034c02cdd50040a5114a02c2c2c2c2c601800260126ea801858888c94ccc028c0180044c94ccc03800400c4c94cccccc0480040100100100104c94ccc040c04800c54018014dd7000980780098061baa0041533300a3005001132533300e00100313253333330120010040040040041325333010301200315006005375c002601e00260186ea8010008c028dd50019b8748008dc3a400029309b2b2b9a5573aaae7955cfaba15744ae91", - "hash": "22fcdd5defc5c63e55afed5ee2e88c9c695809f8b1e99342e045438d" + "compiledCode": "5902fd010000323232323232322533300232323232325332330083001300937540042646464a664660186002601a6ea80084c8c94ccc038c00cc03cdd500109929998090008b099299999980b0008a999809980a8010991929998091803800899299980b0008b099299999980d0008a99980b980c8010a99980a1804980a9baa001132533301800116132533333301c00115333019301b00215333016300b30173754002264a6660340022c264a66666603c002264a6660380022c264a6666660400022a66603a603e004266601a00626464a6660386022002264a6660400022c264a6666660480022a666042604600426464a666040602a002264a6660480022c264a6666660500022a66604a604e004266602a0022a0082c2c2c2c2c2c604a00260446ea800c54ccc080c0640044c94ccc090004584c94cccccc0a00045858584c8c94ccc09c004584c94cccccc0ac0045858584c8c94ccc0a8004584c94cccccc0b80045858584c94ccc0b0c0b800c5402c58dd68008b181580098158019bad0011630280013028003375a0022c604a00260446ea800c58c080dd50010a8020b0b0b0b0b1810800980f1baa0031533301c30150011533301f301e37540062a0042c2c60386ea800854028585858585858c074004c07400858585858c06c004c060dd50008b0b0b0b0b0b180c800980b1baa0011616161616163017001301437540062a66602460160022a66602a60286ea800c540085858c048dd50010a999808180298089baa30143012375400829445280b0b0b0b0b180980098081baa002162223253330113006001132533301500100313253333330190010040040040041325333017301900315006005375c002602c00260266ea801054ccc044c0280044c94ccc05400400c4c94cccccc0640040100100100104c94ccc05cc06400c54018014dd7000980b00098099baa004002301137540066020601c6ea8008dc3a40002c601c601e004601a00260146ea8008dc3a40042c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae895d21", + "hash": "a63866b5537d618101fccdf892f6bb58f0f1092bc483bfedca3a813e" + }, + { + "title": "other.validate.else", + "compiledCode": "5902fd010000323232323232322533300232323232325332330083001300937540042646464a664660186002601a6ea80084c8c94ccc038c00cc03cdd500109929998090008b099299999980b0008a999809980a8010991929998091803800899299980b0008b099299999980d0008a99980b980c8010a99980a1804980a9baa001132533301800116132533333301c00115333019301b00215333016300b30173754002264a6660340022c264a66666603c002264a6660380022c264a6666660400022a66603a603e004266601a00626464a6660386022002264a6660400022c264a6666660480022a666042604600426464a666040602a002264a6660480022c264a6666660500022a66604a604e004266602a0022a0082c2c2c2c2c2c604a00260446ea800c54ccc080c0640044c94ccc090004584c94cccccc0a00045858584c8c94ccc09c004584c94cccccc0ac0045858584c8c94ccc0a8004584c94cccccc0b80045858584c94ccc0b0c0b800c5402c58dd68008b181580098158019bad0011630280013028003375a0022c604a00260446ea800c58c080dd50010a8020b0b0b0b0b1810800980f1baa0031533301c30150011533301f301e37540062a0042c2c60386ea800854028585858585858c074004c07400858585858c06c004c060dd50008b0b0b0b0b0b180c800980b1baa0011616161616163017001301437540062a66602460160022a66602a60286ea800c540085858c048dd50010a999808180298089baa30143012375400829445280b0b0b0b0b180980098081baa002162223253330113006001132533301500100313253333330190010040040040041325333017301900315006005375c002602c00260266ea801054ccc044c0280044c94ccc05400400c4c94cccccc0640040100100100104c94ccc05cc06400c54018014dd7000980b00098099baa004002301137540066020601c6ea8008dc3a40002c601c601e004601a00260146ea8008dc3a40042c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae895d21", + "hash": "a63866b5537d618101fccdf892f6bb58f0f1092bc483bfedca3a813e" } ], "definitions": { diff --git a/examples/acceptance_tests/086/validators/other.ak b/examples/acceptance_tests/086/validators/other.ak index 7dcd3aee..c548df3f 100644 --- a/examples/acceptance_tests/086/validators/other.ak +++ b/examples/acceptance_tests/086/validators/other.ak @@ -1,5 +1,5 @@ -use aiken/transaction.{ScriptContext} -use aiken/transaction/credential.{Address} +use cardano/credential.{Address} +use cardano/transaction.{Transaction} type TestData { addr: Address, @@ -9,13 +9,18 @@ type TestDatum { data: Option, } -validator { - fn validate(raw_datum: Data, _redeemer: Data, _context: ScriptContext) -> Bool { - expect datum: TestDatum = raw_datum +validator validate { + spend(raw_datum: Option, _redeemer: Data, oref: Data, _tx: Transaction) { + expect Some(datum): Option = raw_datum + expect datum: TestDatum = datum let TestDatum { data } = datum when data is { Some(_) -> True None -> False } } + + else(_) { + fail + } } diff --git a/examples/acceptance_tests/087/aiken.lock b/examples/acceptance_tests/087/aiken.lock index c422013d..d8ea5732 100644 --- a/examples/acceptance_tests/087/aiken.lock +++ b/examples/acceptance_tests/087/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 341686000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776982, nanos_since_epoch = 107153000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/088/aiken.lock b/examples/acceptance_tests/088/aiken.lock index bf6a6289..5e6cbb9b 100644 --- a/examples/acceptance_tests/088/aiken.lock +++ b/examples/acceptance_tests/088/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158431, nanos_since_epoch = 948979000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776991, nanos_since_epoch = 282756000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/089/aiken.lock b/examples/acceptance_tests/089/aiken.lock index f58439fc..0483893d 100644 --- a/examples/acceptance_tests/089/aiken.lock +++ b/examples/acceptance_tests/089/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158435, nanos_since_epoch = 937845000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724776982, nanos_since_epoch = 146951000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/089/aiken.toml b/examples/acceptance_tests/089/aiken.toml index ff0ea909..137b61ba 100644 --- a/examples/acceptance_tests/089/aiken.toml +++ b/examples/acceptance_tests/089/aiken.toml @@ -4,5 +4,5 @@ description = "" [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/acceptance_tests/089/lib/tests.ak b/examples/acceptance_tests/089/lib/tests.ak index 24e8c5a0..ab39bad4 100644 --- a/examples/acceptance_tests/089/lib/tests.ak +++ b/examples/acceptance_tests/089/lib/tests.ak @@ -1,7 +1,6 @@ -use aiken/cbor -use aiken/transaction.{Datum, InlineDatum, NoDatum, Output} -use aiken/transaction/credential.{Address, VerificationKeyCredential} -use aiken/transaction/value.{from_lovelace} +use cardano/assets.{from_lovelace} +use cardano/credential.{Address, VerificationKey} +use cardano/transaction.{Datum, InlineDatum, NoDatum, Output} type SmallOracleState { Thing(Int) @@ -18,7 +17,7 @@ fn create_output( let x = Output { address: Address { - payment_credential: VerificationKeyCredential(payment_key), + payment_credential: VerificationKey(payment_key), stake_credential: None, }, value: from_lovelace(value), diff --git a/examples/acceptance_tests/089/plutus.json b/examples/acceptance_tests/089/plutus.json index ddbfddbb..a2803504 100644 --- a/examples/acceptance_tests/089/plutus.json +++ b/examples/acceptance_tests/089/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "test2.simple_oneshot", + "title": "test2.simple_oneshot.mint", "redeemer": { "title": "_r", "schema": { @@ -21,12 +21,25 @@ { "title": "utxo_ref", "schema": { - "$ref": "#/definitions/aiken~1transaction~1OutputReference" + "$ref": "#/definitions/cardano~1transaction~1OutputReference" } } ], - "compiledCode": "58d8010000323232323232322232322533300632325333008300530093754601a601c00426464a666014600e60166ea8cc00400c8cdd7980198069baa00100a1533300a3007300b375466002006466ebcc00cc034dd50008050a5114a02c44646600200200644a6660200022980103d87a800013232533300f300500213374a90001980980125eb804cc010010004c050008c0480048c03800458dd6180618049baa300c0013008375400229309b2b2999802180098029baa00215333007300637540042930b0b1b87480015cd2ab9d5573caae7d5d02ba15745", - "hash": "0934dd37409ea743705a7340769acd8c84843fec54013e9f0ced9251" + "compiledCode": "58f00100003232323232323222533300332323232325332330093001300a375400426464646464a66601c600c601e6ea8cc00400c8cdd7980198089baa00100e1533300e3006300f375466002006466ebcc00cc044dd50008070a5114a02c44646600200200644a666028002298103d87a8000132325333013300500213374a90001980b80125eb804cc010010004c060008c0580048c048004dd6180818069baa007533300a3002300b37540082a66601a60186ea80105261616375c601c60166ea8008dc3a40002c6018601a004601600260160046012002600a6ea8004526136565734aae7555cf2ab9f5740ae855d101", + "hash": "6f67a4f89e77e01da00ed12f89b15baa823791e83757d5ac97843e91" + }, + { + "title": "test2.simple_oneshot.else", + "parameters": [ + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "58f00100003232323232323222533300332323232325332330093001300a375400426464646464a66601c600c601e6ea8cc00400c8cdd7980198089baa00100e1533300e3006300f375466002006466ebcc00cc044dd50008070a5114a02c44646600200200644a666028002298103d87a8000132325333013300500213374a90001980b80125eb804cc010010004c060008c0580048c048004dd6180818069baa007533300a3002300b37540082a66601a60186ea80105261616375c601c60166ea8008dc3a40002c6018601a004601600260160046012002600a6ea8004526136565734aae7555cf2ab9f5740ae855d101", + "hash": "6f67a4f89e77e01da00ed12f89b15baa823791e83757d5ac97843e91" } ], "definitions": { @@ -47,7 +60,7 @@ } ] }, - "aiken/transaction/OutputReference": { + "cardano/transaction/OutputReference": { "title": "OutputReference", "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", "anyOf": [ @@ -58,7 +71,7 @@ "fields": [ { "title": "transaction_id", - "$ref": "#/definitions/aiken~1transaction~1TransactionId" + "$ref": "#/definitions/ByteArray" }, { "title": "output_index", @@ -67,23 +80,6 @@ ] } ] - }, - "aiken/transaction/TransactionId": { - "title": "TransactionId", - "description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.", - "anyOf": [ - { - "title": "TransactionId", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "hash", - "$ref": "#/definitions/ByteArray" - } - ] - } - ] } } } \ No newline at end of file diff --git a/examples/acceptance_tests/089/validators/test2.ak b/examples/acceptance_tests/089/validators/test2.ak index 4a445db0..4434ed2c 100644 --- a/examples/acceptance_tests/089/validators/test2.ak +++ b/examples/acceptance_tests/089/validators/test2.ak @@ -1,10 +1,7 @@ -use aiken/list -use aiken/transaction.{ - Input, Mint, NoDatum, Output, OutputReference, ScriptContext, Transaction, - TransactionId, -} -use aiken/transaction/credential.{Address, VerificationKeyCredential} -use aiken/transaction/value +use aiken/collection/list +use cardano/assets +use cardano/credential.{Address, VerificationKey} +use cardano/transaction.{Input, NoDatum, Output, OutputReference, Transaction} pub const own_hash = #"01020304050607080910111213140102030405060708091011121314" @@ -20,17 +17,14 @@ pub fn beneficiary_address() { pub fn keyhash_address(keyhash: ByteArray) { Address { - payment_credential: VerificationKeyCredential(keyhash), + payment_credential: VerificationKey(keyhash), stake_credential: None, } } -validator(utxo_ref: OutputReference) { - fn simple_oneshot(_r: Void, ctx: ScriptContext) -> Bool { - let ScriptContext { transaction, purpose } = ctx - let Transaction { inputs, .. } = transaction - - expect Mint(_policy_id) = purpose +validator simple_oneshot(utxo_ref: OutputReference) { + mint(_r: Void, _policy_id: ByteArray, self: Transaction) { + let Transaction { inputs, .. } = self expect Some(_input) = list.find(inputs, fn(input) { input.output_reference == utxo_ref }) @@ -42,31 +36,34 @@ validator(utxo_ref: OutputReference) { None -> False } } + + else(_) { + fail + } } test test_simple_oneshot() { let output = Output { address: beneficiary_address(), - value: value.zero(), + value: assets.zero(), datum: NoDatum, reference_script: None, } - let val = - value.from_asset(policy_id: own_hash, asset_name: "testtoken", quantity: 1) - let utxo = - OutputReference { transaction_id: TransactionId(""), output_index: 0 } + let mint = + assets.from_asset(policy_id: own_hash, asset_name: "testtoken", quantity: 1) + let utxo = OutputReference { transaction_id: "", output_index: 0 } let input = Input { output_reference: utxo, output } let tx = Transaction { ..transaction.placeholder(), - mint: value.to_minted_value(val), + mint: mint, extra_signatories: [other_hash], inputs: [input], } - let context = ScriptContext { purpose: Mint(own_hash), transaction: tx } - simple_oneshot(utxo, Void, context) == True + + simple_oneshot.mint(utxo, Void, own_hash, tx) == True } diff --git a/examples/acceptance_tests/090/plutus.json b/examples/acceptance_tests/090/plutus.json index 2408316c..31c9f2e0 100644 --- a/examples/acceptance_tests/090/plutus.json +++ b/examples/acceptance_tests/090/plutus.json @@ -5,12 +5,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" } }, "validators": [ { - "title": "foo.spend", + "title": "foo.foo.spend", "datum": { "title": "datum", "schema": { @@ -23,8 +23,13 @@ "$ref": "#/definitions/Data" } }, - "compiledCode": "583f010000322322253330053370e00690487777c9cfdde5c8f27bf4c1637fc55b5eeef7d8c4d9e0d4454967ff7d6e7ee6e242eb60c6318a4c26cac6eb40055cd1", - "hash": "6c5f960b7a078766778eef14cef347f3b5cd3c5fc4a7797f031aad70" + "compiledCode": "5884010000323232323225333002323232323253330073370e900118041baa001132323375e6018601a004980129d8799fc25822018c641ac1624dfb73d7e9e4852882cc4b1df75eb615fe302d3df21196ecf93dfb88ff00300b001300937540022c6012601400460100026010004600c00260086ea8004526136565734aae7555cf2ba15745", + "hash": "dfa7cee7ce4b00790987cebda791bad5ffd34e12c58adc567094edad" + }, + { + "title": "foo.foo.else", + "compiledCode": "5884010000323232323225333002323232323253330073370e900118041baa001132323375e6018601a004980129d8799fc25822018c641ac1624dfb73d7e9e4852882cc4b1df75eb615fe302d3df21196ecf93dfb88ff00300b001300937540022c6012601400460100026010004600c00260086ea8004526136565734aae7555cf2ba15745", + "hash": "dfa7cee7ce4b00790987cebda791bad5ffd34e12c58adc567094edad" } ], "definitions": { diff --git a/examples/acceptance_tests/090/validators/foo.ak b/examples/acceptance_tests/090/validators/foo.ak index de1ec371..0f101202 100644 --- a/examples/acceptance_tests/090/validators/foo.ak +++ b/examples/acceptance_tests/090/validators/foo.ak @@ -1,8 +1,12 @@ const foo = 45898945895546556456546223123184821312385384845153123213185685815615232323484552 -validator { - fn spend(datum: Int, _redeemer: Data, _context: Data) { - datum == foo +validator foo { + spend(datum: Option, _redeemer: Data, o_ref: Data, _tx: Data) { + datum == Some(foo) + } + + else(_) { + fail } } diff --git a/examples/acceptance_tests/096/aiken.lock b/examples/acceptance_tests/096/aiken.lock index 875510d7..299bf850 100644 --- a/examples/acceptance_tests/096/aiken.lock +++ b/examples/acceptance_tests/096/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158436, nanos_since_epoch = 833716000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724776968, nanos_since_epoch = 78547000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/096/aiken.toml b/examples/acceptance_tests/096/aiken.toml index 05c1fb2e..a6262e58 100644 --- a/examples/acceptance_tests/096/aiken.toml +++ b/examples/acceptance_tests/096/aiken.toml @@ -10,5 +10,5 @@ platform = "github" [[dependencies]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" diff --git a/examples/acceptance_tests/096/plutus.json b/examples/acceptance_tests/096/plutus.json index b0c3be36..c216cf87 100644 --- a/examples/acceptance_tests/096/plutus.json +++ b/examples/acceptance_tests/096/plutus.json @@ -6,13 +6,13 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" }, "license": "Apache-2.0" }, "validators": [ { - "title": "foo.is_fourty_two", + "title": "foo.is_fourty_two.spend", "datum": { "title": "dat", "schema": { @@ -25,8 +25,13 @@ "$ref": "#/definitions/Data" } }, - "compiledCode": "581c01000032222533300453330043375e00400629445280a4c26cacae69", - "hash": "8be8ae44ae022691acf356eae743ba402b8b7918f1e54092367ae0b7" + "compiledCode": "586d01000032323232323225333002323232323253330073370e900118041baa0011323253330093375e66e9520003300c0044bd70180698070010a5114a0601800260126ea800458c028c02c008c024004c024008c01c004c010dd50008a4c26cacae6955ceaab9e5740ae855d101", + "hash": "aa09f972cd22cf3bcbadb40dbe865d16dd4a50ff84022ef76a885d63" + }, + { + "title": "foo.is_fourty_two.else", + "compiledCode": "586d01000032323232323225333002323232323253330073370e900118041baa0011323253330093375e66e9520003300c0044bd70180698070010a5114a0601800260126ea800458c028c02c008c024004c024008c01c004c010dd50008a4c26cacae6955ceaab9e5740ae855d101", + "hash": "aa09f972cd22cf3bcbadb40dbe865d16dd4a50ff84022ef76a885d63" } ], "definitions": { diff --git a/examples/acceptance_tests/096/validators/foo.ak b/examples/acceptance_tests/096/validators/foo.ak index 8813dc9f..57e46bd1 100644 --- a/examples/acceptance_tests/096/validators/foo.ak +++ b/examples/acceptance_tests/096/validators/foo.ak @@ -1,7 +1,11 @@ -use aiken/transaction.{ScriptContext} +use cardano/transaction.{Transaction} -validator { - fn is_fourty_two(dat, rdm, _ctx: ScriptContext) -> Bool { - rdm == dat && #"68656c6c6f20776f726c64" == #"68656c6c6f20776f726c64" +validator is_fourty_two { + spend(dat, rdm, _oref, _ctx: Transaction) { + Some(rdm) == dat && #"68656c6c6f20776f726c64" == #"68656c6c6f20776f726c64" + } + + else(_) { + fail } } diff --git a/examples/acceptance_tests/099/aiken.lock b/examples/acceptance_tests/099/aiken.lock index 58c9fa00..72c4abc2 100644 --- a/examples/acceptance_tests/099/aiken.lock +++ b/examples/acceptance_tests/099/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158436, nanos_since_epoch = 95704000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776974, nanos_since_epoch = 482154000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/101/aiken.lock b/examples/acceptance_tests/101/aiken.lock index da2cd68d..1915b827 100644 --- a/examples/acceptance_tests/101/aiken.lock +++ b/examples/acceptance_tests/101/aiken.lock @@ -24,5 +24,5 @@ requirements = [] source = "github" [etags] -"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1723158434, nanos_since_epoch = 581622000 }, "24d601fa19a2002318495bbb8562b9677563ca1b5c03126d6b093a65df076bef"] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158434, nanos_since_epoch = 474753000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1724776982, nanos_since_epoch = 317854000 }, "24d601fa19a2002318495bbb8562b9677563ca1b5c03126d6b093a65df076bef"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776982, nanos_since_epoch = 83201000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/102/aiken.lock b/examples/acceptance_tests/102/aiken.lock index 460ae0a3..b0f59358 100644 --- a/examples/acceptance_tests/102/aiken.lock +++ b/examples/acceptance_tests/102/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158431, nanos_since_epoch = 792706000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776954, nanos_since_epoch = 774618000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/104/aiken.lock b/examples/acceptance_tests/104/aiken.lock index 952e6b14..9b0ad657 100644 --- a/examples/acceptance_tests/104/aiken.lock +++ b/examples/acceptance_tests/104/aiken.lock @@ -24,5 +24,5 @@ requirements = [] source = "github" [etags] -"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1723158432, nanos_since_epoch = 675720000 }, "24d601fa19a2002318495bbb8562b9677563ca1b5c03126d6b093a65df076bef"] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723158432, nanos_since_epoch = 474723000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] +"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1724776955, nanos_since_epoch = 575782000 }, "24d601fa19a2002318495bbb8562b9677563ca1b5c03126d6b093a65df076bef"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1724776954, nanos_since_epoch = 782601000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/104/plutus.json b/examples/acceptance_tests/104/plutus.json index ddb8f0bd..021fd28f 100644 --- a/examples/acceptance_tests/104/plutus.json +++ b/examples/acceptance_tests/104/plutus.json @@ -6,15 +6,15 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+6e4a16d" + "version": "v1.0.31-alpha+4003343" }, "license": "Apache-2.0" }, "validators": [ { - "title": "tests.foo_3", + "title": "tests.foo_3.mint", "redeemer": { - "title": "_data", + "title": "_redeemer", "schema": { "$ref": "#/definitions/Data" } @@ -27,8 +27,21 @@ } } ], - "compiledCode": "582401000032323222253330043370e6eb4c018c014dd5001a400429309b2b2b9a5573cae841", - "hash": "047dafbc61fb4a550a28398bde3680c48ff2000cf1022efc883124cd" + "compiledCode": "58670100003232323232225333003323232323253330083370e900018049baa0011323370e6eb4c030c02cdd5004240046eb8c02cc028dd500089931bad300b300a375400e6014601600460120026012004600e002600a6ea8004526136565734aae7555cf2ba15745", + "hash": "8d14659c82f8f0a1281c561b563283c30c43546d4215c9acafa78edf" + }, + { + "title": "tests.foo_3.else", + "parameters": [ + { + "title": "th_arg", + "schema": { + "$ref": "#/definitions/tests~1Foo" + } + } + ], + "compiledCode": "58670100003232323232225333003323232323253330083370e900018049baa0011323370e6eb4c030c02cdd5004240046eb8c02cc028dd500089931bad300b300a375400e6014601600460120026012004600e002600a6ea8004526136565734aae7555cf2ba15745", + "hash": "8d14659c82f8f0a1281c561b563283c30c43546d4215c9acafa78edf" } ], "definitions": { diff --git a/examples/acceptance_tests/104/validators/tests.ak b/examples/acceptance_tests/104/validators/tests.ak index f8f3582e..3f93d380 100644 --- a/examples/acceptance_tests/104/validators/tests.ak +++ b/examples/acceptance_tests/104/validators/tests.ak @@ -1,6 +1,6 @@ use aiken/fuzz -type Foo { +pub type Foo { a0: Int, a1: Bool, } @@ -17,10 +17,14 @@ fn foo_2(Foo { a0, a1 } as foo) -> Int { } } -validator(Foo { a0, .. }: Foo) { - fn foo_3(_data, _redeemer) { +validator foo_3(Foo { a0, .. }: Foo) { + mint(_redeemer, _policy_, _tx) { a0 == 1 } + + else(_) { + fail + } } test example_1() { @@ -32,14 +36,15 @@ test example_2() { } test example_3() { - foo_3(Foo { a0: 1, a1: False }, "", "") + foo_3.mint(Foo { a0: 1, a1: False }, "", "", "") } test example_4() { - let foo_4 = fn(Foo { a1, .. }) { a1 } + let foo_4 = + fn(Foo { a1, .. }) { a1 } foo_4(Foo { a0: 1, a1: True }) } test example_5((a, b) via fuzz.both(fuzz.int(), fuzz.int())) { - a + b == b + a + a + b == b + a } diff --git a/examples/acceptance_tests/110/aiken.lock b/examples/acceptance_tests/110/aiken.lock new file mode 100644 index 00000000..6e350cda --- /dev/null +++ b/examples/acceptance_tests/110/aiken.lock @@ -0,0 +1,7 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +requirements = [] +packages = [] + +[etags] diff --git a/examples/acceptance_tests/110/aiken.toml b/examples/acceptance_tests/110/aiken.toml new file mode 100644 index 00000000..4cd28fba --- /dev/null +++ b/examples/acceptance_tests/110/aiken.toml @@ -0,0 +1,9 @@ +name = "aiken-lang/acceptance_test_110" +version = "0.0.0" +license = "Apache-2.0" +description = "Aiken contracts for project 'aiken-lang/110'" + +[repository] +user = "aiken-lang" +project = "110" +platform = "github" diff --git a/examples/acceptance_tests/110/lib/foo.ak b/examples/acceptance_tests/110/lib/foo.ak new file mode 100644 index 00000000..2608e4e7 --- /dev/null +++ b/examples/acceptance_tests/110/lib/foo.ak @@ -0,0 +1,39 @@ +type Foo { + Foo(Int, Never) + Bar +} + +test never_is_none() { + let none: Option = None + + trace @"Never": Never + trace @"None": none + + let data_never: Data = Never + let data_none: Data = none + + data_never == data_none +} + +test never_pattern_match() { + when Foo(14, Never) is { + Foo(x, Never) -> x == 14 + Bar -> False + } +} + +test never_assignment() { + let Never = Never + True +} + +test never_wrong_cast() fail { + let data: Data = Some(42) + expect _: Never = data +} + +test never_ok_cast() { + let none: Option = None + let data: Data = none + expect _: Never = data +} diff --git a/examples/acceptance_tests/script_context/v2/.gitignore b/examples/acceptance_tests/script_context/v2/.gitignore deleted file mode 100644 index 857abe49..00000000 --- a/examples/acceptance_tests/script_context/v2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.cbor -*.log diff --git a/examples/acceptance_tests/script_context/v2/README.md b/examples/acceptance_tests/script_context/v2/README.md deleted file mode 100644 index 2b04873b..00000000 --- a/examples/acceptance_tests/script_context/v2/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# V2 Script Context Tests - -This project contains a few handcrafted Plutus V2 validators and transactions -whose sole purpose is to test the interpretation of the `ScriptContext` from -within an Aiken's validators. - -So validators are meant to work hand-in-hand with an associated context. -Because we can't have fully static context (since they contain the validator -and its hash), we define _templates_. - -Everything is a bit clunky, but steps have been captured in a `test.sh` script -for convenience. - -## How to use - -``` -./test.sh [VALIDATOR_TITLE] -``` - -## Test Coverage - -- [ ] Purpose - - [x] spend - - [x] mint - - [x] withdraw - - [ ] publish - -- [ ] Transaction - - [ ] inputs - - [ ] reference inputs - - [ ] outputs - - [ ] address - - [x] verification key - - [x] script - - [ ] pointer - - [x] value - - [x] datum - - [x] none - - [x] hash - - [x] inline - - [x] script - - [x] none - - [x] reference - - [x] values - - [x] pure ada - - [x] native assets - - [x] fee - - [x] mint - - [ ] certificates - - [x] withdrawals - - [x] verification key - - [x] script - - [ ] validity range - - [x] extra signatories - - [x] redeemers - - [x] datums diff --git a/examples/acceptance_tests/script_context/v2/aiken.lock b/examples/acceptance_tests/script_context/v2/aiken.lock deleted file mode 100644 index 92b95b36..00000000 --- a/examples/acceptance_tests/script_context/v2/aiken.lock +++ /dev/null @@ -1,16 +0,0 @@ -# This file was generated by Aiken -# You typically do not need to edit this file - -[[requirements]] -name = "aiken-lang/stdlib" -version = "main" -source = "github" - -[[packages]] -name = "aiken-lang/stdlib" -version = "main" -requirements = [] -source = "github" - -[etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1723583483, nanos_since_epoch = 18378000 }, "5e58899446492a704d0927a43299139856bef746e697b55895ba34206fa28452"] diff --git a/examples/acceptance_tests/script_context/v2/aiken.toml b/examples/acceptance_tests/script_context/v2/aiken.toml deleted file mode 100644 index 3d679522..00000000 --- a/examples/acceptance_tests/script_context/v2/aiken.toml +++ /dev/null @@ -1,10 +0,0 @@ -name = "script_context/v2" -version = "0.0.0" -plutus = "v2" -license = "Apache-2.0" -description = "Aiken contracts for project 'script_context/v2'" - -[[dependencies]] -name = "aiken-lang/stdlib" -version = "main" -source = "github" diff --git a/examples/acceptance_tests/script_context/v2/ctx/basic/inputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/basic/inputs.cbor.template deleted file mode 100644 index e7f75b49..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/basic/inputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81825820000000000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/acceptance_tests/script_context/v2/ctx/basic/outputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/basic/outputs.cbor.template deleted file mode 100644 index 71a0de30..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/basic/outputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81A300581D70{{ VALIDATOR_HASH }}011A3B9ACA00028201D81843D87980 diff --git a/examples/acceptance_tests/script_context/v2/ctx/basic/tx.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/basic/tx.cbor.template deleted file mode 100644 index 1b121c91..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/basic/tx.cbor.template +++ /dev/null @@ -1 +0,0 @@ -84A70081825820000000000000000000000000000000000000000000000000000000000000000000018182581D60111111111111111111111111111111111111111111111111111111111A3B9ACA0002182A0B5820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D818258200000000000000000000000000000000000000000000000000000000000000000001082581D60000000000000000000000000000000000000000000000000000000001A3B9ACA001101A20581840000D87980821A000F42401A05F5E1000681{{ VALIDATOR }}F5F6 diff --git a/examples/acceptance_tests/script_context/v2/ctx/basic/tx.diag.template b/examples/acceptance_tests/script_context/v2/ctx/basic/tx.diag.template deleted file mode 100644 index 8f5b82e9..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/basic/tx.diag.template +++ /dev/null @@ -1,34 +0,0 @@ -[ - { 0: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 1: - [ [h'6011111111111111111111111111111111111111111111111111111111', 1000000000] - ] - - , 2: 42 - - , 11: h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' - - , 13: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 16: - [ h'6000000000000000000000000000000000000000000000000000000000', 1000000000 - ] - - , 17: 1 - }, - - { 5: [[0, 0, 121([]), [1000000, 100000000]]] - - , 6: [h'{{ VALIDATOR }}'] - - }, - - true, - - null -] diff --git a/examples/acceptance_tests/script_context/v2/ctx/deploy/inputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/deploy/inputs.cbor.template deleted file mode 100644 index e7f75b49..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/deploy/inputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81825820000000000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/acceptance_tests/script_context/v2/ctx/deploy/outputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/deploy/outputs.cbor.template deleted file mode 100644 index 7c6083d6..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/deploy/outputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81A300581D70{{ VALIDATOR_HASH }}011A000F4240028201D81843D87980 diff --git a/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.cbor.template deleted file mode 100644 index 61d86c63..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.cbor.template +++ /dev/null @@ -1 +0,0 @@ -84A300818258200000000000000000000000000000000000000000000000000000000000000000000182A400581D6000000000000000000000000000000000000000000000000000000000011A000F42400282005820FCAA61FB85676101D9E3398A484674E71C45C3FD41B492682F3B0054F4CF327303D81858418202583D583B0100003232323232323222253330064A22930B180080091129998030010A4C26600A6002600E0046660060066010004002AE695CDAAB9F5742AE89A3005839100000000000000000000000000000000000000000000000000000000066666666666666666666666666666666666666666666666666666666011A000F4240028201D81846D8799F182AFF0201A30482D8799FFFD8799F182AFF0581840000D87980821A000F42401A05F5E1000681{{ VALIDATOR }}F5F6 diff --git a/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.diag.template b/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.diag.template deleted file mode 100644 index bf0d1fc0..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/deploy/tx.diag.template +++ /dev/null @@ -1,33 +0,0 @@ -[ - { 0: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 1: - [ { 0: h'6000000000000000000000000000000000000000000000000000000000' - , 1: 1000000 - , 2: [ 0, h'fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273' ] - , 3: 24(h'8202583D583B0100003232323232323222253330064A22930B180080091129998030010A4C26600A6002600E0046660060066010004002AE695CDAAB9F5742AE89') - } - - , { 0: h'100000000000000000000000000000000000000000000000000000000066666666666666666666666666666666666666666666666666666666' - , 1: 1000000 - , 2: [ 1, 24(h'D8799F182AFF') ] - } - ] - - , 2: 1 - }, - - { 4: [121([]), 121([42])] - - , 5: [[0, 0, 121([]), [1000000, 100000000]]] - - , 6: [h'{{ VALIDATOR }}'] - - }, - - true, - - null -] diff --git a/examples/acceptance_tests/script_context/v2/ctx/mint/inputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/mint/inputs.cbor.template deleted file mode 100644 index e7f75b49..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/mint/inputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81825820000000000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/acceptance_tests/script_context/v2/ctx/mint/outputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/mint/outputs.cbor.template deleted file mode 100644 index 155c6800..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/mint/outputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81A200581D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF011A000F4240 diff --git a/examples/acceptance_tests/script_context/v2/ctx/mint/tx.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/mint/tx.cbor.template deleted file mode 100644 index 522ca566..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/mint/tx.cbor.template +++ /dev/null @@ -1 +0,0 @@ -84A400818258200000000000000000000000000000000000000000000000000000000000000000000180020109A1581C{{ VALIDATOR_HASH }}A143666F6F190539A20581840100D87980821A000F42401A05F5E1000681{{ VALIDATOR }}F5F6 diff --git a/examples/acceptance_tests/script_context/v2/ctx/mint/tx.diag.template b/examples/acceptance_tests/script_context/v2/ctx/mint/tx.diag.template deleted file mode 100644 index 5894a3a6..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/mint/tx.diag.template +++ /dev/null @@ -1,25 +0,0 @@ -[ - { 0: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 1: - [] - - , 2: 1 - - , 9: - { h'{{ VALIDATOR_HASH }}': { h'666f6f': 1337 } - } - }, - - { 5: [[1, 0, 121([]), [1000000, 100000000]]] - - , 6: [h'{{ VALIDATOR }}'] - - }, - - true, - - null -] diff --git a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/inputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/withdrawals/inputs.cbor.template deleted file mode 100644 index e7f75b49..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/inputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81825820000000000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/outputs.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/withdrawals/outputs.cbor.template deleted file mode 100644 index 71a0de30..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/outputs.cbor.template +++ /dev/null @@ -1 +0,0 @@ -81A300581D70{{ VALIDATOR_HASH }}011A3B9ACA00028201D81843D87980 diff --git a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.cbor.template b/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.cbor.template deleted file mode 100644 index dca960e7..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.cbor.template +++ /dev/null @@ -1 +0,0 @@ -84A80081825820000000000000000000000000000000000000000000000000000000000000000000018182581D60111111111111111111111111111111111111111111111111111111111A3B9ACA0002182A05A2581DE022222222222222222222222222222222222222222222222222222222182A581DF0AFDDC16C18E7D8DE379FB9AAD39B3D1B5AFD27603E5EBAC818432A720E0B5820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D818258200000000000000000000000000000000000000000000000000000000000000000001082581D60000000000000000000000000000000000000000000000000000000001A3B9ACA001101A20582840000D87980821A000F42401A05F5E100840300D87980821A000F42401A05F5E1000682{{ VALIDATOR }}583D583B010000323232323232322253330054A22930B180080091129998030010A4C26600A6002600E0046660060066010004002AE695CDAAB9F5742AE881F5F6 diff --git a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.diag.template b/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.diag.template deleted file mode 100644 index 3086656d..00000000 --- a/examples/acceptance_tests/script_context/v2/ctx/withdrawals/tx.diag.template +++ /dev/null @@ -1,42 +0,0 @@ -[ - { 0: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 1: - [ [h'6011111111111111111111111111111111111111111111111111111111', 1000000000] - ] - - , 2: 42 - - , 5: - { h'e022222222222222222222222222222222222222222222222222222222': 42 - , h'f0afddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72': 14 - } - - , 11: h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' - - , 13: - [ [h'0000000000000000000000000000000000000000000000000000000000000000', 0] - ] - - , 16: - [ h'6000000000000000000000000000000000000000000000000000000000', 1000000000 - ] - - , 17: 1 - }, - - { 5: - [ [0, 0, 121([]), [1000000, 100000000]] - , [3, 0, 121([]), [1000000, 100000000]] - ] - - , 6: [ {{ VALIDATOR }}, h'583b010000323232323232322253330054a22930b180080091129998030010a4c26600a6002600e0046660060066010004002ae695cdaab9f5742ae881' ] - - }, - - true, - - null -] diff --git a/examples/acceptance_tests/script_context/v2/plutus.json b/examples/acceptance_tests/script_context/v2/plutus.json deleted file mode 100644 index 6dae6d6e..00000000 --- a/examples/acceptance_tests/script_context/v2/plutus.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "preamble": { - "title": "script_context/v2", - "description": "Aiken contracts for project 'script_context/v2'", - "version": "0.0.0", - "plutusVersion": "v2", - "compiler": { - "name": "Aiken", - "version": "v1.0.31-alpha+fe5c565" - }, - "license": "Apache-2.0" - }, - "validators": [ - { - "title": "basic.spend", - "datum": { - "title": "_datum", - "schema": { - "$ref": "#/definitions/Void" - } - }, - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/Void" - } - }, - "compiledCode": "5903fb01000032323232323232323232322533333300c00115332330053001300737540042a66601260106ea8008494cccccc03800454ccc018c008c020dd50008a99980518049baa0011253330073253330083330083375e601c601e601e601e601e601e601e601e601e601e601e601e60166ea8c004c02cdd500126126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a09444c94ccc024c94ccc028cdc3a400460186ea80044c94ccc02ccdd7980218071baa0014c0126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013007375a6006601c6ea8004528180818069baa001153300b4911c73637269707420707572706f73652069736e277420275370656e642700163001300c375400626464a6660166464a6660220022a6601c92011c756e6578706563746564206e756d626572206f66206f7574707574730016153330113014001132533300e3375e600c60226ea8004dd318022410151ad720e2a66601c66ebcc01cc044dd5180398089baa0014c0122d8799f581c11111111111111111111111111111111111111111111111111111111ff001533300e533300e300a30103754600c60226ea8c01cc044dd50008a5014a22a66601c66ebcc00cc044dd5000a60103d879800013375e600a60226ea800530103d87a800014a029405280a503013001153300e4911c756e6578706563746564206e756d626572206f66206f757470757473001637586002601e6ea8c014c03cdd50031180918099809800899baf3002300e37546008601c6ea8014dd31800a40a8294094ccc02cc01c00452f5bded8c0264646600200297adef6c6022533301200113301333760981014000374c00697adef6c60132323232533301233720910100002133017337609801014000374c00e00a2a66602466e3d22100002133017337609801014000374c00e00626602e66ec0dd48011ba600133006006003375660280066eb8c048008c058008c050004c8cc0040052f5bded8c044a66602200226602466ec13001014000375000697adef6c60132323232533301133720910100002133016337609801014000375000e00a2a66602266e3d22100002133016337609801014000375000e00626602c66ec0dd48011ba800133006006003375a60260066eb8c044008c054008c04c0048c040c044c044c0440045281180798080008a502300e001149854cc0212411856616c696461746f722072657475726e65642066616c73650013656004004004004004004004370e90000018018018018018a99801a4810f5f72656465656d65723a20566f6964001615330024910c5f646174756d3a20566f696400165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "1c6c13a9a56cbcb9ed18c312c9e9e9996b0545b7230b7cf81cbe012d" - }, - { - "title": "deploy.spend", - "datum": { - "title": "datum", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "compiledCode": "59039801000032323232323232323232222533300553330053375e00698103d8798000132533300633232232533300a3370e900018061baa00113253333330130011533300b3370e900018069baa001132533301000100b132533333301500100c00c00c132533301230150031533300e3375e980106d8799f182aff0000413370e600e00c90020a5000d375a0020186024002601c6ea8004028028028028028c040c034dd50008a99805a495865787065637420536f6d6528646174756d29203d0a20202020646963742e67657428646174756d732c20626c616b6532625f323536286275696c74696e2e73657269616c6973655f64617461286d795f646174756d292929001632323300100100322533301000114c0103d87a800013232323253330103372200e0042a66602066e3c01c0084cdd2a40006602a00297ae014c0103d87a80001330060060033012003375c6020004602800460240026e50dd9a6106d8799f182aff00300100122533300c0011480004cdc02400466004004601e0026eacc030c034c034c034c034c034c034c034c034c034c034c024dd5180098049baa00213232533300c00115330094901316578706563746564207472616e73616374696f6e20746f206861766520286174206c65617374292032206f7574707574730016132533300d001153300a4901316578706563746564207472616e73616374696f6e20746f206861766520286174206c65617374292032206f7574707574730016132533300a32533300b3375e600a601c6ea800530126d87a9f5820fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273ff0013375e6022602460246024601c6ea800530122d8799f581ce37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4ff0014a060200062a66601466ebcc040c044c034dd5180298069baa0014c012ad8799fd8799fd8799f581c66666666666666666666666666666666666666666666666666666666ffffff001533300a3370e900218061baa3004300d3754002294454cc02d24115657870656374656420696e6c696e6520646174756d001614a02940c03c004c03c004dd6180098051baa3002300a37540064601a601c601c00229408c0300045280a4c2a6600c92011856616c696461746f722072657475726e65642066616c73650013656153300249011d65787065637420646174756d3a204d79446174756d203d20646174756d00165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "66a5272eb58aed0097083185588ef1e8b3888a3bc2e03c061f09c898" - }, - { - "title": "mint.mint", - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "compiledCode": "590496010000323232323232323232225333004323232323253323300a3232533301000100b13253330113014002132533300e300530103754002266e3c008dd7180a18089baa001153300f49124657870656374204d696e7428706f6c6963795f696429203d206374782e707572706f736500163008301037540140186eb8c048004cc004004cc010c00cdd5980298071baa3007300e375401091010022533301000114bd70099808980718090009980100118098008a999191980619912999807180298081baa002132533300f3005301137540022a6602092010f746f6b656e206e6f7420666f756e64001613370e6eb4c054c048dd5000a41e428646600200264a666020600c60246ea800452f5bded8c026eacc058c04cdd500099191980080098049bab300b3014375400844a66602c002298103d87a800013232323253330163372200e0042a66602c66e3c01c0084c02ccc06cdd3000a5eb80530103d87a8000133006006003375660300066eb8c058008c068008c060004dd7180a98091baa00322533301400114c103d87a800013232323253330143372291103666f6f00002153330143371e910103666f6f000021300933019375000297ae014c0103d87a8000133006006003375a602c0066eb8c050008c060008c05800454cc03d24120657870656374204d696e7428706f6c6963795f696429203d20707572706f736500163007300f37540126010601e6ea80244c8c8c8c94ccc040c01cc048dd50008a99980819baf00e30133233760602e002602e60300026eb0c058c04cdd50008980318011bab300430133754601860266ea80345280a99808a496b65787065637420536f6d652850616972285f2c2072656465656d65722929203d0a202020206c6973742e66696e64286374782e7472616e73616374696f6e2e72656465656d6572732c20666e286b7629207b206b762e317374203d3d206374782e707572706f7365207d29001632330010013756600860266ea8c030c04cdd500691299980a8008a6103d87a80001323253330133375e602a004601c602c6ea80404c020cc060dd39980c180a8011980c180b00125eb812f5c02660080080026032004602e002600200244a66602600229000099b8048008cc008008c0580048c04cc050c050c050c050c050c050c050c050c050004dd2a40006e1d200214a06e1d200014a046600400291010022323300100100322533300f00114bd6f7b630099191919299980799b910070021533300f3371e00e0042006200a26602866ec0dd48011ba600133006006003375660220066eb8c03c008c04c008c0440048c034c038c038c038c0380048c030c0340048c02c00452615330054911856616c696461746f722072657475726e65642066616c736500136561533002490189657870656374205b6d795f706f6c6963795f69645d203d0a202020206374782e7472616e73616374696f6e2e6d696e740a2020202020207c3e2076616c75652e66726f6d5f6d696e7465645f76616c75650a2020202020207c3e2076616c75652e776974686f75745f6c6f76656c6163650a2020202020207c3e2076616c75652e706f6c696369657300165734ae7155ceaab9e5573eae815d0aba21", - "hash": "8372367de2b0391b1bec0489dc72cb65de1a791f4e9712b9149d6392" - }, - { - "title": "withdrawals.spend", - "datum": { - "title": "_datum", - "schema": { - "$ref": "#/definitions/Void" - } - }, - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/Void" - } - }, - "compiledCode": "5902de01000032323232323232323232322533333300c001153330043370e900018031baa001153330083007375400224a66666601a0022a66600a66e1d2000300737540022a66601260106ea8004494ccc018c8c8c94ccc024c94ccc028cdc3a400460186ea800454cc02d2411c616c6963652773207769746864726177616c206e6f7420666f756e64001613370e6eb4c034c8cdd81808800980898090009bac3010300d3754002902a198009bab3002300c3754600660186ea80108cdd79806000a6126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff001533300932533300a3370e900118061baa001153300b49011a626f622773207769746864726177616c206e6f7420666f756e64001613370e6eb4c034c8cdd81808800980898090009bac3010300d3754002900e198009bab3002300c3754600660186ea80108cdd79806000a6126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff0013375e6e9cc8cc004004dd5980198069baa3004300d375400a44a66601e002297ae0133010300d3011001330020023012001374e6601c98126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff003300e4c126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff004bd700a5014a044646600200200644a666020002298103d87a800013232533300e300500213374a9000198099ba73301330100023301330110024bd7025eb804cc010010004c050008c0480048c038c03cc03cc03cc03cc03cc03c0048c03400452615330074911856616c696461746f722072657475726e65642066616c73650013656003003003003003003003003003003003003153300349010f5f72656465656d65723a20566f6964001615330024910c5f646174756d3a20566f696400165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "4f44caf93e36ee884b6d03b1e1c93bf8cda516fd39f7113823508571" - } - ], - "definitions": { - "Data": { - "title": "Data", - "description": "Any Plutus data." - }, - "Void": { - "title": "Unit", - "description": "The nullary constructor.", - "anyOf": [ - { - "dataType": "constructor", - "index": 0, - "fields": [] - } - ] - } - } -} \ No newline at end of file diff --git a/examples/acceptance_tests/script_context/v2/test.sh b/examples/acceptance_tests/script_context/v2/test.sh deleted file mode 100755 index 1213337b..00000000 --- a/examples/acceptance_tests/script_context/v2/test.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -TITLE=$1 -if [ -z $TITLE ]; then - echo -e "\033[31mMissing argument: \033[1mVALIDATOR_TITLE\033[0m" - echo "" - echo -e "\033[1mUsage: \033[0m" - echo " test.sh {ACCEPTANCE_TEST}" - echo "" - echo -e "\033[1mExample: \033[0m" - echo " test.sh basic" - exit 1 -fi - -AIKEN=${2:-"cargo run -r --quiet --"} - -if ! command -v jq &> /dev/null -then - echo "\033[1mjq\033[0m missing from system but required." - exit 1 -fi - -if ! command -v cbor-diag &> /dev/null -then - echo "\033[1mcbor-diag\033[0m missing from system but required." - exit 1 -fi - -$AIKEN build --filter-traces all -t verbose -if [ $? -ne 0 ]; then - exit $? -fi - -BLUEPRINT=$(jq ".validators[] | select(.title|contains(\"$TITLE\"))" plutus.json) - -VALIDATOR_HASH=$(echo $BLUEPRINT | jq .hash | sed s/\"//g) -VALIDATOR=$(echo $BLUEPRINT | jq .compiledCode | sed s/\"//g) -VALIDATOR=$(cbor-diag --to hex --from diag <<< "h'$VALIDATOR'") - -cp ctx/$TITLE/inputs.cbor.template ctx/$TITLE/inputs.cbor -sed "s/{{ VALIDATOR_HASH }}/$VALIDATOR_HASH/" ctx/$TITLE/outputs.cbor.template > ctx/$TITLE/outputs.cbor -sed "s/{{ VALIDATOR }}/$VALIDATOR/" ctx/$TITLE/tx.cbor.template | sed "s/{{ VALIDATOR_HASH }}/$VALIDATOR_HASH/" > ctx/$TITLE/tx.cbor - -$AIKEN tx simulate \ - ctx/$TITLE/tx.cbor \ - ctx/$TITLE/inputs.cbor \ - ctx/$TITLE/outputs.cbor diff --git a/examples/acceptance_tests/script_context/v2/validators/basic.ak b/examples/acceptance_tests/script_context/v2/validators/basic.ak deleted file mode 100644 index 8f33ec40..00000000 --- a/examples/acceptance_tests/script_context/v2/validators/basic.ak +++ /dev/null @@ -1,51 +0,0 @@ -use aiken/option -use aiken/transaction.{NoDatum, - ScriptContext, Spend, Transaction, TransactionId} -use aiken/transaction/credential.{VerificationKeyCredential} -use aiken/transaction/value - -validator { - fn spend(_datum: Void, _redeemer: Void, ctx: ScriptContext) { - and { - assert_id(ctx.transaction), - assert_purpose(ctx.purpose), - assert_outputs(ctx.transaction), - assert_fee(ctx.transaction), - } - } -} - -fn assert_id(transaction: Transaction) { - transaction.id != TransactionId( - #"0000000000000000000000000000000000000000000000000000000000000000", - ) -} - -fn assert_purpose(purpose) { - when purpose is { - Spend(ref) -> - ref.transaction_id == TransactionId( - #"0000000000000000000000000000000000000000000000000000000000000000", - ) && ref.output_index == 0 - _ -> fail @"script purpose isn't 'Spend'" - } -} - -fn assert_fee(transaction: Transaction) { - transaction.fee == value.from_lovelace(42) -} - -fn assert_outputs(transaction: Transaction) { - when transaction.outputs is { - [output] -> and { - output.value == value.from_lovelace(1000000000), - output.address.payment_credential == VerificationKeyCredential( - #"11111111111111111111111111111111111111111111111111111111", - ), - option.is_none(output.address.stake_credential), - output.datum == NoDatum, - output.reference_script == None, - } - _ -> fail @"unexpected number of outputs" - } -} diff --git a/examples/acceptance_tests/script_context/v2/validators/deploy.ak b/examples/acceptance_tests/script_context/v2/validators/deploy.ak deleted file mode 100644 index 7003d412..00000000 --- a/examples/acceptance_tests/script_context/v2/validators/deploy.ak +++ /dev/null @@ -1,70 +0,0 @@ -use aiken/builtin -use aiken/dict.{Dict} -use aiken/hash.{blake2b_256} -use aiken/transaction.{DatumHash, InlineDatum, Output, ScriptContext} -use aiken/transaction/credential.{Inline, VerificationKeyCredential} - -validator { - fn spend(datum: Data, _redeemer: Data, ctx: ScriptContext) { - and { - assert_datum(datum), - assert_datums(ctx.transaction.datums), - assert_outputs(ctx.transaction.outputs), - } - } -} - -fn assert_datum(datum) { - let my_datum: Data = Void - datum == my_datum -} - -type MyDatum { - MyDatum(Int) -} - -fn assert_datums(datums: Dict) { - let my_datum = MyDatum(42) - - expect Some(datum) = - dict.get(datums, blake2b_256(builtin.serialise_data(my_datum))) - - expect datum: MyDatum = datum - - my_datum == datum && dict.size(datums) == 2 -} - -fn assert_outputs(outputs) { - when outputs is { - [output_1, output_2, ..] -> - assert_first_output(output_1) && assert_second_output(output_2) - _ -> fail @"expected transaction to have (at least) 2 outputs" - } -} - -fn assert_first_output(output: Output) { - and { - output.datum == DatumHash( - #"fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273", - ), - output.reference_script == Some( - #"e37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4", - ), - } -} - -fn assert_second_output(output: Output) { - and { - output.address.stake_credential == Some( - Inline( - VerificationKeyCredential( - #"66666666666666666666666666666666666666666666666666666666", - ), - ), - ), - when output.datum is { - InlineDatum(_) -> True - _ -> fail @"expected inline datum" - }, - } -} diff --git a/examples/acceptance_tests/script_context/v2/validators/mint.ak b/examples/acceptance_tests/script_context/v2/validators/mint.ak deleted file mode 100644 index c2c28245..00000000 --- a/examples/acceptance_tests/script_context/v2/validators/mint.ak +++ /dev/null @@ -1,43 +0,0 @@ -use aiken/dict -use aiken/list -use aiken/transaction.{Mint, ScriptContext, Transaction} -use aiken/transaction/value - -validator { - fn mint(redeemer: Data, ctx: ScriptContext) { - and { - assert_purpose(ctx), - assert_mint(ctx.purpose, ctx.transaction), - assert_redeemers(ctx, redeemer), - } - } -} - -fn assert_purpose(ctx: ScriptContext) { - expect [my_policy_id] = - ctx.transaction.mint - |> value.from_minted_value - |> value.without_lovelace - |> value.policies - - expect Mint(policy_id) = ctx.purpose - - my_policy_id == policy_id -} - -fn assert_mint(purpose, transaction: Transaction) { - expect Mint(policy_id) = purpose - let tokens = - value.tokens(transaction.mint |> value.from_minted_value, policy_id) - - when dict.get(tokens, #"666f6f") is { - None -> fail @"token not found" - Some(quantity) -> quantity == 1337 - } -} - -fn assert_redeemers(ctx: ScriptContext, my_redeemer) { - expect Some(Pair(_, redeemer)) = - list.find(ctx.transaction.redeemers, fn(kv) { kv.1st == ctx.purpose }) - my_redeemer == redeemer && list.length(ctx.transaction.redeemers) == 1 -} diff --git a/examples/acceptance_tests/script_context/v2/validators/withdrawals.ak b/examples/acceptance_tests/script_context/v2/validators/withdrawals.ak deleted file mode 100644 index a307f114..00000000 --- a/examples/acceptance_tests/script_context/v2/validators/withdrawals.ak +++ /dev/null @@ -1,37 +0,0 @@ -use aiken/list -use aiken/transaction.{ScriptContext} -use aiken/transaction/credential.{ - Inline, ScriptCredential, VerificationKeyCredential, -} - -validator { - fn spend(_datum: Void, _redeemer: Void, ctx: ScriptContext) { - let alice = - Inline( - VerificationKeyCredential( - #"22222222222222222222222222222222222222222222222222222222", - ), - ) - - let bob = - Inline( - ScriptCredential( - #"afddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72", - ), - ) - - and { - when - list.find(ctx.transaction.withdrawals, fn(kv) { kv.1st == alice }) - is { - None -> fail @"alice's withdrawal not found" - Some(value) -> value.2nd == 42 - }, - when list.find(ctx.transaction.withdrawals, fn(kv) { kv.1st == bob }) is { - None -> fail @"bob's withdrawal not found" - Some(value) -> value.2nd == 14 - }, - list.map(ctx.transaction.withdrawals, fn(kv) { kv.1st }) == [bob, alice], - } - } -} diff --git a/examples/acceptance_tests/script_context/v3/aiken.lock b/examples/acceptance_tests/script_context/v3/aiken.lock index c90f4933..0be3fb39 100644 --- a/examples/acceptance_tests/script_context/v3/aiken.lock +++ b/examples/acceptance_tests/script_context/v3/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1723583491, nanos_since_epoch = 208977000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724760716, nanos_since_epoch = 700202000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/acceptance_tests/script_context/v3/ctx/certificates/tx.template b/examples/acceptance_tests/script_context/v3/ctx/certificates/tx.template index 8e96ec3d..a261e479 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/certificates/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/certificates/tx.template @@ -93,7 +93,7 @@ ] , [ 2 , [ 1 - , h'{{ certificates.script.hash }}' + , h'{{ certificates.purposes.publish.hash }}' ] , h'11111111111111111111111111111111111111111111111111111111' ] @@ -109,7 +109,7 @@ { 5: [[2, 20, 121([]), [1000000, 100000000]]] - , 7: [h'{{ certificates.script.cbor }}'] + , 7: [h'{{ certificates.purposes.publish.cbor }}'] }, true, diff --git a/examples/acceptance_tests/script_context/v3/ctx/mint/tx.template b/examples/acceptance_tests/script_context/v3/ctx/mint/tx.template index 1e54fcc7..729e284c 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/mint/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/mint/tx.template @@ -11,15 +11,15 @@ , { 0: h'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' , 1: [ 1000000 - , { h'{{ mint.mint_1.hash }}': { h'74756e61': 100000000000000 } - , h'{{ mint.mint_2.hash }}': { h'61696b656e': 42 } + , { h'{{ mint.test_1.mint.hash }}': { h'74756e61': 100000000000000 } + , h'{{ mint.test_2.mint.hash }}': { h'61696b656e': 42 } } ] } , { 0: h'100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' , 1: [ 1000000 - , { h'{{ mint.mint_2.hash }}': { h'63617264616e6f': 1 } + , { h'{{ mint.test_2.mint.hash }}': { h'63617264616e6f': 1 } } ] , 3: 24(h'82034463666F6F') @@ -29,10 +29,10 @@ , 2: 42 , 9: - { h'{{ mint.mint_1.hash }}': + { h'{{ mint.test_1.mint.hash }}': { h'74756e61': 100000000000000 } - , h'{{ mint.mint_2.hash }}': + , h'{{ mint.test_2.mint.hash }}': { h'63617264616e6f': 1 , h'61696b656e': -14 } @@ -65,8 +65,8 @@ ] , 7: - [ h'{{ mint.mint_1.cbor }}' - , h'{{ mint.mint_2.cbor }}' + [ h'{{ mint.test_1.mint.cbor }}' + , h'{{ mint.test_2.mint.cbor }}' ] }, diff --git a/examples/acceptance_tests/script_context/v3/ctx/proposing_all/tx.template b/examples/acceptance_tests/script_context/v3/ctx/proposing_all/tx.template index afb4c438..eeddbaed 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/proposing_all/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/proposing_all/tx.template @@ -41,7 +41,7 @@ , h'F000000000000000000000000000000000000000000000000000000000' , [ 2 , { h'E022222222222222222222222222222222222222222222222222222222': 1000000 } - , h'{{ proposing_all.guardrails.hash }}' + , h'{{ proposing_all.guardrails.propose.hash }}' ] , [ "https://aiken-lang.org" , h'0000000000000000000000000000000000000000000000000000000000000000' @@ -112,7 +112,7 @@ { 5: [[5, 3, 121([]), [1000000, 100000000]]] - , 7: [h'{{ proposing_all.guardrails.cbor }}'] + , 7: [h'{{ proposing_all.guardrails.propose.cbor }}'] }, true, diff --git a/examples/acceptance_tests/script_context/v3/ctx/proposing_pparams/tx.template b/examples/acceptance_tests/script_context/v3/ctx/proposing_pparams/tx.template index 82d5fda0..79f8c228 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/proposing_pparams/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/proposing_pparams/tx.template @@ -61,7 +61,7 @@ , 32: 20 , 33: 30([15, 1]) } - , h'{{ proposing_pparams.guardrails.hash }}' + , h'{{ proposing_pparams.guardrails.propose.hash }}' ] , [ "https://aiken-lang.org" , h'0000000000000000000000000000000000000000000000000000000000000000' @@ -73,7 +73,7 @@ { 5: [[5, 0, 121([]), [1000000, 100000000]]] - , 7: [h'{{ proposing_pparams.guardrails.cbor }}'] + , 7: [h'{{ proposing_pparams.guardrails.propose.cbor }}'] }, true, diff --git a/examples/acceptance_tests/script_context/v3/ctx/simple_spend/resolved_inputs.template b/examples/acceptance_tests/script_context/v3/ctx/simple_spend/resolved_inputs.template index fc52b0ab..4a7802f1 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/simple_spend/resolved_inputs.template +++ b/examples/acceptance_tests/script_context/v3/ctx/simple_spend/resolved_inputs.template @@ -1,5 +1,5 @@ [ - { 0: h'70{{ simple_spend.spend.hash }}' + { 0: h'70{{ simple_spend.simple_spend.spend.hash }}' , 1: 1000000000 , 2: [1, 24(h'd87980')] } diff --git a/examples/acceptance_tests/script_context/v3/ctx/simple_spend/tx.template b/examples/acceptance_tests/script_context/v3/ctx/simple_spend/tx.template index 1796bb21..608c07c3 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/simple_spend/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/simple_spend/tx.template @@ -23,7 +23,7 @@ { 5: [[0, 0, 121([]), [1000000, 100000000]]] - , 7: [h'{{ simple_spend.spend.cbor }}'] + , 7: [h'{{ simple_spend.simple_spend.spend.cbor }}'] }, diff --git a/examples/acceptance_tests/script_context/v3/ctx/voting/tx.template b/examples/acceptance_tests/script_context/v3/ctx/voting/tx.template index 8fef1ee7..41a3e85a 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/voting/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/voting/tx.template @@ -25,7 +25,7 @@ , [ h'7777777777777777777777777777777777777777777777777777777777777777', 2 ]: [ 2, null ] } - , [ 3, h'{{ voting.script.hash }}' ]: + , [ 3, h'{{ voting.purposes.vote.hash }}' ]: { [ h'9999999999999999999999999999999999999999999999999999999999999999', 3 ]: [ 0, null ] } @@ -33,7 +33,7 @@ { [ h'9999999999999999999999999999999999999999999999999999999999999999', 4 ]: [ 1, null ] } - , [ 1, h'{{ voting.script.hash }}' ]: + , [ 1, h'{{ voting.purposes.vote.hash }}' ]: { [ h'9999999999999999999999999999999999999999999999999999999999999999', 1 ]: [ 1, null ] } } @@ -43,7 +43,7 @@ , [4, 0, 121([42]), [1000000, 100000000]] ] - , 7: [h'{{ voting.script.cbor }}'] + , 7: [h'{{ voting.purposes.vote.cbor }}'] }, true, diff --git a/examples/acceptance_tests/script_context/v3/ctx/withdraw/resolved_inputs.template b/examples/acceptance_tests/script_context/v3/ctx/withdraw/resolved_inputs.template index 6516f2d1..1565393f 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/withdraw/resolved_inputs.template +++ b/examples/acceptance_tests/script_context/v3/ctx/withdraw/resolved_inputs.template @@ -1,7 +1,7 @@ [ - { 0: h'30{{ withdraw.spend.hash }}{{ withdraw.spend.hash }}' + { 0: h'30{{ withdraw.thing.spend.hash }}{{ withdraw.thing.spend.hash }}' , 1: 1000000 , 2: [1, 24(h'd87980')] - , 3: 24(h'8203{{ withdraw.spend.cbor }}') + , 3: 24(h'8203{{ withdraw.thing.spend.cbor }}') } ] diff --git a/examples/acceptance_tests/script_context/v3/ctx/withdraw/tx.template b/examples/acceptance_tests/script_context/v3/ctx/withdraw/tx.template index 2d6f7c3e..6e523e17 100644 --- a/examples/acceptance_tests/script_context/v3/ctx/withdraw/tx.template +++ b/examples/acceptance_tests/script_context/v3/ctx/withdraw/tx.template @@ -23,7 +23,7 @@ , 5: { h'E000000000000000000000000000000000000000000000000000000000': 14 - , h'F0{{ withdraw.withdraw.hash }}': 0 + , h'F0{{ withdraw.thing.withdraw.hash }}': 0 } , 14: @@ -31,7 +31,7 @@ ] }, - { 5: [ [0, 0, 122([121([])]), [1000000, 100000000]] + { 5: [ [0, 0, 121([]), [1000000, 100000000]] , [3, 0, 121([]), [1000000, 100000000]] ] }, diff --git a/examples/acceptance_tests/script_context/v3/plutus.json b/examples/acceptance_tests/script_context/v3/plutus.json index 53e4b874..81fdf1a4 100644 --- a/examples/acceptance_tests/script_context/v3/plutus.json +++ b/examples/acceptance_tests/script_context/v3/plutus.json @@ -6,121 +6,161 @@ "plutusVersion": "v3", "compiler": { "name": "Aiken", - "version": "v1.0.31-alpha+fe5c565" + "version": "v1.0.31-alpha+3521a8c" }, "license": "Apache-2.0" }, "validators": [ { - "title": "certificates.script", + "title": "certificates.purposes.publish", "redeemer": { - "title": "_tmp1", + "title": "_redeemer", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "591a0301010032323232323232323232323232322533333300f00115332330083001300a37540042a66601860166ea8008494ccc024c8c8c8c94ccc034c018c03cdd50008a99980699b87482036b1024dd6980998081baa001132533300e3007301037540022a66601c66e1d201c375a602860226ea80044c8c94ccc040cdd7a612dd8799fd8799fd87a9f581c22222222222222222222222222222222222222222222222222222222ffd87a80ffff00330010054800054ccc040cdd7a612dd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054800854ccc040cdd7a612dd8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054801054ccc040cdd7a6149d8799fd905009f581c1111111111111111111111111111111111111111111111111111111158209999999999999999999999999999999999999999999999999999999999999999ffff00330010054801854ccc040cdd7a612ad8799fd905019f581c11111111111111111111111111111111111111111111111111111111190539ffff00330010054802054ccc040cdd7a6133d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f1a002dc6c0ffffff00330010054802854ccc040cdd7a6133d8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f1a002dc6c0ffffff00330010054803054ccc040cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054803854ccc040cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd87a9f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054804054ccc040cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87a80ffffff00330010054804854ccc040cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ffffff00330010054805054ccc040cdd7a614fd8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ffffff00330010054805854ccc040cdd7a6151d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c11111111111111111111111111111111111111111111111111111111ff1a002dc6c0ffff00330010054806054ccc040cdd7a6136d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ff1a002dc6c0ffff00330010054806854ccc040cdd7a6154d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ff1a002dc6c0ffff00330010054807054ccc040cdd7a614dd8799fd905029fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c22222222222222222222222222222222222222222222222222222222ffffff00330010054807854ccc040cdd7a612bd8799fd905039fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00330010054808054ccc040cdd7a612fd8799fd87d9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054808854ccc040cdd7a612fd8799fd87f9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054809054ccc040cdd7a612ad8799fd87e9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff0033001005480984c94ccc044c028c04cdd5000899299980919b8748010c050dd500089919299980a19b8748008c058dd5180d0010a99980a1806980b1baa00114a202202260326034002602a6ea800403cc05cc050dd500080719800802a40502a660229201a56578706563740a202020202020536f6d65280a202020202020202055706461746544656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031392900161533011491c66578706563740a202020202020536f6d65280a2020202020202020556e726567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031382900161533011491c56578706563740a202020202020536f6d65280a2020202020202020526567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031372900161533011491b26578706563740a202020202020536f6d65280a202020202020202052657469726546726f6d436f6e737469747574696f6e616c436f6d6d6974746565207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031362900161533011491e06578706563740a202020202020536f6d65280a2020202020202020417574686f72697a65436f6e737469747574696f6e616c436f6d6d697474656550726f7879207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202070726f78793a20566572696669636174696f6e4b6579286f6e6c793273292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031352900161533011491ff6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020202020646541706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031342900161533011491ed6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031332900161533011491ec6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e286f6e6c793173292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031322900161533011491ff6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020207d2c0a20202020202029203d3d206c186973742e6174286365727469666963617465732c2031312900161533011491c46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031302900161533011491be6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734162737461696e292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20392900161533011491cb6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428536372697074286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20382900161533011491d46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428566572696669636174696f6e4b6579286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20372900161533011491b26578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a20536f6d6528335f3030305f303030292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20362900161533011491b16578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a20536f6d6528335f3030305f303030292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c203529001615330114917e6578706563740a202020202020536f6d65285265746972655374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c2061745f65706f63683a2031333337207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020342c0a20202020202029001615330114917d6578706563740a202020202020536f6d652852656769737465725374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c207672663a206f6e6c793973207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020332c0a2020202020202900161533011491a76578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20322900161533011491a66578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20312900161533011491886578706563740a202020202020536f6d6528526567697374657243726564656e7469616c207b2063726564656e7469616c3a20536372697074286f6e6c793273292c206465706f7369743a204e6f6e65207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020302c0a2020202020202900163001001222533301500214c103d87a8000132325333013300c00313374a90001980c00125eb804ccc014014004cdc0001a40026032006602e004014014602660286028602860286028602860286028602860286028602860286028602860206ea8c00cc040dd500280400418091809980998099809980998099809980998099809980998099809980998079baa3002300f37540086eb0c044c048c048c048c048c048c038dd5180098071baa0032301100132533300a3370e900318061baa00113232533300c3370e90141bad30120021533300c3370e900218071baa00113232533300e3375e98122d8799f581c11111111111111111111111111111111111111111111111111111111ff00301430150021533300e3370e900118081baa001149854cc03d24011e65787065637420536372697074282e2e29203d2063726564656e7469616c0016153300f491416578706563742044656c6567617465426c6f636b50726f64756374696f6e207b207374616b655f706f6f6c3a206f6e6c793173207d203d3d2064656c656761746500163013001300f375400201601660226024002601a6ea8004024c03cc040c040c030dd50008a4c2a6601492011856616c696461746f722072657475726e65642066616c73650013656006370e90000028028028028028a9980324814165787065637420536f6d652831305f3030305f30303029203d206374782e7472616e73616374696f6e2e63757272656e745f74726561737572795f616d6f756e74001615330054913365787065637420536f6d6528313429203d206374782e7472616e73616374696f6e2e74726561737572795f646f6e6174696f6e001615330044918e65787065637420536f6d652844656c656761746543726564656e7469616c207b0a20202020202063726564656e7469616c3a20536372697074282e2e292c0a20202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e282e2e292c0a202020207d29203d206c6973742e6174286365727469666963617465732c20323029001615330034910b5f746d70313a20566f69640016153300249149657870656374205075626c697368696e672832302c2044656c656761746543726564656e7469616c207b2063726564656e7469616c2c2064656c6567617465207d29203d20696e666f00165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "9d0e90919e83c40a0c1f5be7c2203a78003210e4e52629c33b017bca" + "compiledCode": "5919990101003232323232323232323232253330053232323232533300a3370e900318061baa00113232323232323253330113005301337540022a66602266e1d2080dac409375a602e60286ea80044c94ccc048c018c050dd50008a99980919b8748070dd6980c180a9baa0011323253330143375e9812dd8799fd8799fd87a9f581c22222222222222222222222222222222222222222222222222222222ffd87a80ffff00330010054800054ccc050cdd7a612dd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054800854ccc050cdd7a612dd8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054801054ccc050cdd7a6149d8799fd905009f581c1111111111111111111111111111111111111111111111111111111158209999999999999999999999999999999999999999999999999999999999999999ffff00330010054801854ccc050cdd7a612ad8799fd905019f581c11111111111111111111111111111111111111111111111111111111190539ffff00330010054802054ccc050cdd7a612dd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054802854ccc050cdd7a612dd8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054803054ccc050cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054803854ccc050cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd87a9f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054804054ccc050cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87a80ffffff00330010054804854ccc050cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ffffff00330010054805054ccc050cdd7a614fd8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ffffff00330010054805854ccc050cdd7a6151d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c11111111111111111111111111111111111111111111111111111111ff1a002dc6c0ffff00330010054806054ccc050cdd7a6136d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ff1a002dc6c0ffff00330010054806854ccc050cdd7a6154d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ff1a002dc6c0ffff00330010054807054ccc050cdd7a614dd8799fd905029fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c22222222222222222222222222222222222222222222222222222222ffffff00330010054807854ccc050cdd7a612bd8799fd905039fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00330010054808054ccc050cdd7a612fd8799fd87d9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054808854ccc050cdd7a612fd8799fd87f9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054809054ccc050cdd7a612ad8799fd87e9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff0033001005480984c94ccc054c024c05cdd5000899299980b19b8748010c060dd500089919299980c19b8748008c068dd5180f0010a99980c1806180d1baa00114a202e02e603a603c00260326ea8004054c06cc060dd500080a19800802a40502a6602a9201a56578706563740a202020202020536f6d65280a202020202020202055706461746544656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031392900161533015491c66578706563740a202020202020536f6d65280a2020202020202020556e726567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031382900161533015491c56578706563740a202020202020536f6d65280a2020202020202020526567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031372900161533015491b26578706563740a202020202020536f6d65280a202020202020202052657469726546726f6d436f6e737469747574696f6e616c436f6d6d6974746565207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031362900161533015491e06578706563740a202020202020536f6d65280a2020202020202020417574686f72697a65436f6e737469747574696f6e616c436f6d6d697474656550726f7879207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202070726f78793a20566572696669636174696f6e4b6579286f6e6c793273292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031352900161533015491ff6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020202020646541706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031342900161533015491ed6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031332900161533015491ec6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e286f6e6c793173292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031322900161533015491ff6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020207d2c0a20202020202029203d3d206c186973742e6174286365727469666963617465732c2031312900161533015491c46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031302900161533015491be6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734162737461696e292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20392900161533015491cb6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428536372697074286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20382900161533015491d46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428566572696669636174696f6e4b6579286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20372900161533015491a76578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20362900161533015491a66578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c203529001615330154917e6578706563740a202020202020536f6d65285265746972655374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c2061745f65706f63683a2031333337207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020342c0a20202020202029001615330154917d6578706563740a202020202020536f6d652852656769737465725374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c207672663a206f6e6c793973207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020332c0a2020202020202900161533015491a76578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20322900161533015491a66578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20312900161533015491886578706563740a202020202020536f6d6528526567697374657243726564656e7469616c207b2063726564656e7469616c3a20536372697074286f6e6c793273292c206465706f7369743a204e6f6e65207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020302c0a2020202020202900163001001222533301900214c103d87a8000132325333017300b00313374a90001980e00125eb804ccc014014004cdc0001a4002603a0066036004020020602e60306030603060306030603060306030603060306030603060306030603060286ea802c038038c058c05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc04cdd50051bac3015301630163016301630163012375401264a66601e66e1d20043011375400226464a66602266ebd300122d8799f581c11111111111111111111111111111111111111111111111111111111ff0030173018002153330113370e900118099baa001149854cc04924011e65787065637420536372697074282e2e29203d2063726564656e7469616c00161533012491416578706563742044656c6567617465426c6f636b50726f64756374696f6e207b207374616b655f706f6f6c3a206f6e6c793173207d203d3d2064656c656761746500163016001301237540022a66020921406578706563742044656c656761746543726564656e7469616c207b2063726564656e7469616c2c2064656c6567617465207d203d206365727469666963617465001630143015004533300d3001300f375400a2a66602260206ea80145261616370e90001bad3011001300d37540022c601e6020004601c002601c004601800260106ea8004526153300649011856616c696461746f722072657475726e65642066616c73650013656153300449013d65787065637420536f6d652831305f3030305f30303029203d207472616e73616374696f6e2e63757272656e745f74726561737572795f616d6f756e74001615330034912f65787065637420536f6d6528313429203d207472616e73616374696f6e2e74726561737572795f646f6e6174696f6e001615330024918e65787065637420536f6d652844656c656761746543726564656e7469616c207b0a20202020202063726564656e7469616c3a20536372697074282e2e292c0a20202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e282e2e292c0a202020207d29203d206c6973742e6174286365727469666963617465732c2032302900165734ae7155ceaab9e5573eae815d0aba21", + "hash": "a02054fde28a3bf37a20ffb4eb34d84ab50eb5980a9b2b44789dc3bd" }, { - "title": "mint.mint_1", + "title": "certificates.purposes.else", + "compiledCode": "5919990101003232323232323232323232253330053232323232533300a3370e900318061baa00113232323232323253330113005301337540022a66602266e1d2080dac409375a602e60286ea80044c94ccc048c018c050dd50008a99980919b8748070dd6980c180a9baa0011323253330143375e9812dd8799fd8799fd87a9f581c22222222222222222222222222222222222222222222222222222222ffd87a80ffff00330010054800054ccc050cdd7a612dd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054800854ccc050cdd7a612dd8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054801054ccc050cdd7a6149d8799fd905009f581c1111111111111111111111111111111111111111111111111111111158209999999999999999999999999999999999999999999999999999999999999999ffff00330010054801854ccc050cdd7a612ad8799fd905019f581c11111111111111111111111111111111111111111111111111111111190539ffff00330010054802054ccc050cdd7a612dd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054802854ccc050cdd7a612dd8799fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffff00330010054803054ccc050cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054803854ccc050cdd7a6154d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd87a9f581c00000000000000000000000000000000000000000000000000000000ffffffffff00330010054804054ccc050cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87a80ffffff00330010054804854ccc050cdd7a6131d8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ffffff00330010054805054ccc050cdd7a614fd8799fd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ffffff00330010054805854ccc050cdd7a6151d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c11111111111111111111111111111111111111111111111111111111ff1a002dc6c0ffff00330010054806054ccc050cdd7a6136d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ff1a002dc6c0ffff00330010054806854ccc050cdd7a6154d8799fd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ff1a002dc6c0ffff00330010054807054ccc050cdd7a614dd8799fd905029fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c22222222222222222222222222222222222222222222222222222222ffffff00330010054807854ccc050cdd7a612bd8799fd905039fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00330010054808054ccc050cdd7a612fd8799fd87d9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054808854ccc050cdd7a612fd8799fd87f9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffff00330010054809054ccc050cdd7a612ad8799fd87e9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff0033001005480984c94ccc054c024c05cdd5000899299980b19b8748010c060dd500089919299980c19b8748008c068dd5180f0010a99980c1806180d1baa00114a202e02e603a603c00260326ea8004054c06cc060dd500080a19800802a40502a6602a9201a56578706563740a202020202020536f6d65280a202020202020202055706461746544656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031392900161533015491c66578706563740a202020202020536f6d65280a2020202020202020556e726567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031382900161533015491c56578706563740a202020202020536f6d65280a2020202020202020526567697374657244656c6567617465526570726573656e746174697665207b0a2020202020202020202064656c65676174655f726570726573656e7461746976653a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031372900161533015491b26578706563740a202020202020536f6d65280a202020202020202052657469726546726f6d436f6e737469747574696f6e616c436f6d6d6974746565207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031362900161533015491e06578706563740a202020202020536f6d65280a2020202020202020417574686f72697a65436f6e737469747574696f6e616c436f6d6d697474656550726f7879207b0a20202020202020202020636f6e737469747574696f6e616c5f636f6d6d69747465655f6d656d6265723a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202070726f78793a20566572696669636174696f6e4b6579286f6e6c793273292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031352900161533015491ff6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020202020646541706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031342900161533015491ed6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031332900161533015491ec6578706563740a202020202020536f6d65280a20202020202020205265676973746572416e6444656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e286f6e6c793173292c0a202020202020202020206465706f7369743a20335f3030305f3030302c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031322900161533015491ff6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465426f7468207b0a2020202020202020202020207374616b655f706f6f6c3a206f6e6c7931732c0a20202020202020202020202064656c65676174655f726570726573656e7461746976653a20416c776179734e6f436f6e666964656e63652c0a202020202020202020207d2c0a20202020202020207d2c0a20202020202029203d3d206c186973742e6174286365727469666963617465732c2031312900161533015491c46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734e6f436f6e666964656e6365292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c2031302900161533015491be6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f746528416c776179734162737461696e292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20392900161533015491cb6578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428536372697074286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20382900161533015491d46578706563740a202020202020536f6d65280a202020202020202044656c656761746543726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a2020202020202020202064656c65676174653a2044656c6567617465566f7465285265676973746572656428566572696669636174696f6e4b6579286f6e6c7930732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20372900161533015491a76578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20362900161533015491a66578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c203529001615330154917e6578706563740a202020202020536f6d65285265746972655374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c2061745f65706f63683a2031333337207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020342c0a20202020202029001615330154917d6578706563740a202020202020536f6d652852656769737465725374616b65506f6f6c207b207374616b655f706f6f6c3a206f6e6c7931732c207672663a206f6e6c793973207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020332c0a2020202020202900161533015491a76578706563740a202020202020536f6d65280a2020202020202020556e726567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a20202020202020202020726566756e643a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20322900161533015491a66578706563740a202020202020536f6d65280a2020202020202020526567697374657243726564656e7469616c207b0a2020202020202020202063726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020206465706f7369743a204e6f6e652c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286365727469666963617465732c20312900161533015491886578706563740a202020202020536f6d6528526567697374657243726564656e7469616c207b2063726564656e7469616c3a20536372697074286f6e6c793273292c206465706f7369743a204e6f6e65207d29203d3d206c6973742e6174280a20202020202020206365727469666963617465732c0a2020202020202020302c0a2020202020202900163001001222533301900214c103d87a8000132325333017300b00313374a90001980e00125eb804ccc014014004cdc0001a4002603a0066036004020020602e60306030603060306030603060306030603060306030603060306030603060286ea802c038038c058c05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc05cc04cdd50051bac3015301630163016301630163012375401264a66601e66e1d20043011375400226464a66602266ebd300122d8799f581c11111111111111111111111111111111111111111111111111111111ff0030173018002153330113370e900118099baa001149854cc04924011e65787065637420536372697074282e2e29203d2063726564656e7469616c00161533012491416578706563742044656c6567617465426c6f636b50726f64756374696f6e207b207374616b655f706f6f6c3a206f6e6c793173207d203d3d2064656c656761746500163016001301237540022a66020921406578706563742044656c656761746543726564656e7469616c207b2063726564656e7469616c2c2064656c6567617465207d203d206365727469666963617465001630143015004533300d3001300f375400a2a66602260206ea80145261616370e90001bad3011001300d37540022c601e6020004601c002601c004601800260106ea8004526153300649011856616c696461746f722072657475726e65642066616c73650013656153300449013d65787065637420536f6d652831305f3030305f30303029203d207472616e73616374696f6e2e63757272656e745f74726561737572795f616d6f756e74001615330034912f65787065637420536f6d6528313429203d207472616e73616374696f6e2e74726561737572795f646f6e6174696f6e001615330024918e65787065637420536f6d652844656c656761746543726564656e7469616c207b0a20202020202063726564656e7469616c3a20536372697074282e2e292c0a20202020202064656c65676174653a2044656c6567617465426c6f636b50726f64756374696f6e282e2e292c0a202020207d29203d206c6973742e6174286365727469666963617465732c2032302900165734ae7155ceaab9e5573eae815d0aba21", + "hash": "a02054fde28a3bf37a20ffb4eb34d84ab50eb5980a9b2b44789dc3bd" + }, + { + "title": "mint.test_1.mint", "redeemer": { - "title": "_tmp2", + "title": "_rdmr", "schema": { "$ref": "#/definitions/Data" } }, - "compiledCode": "590fe001010032323232323232323232322253330053232323232323232323232324a2a66602066ebcdd31980a99bb04c1225820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec004c0103d87980004bd6f7b630180b180b980b980b980b980b980b980b980b980b980b98099baa3008301337540182930a99808a4937657870656374205b5061697228766f69645f686173682c20766f6964295d203d3d20646963742e746f5f706169727328646174756d73290016533300f3375e6e9ccc050c014cc051300127d8799f5820000000000000000000000000000000000000000000000000000000000000000000ff0033014300533014300448811c000000000000000000000000000000000000000000000000000000000033014374c6006904044bd1980a260103d8798000330144c103d87a80004bd7025eb812f5c0602a602c60246ea8c01cc048dd50058a4c2a66020921ff6578706563740a202020205b0a202020202020496e707574207b0a20202020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b0a202020202020202020207472616e73616374696f6e5f69643a206e756c6c33322c0a202020202020202020206f75747075745f696e6465783a20302c0a20202020202020207d2c0a20202020202020206f75747075743a204f7574707574207b0a20202020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a2020202020202020202076616c75653a206173736574732e6672776f6d5f6c6f76656c61636528315f3030305f303030292c0a20202020202020202020646174756d3a204e6f446174756d2c0a202020202020202020207265666572656e63655f7363726970743a204e6f6e652c0a20202020202020207d2c0a2020202020207d2c0a202020205d203d3d20696e707574730016533300e3375e6e9ccc04cdd3998099ba9005330134c1064561696b656e00330134c1012d004bd70198099ba733013375200a66026981084763617264616e6f00330134c10101004bd70198099ba733013375200e66026981054474756e6100330134c1091b00005af3107a4000004bd7025eb80dd399198008009bab3015301630163016301630123754600e60246ea802c894ccc05000452f5c0264666444646600200200644a6660340022006264660386e9ccc070dd48031980e180c8009980e180d000a5eb80cc00c00cc078008c070004dd718098009bab30140013300300330180023016001149854cc03d2401a86578706563740a202020205b0a202020202020286f746865725f706f6c6963795f69642c202261696b656e222c202d3134292c0a202020202020286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a202020202020286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030292c0a202020205d203d3d206173736574732e666c617474656e286d696e7429001633232323232323232253330163370e600c00290030a99980b19baf300c3301b300c3301b300b48811c00000000000000000000000000000000000000000000000000000000003301b374c6014904044bd1980da60126d87a9f5820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ecff003301b4c103d87a80004bd7025eb80cc0100052000153330163375e6018660366018660366600660169111c000000000000000000000000000000000000000000000000000000000048811c00000000000000000000000000000000000000000000000000000000003301b374c666600466660046014904044bd007a4410474756e610048202034a1f8af0b403522010561696b656e0048150cc06d300103d87980003301b4c103d87a80004bd7025eb80cc0100052002153330163375e6018660366018660366600660186603666e9520023301b4c011e581c00000000000000000000000000000000000000000000000000000000004bd701980da60103d87a80004bd702451c00000000000000000000000000000000000000000000000000000000003301b374c66660046014904044bd006a450763617264616e6f0048008cc06d300103d87980003301b4c122d8799f581c68ad54b3a8124d9fe5caaaf2011a85d72096e696a2fb3d7f86c41717ff004bd7025eb80cc0100052004149854cc05d2401ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f736372697074286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a2020202020202020646174756d3a204e6f44619c74756d2c0a20202020202020207265666572656e63655f7363726970743a20536f6d65280a2020202020202020202023223638616435346233613831323464396665356361616166323031316138356437323039366536393661326662336437663836633431373137222c0a2020202020202020292c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20322900161533017491ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030290a20932020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202261696b656e222c203432292c0a2020202020202020646174756d3a204e6f446174756d2c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20312900161533017491f56578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030292c0a2020202020202020646174756d3a20446174756d4861736828766f69645f68617368292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c2030290016153301749120657870656374206c6973742e6c656e677468286f75747075747329203d3d203300162222533301830120011004132323300100100622533301f001133020337606ea4018dd3001a5eb7bdb1804c8c8c8c94ccc07ccdc800500109981219bb037520146e9801c01454ccc07ccdc78050010992999810180d18111baa001133025337606ea402cc098c08cdd5000802080219299981029998120008a5114a0298103d87a80001301633025374c00297ae03233001001002225333025001133026337606ea402cdd400525eb7bdb1804c8c8c8c94ccc094cdc800780109981519bb0375201e6ea003801454ccc094cdc78078010992999813181018141baa00113302b337606ea4040c0b0c0a4dd5000802080219299981318100008a6103d87a80001301c3302b375000297ae03370000201c26605466ec0dd48011ba800133006006003375a604e0066eb8c094008c0a4008c09c0044cc090cdd81ba9002374c0026600c00c0066eacc08400cdd7180f80118118011810800991900118058009980e99bb037520046ea00052f5bded8c044601666034601a60306ea8008cc068c02ccc068c02ccc068c02ccc068dd4800a5eb812f5c097ae04bd701800800911299980c0010a60103d87a800013232533301630100031300c3301b0024bd70099980280280099b8000348004c07000cc068008c004004894ccc05400452000133700900119801001180c00098008009129998098008a4c264a66602800229309919299980919b90375c602860300086eb8c0500084cc014014cc05c00800454cc04d241326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f7264657200163018002301600130160013758601060206ea8c014c040dd50049299980698038008a5eb7bdb1804c8c8cc0040052f5bded8c044a66602800226602a66ec13001014000374c00697adef6c60132323232533301433720910100002133019337609801014000374c00e00a2a66602866e3d22100002133019337609801014000374c00e00626603266ec0dd48011ba6001330060060033756602c0066eb8c050008c060008c058004c8cc0040052f5bded8c044a66602600226602866ec13001014000375000697adef6c60132323232533301333720910100002133018337609801014000375000e00a2a66602666e3d22100002133018337609801014000375000e00626603066ec0dd48011ba800133006006003375a602a0066eb8c04c008c05c008c0540048c008cc044c008cc044dd4800a5eb80cc04530103d87a80004bd701ba548000c94ccc0380040204c8c94ccc04000402854ccc040c04c0044c8c94ccc038c020c040dd5001099299999980b8010a999807980498089baa0021533301330123754004200201c01c01c01c01c01c6eb8c050c044dd500100618080019807001005180900118080009bab300f301030103010301030103010301030103010300c3754600260186ea80148c03c004c94ccc020c008c028dd500089bae300e300b37540022a6601292120657870656374204d696e74696e6728706f6c6963795f696429203d20696e666f00163002300a37540066e1d20002300c300d300d001149854cc01924011856616c696461746f722072657475726e65642066616c736500136561533003490139657870656374205b50616972284d696e74286f746865725f706f6c6963795f6964292c2064617461292c205f5d203d2072656465656d657273001615330024911265787065637420566f6964203d206461746100165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "28f948cbe411a7132eb0c1b5f65fb141aa65d8d3a948ec35a07dae38" + "compiledCode": "590fa3010100323232323232323232323225333004323232323253323300a3001300c375400426464646464646464649454ccc048cdd79ba63301733760981225820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec004c0103d87980004bd6f7b630180c180c980c980c980c980c980c980c980c980c980c980a9baa00d149854cc04d240137657870656374205b5061697228766f69645f686173682c20766f6964295d203d3d20646963742e746f5f706169727328646174756d7329001653330113375e6e9ccc058c014cc059300127d8799f5820000000000000000000000000000000000000000000000000000000000000000000ff0033016300533016300448811c000000000000000000000000000000000000000000000000000000000033016374c6006904044bd1980b260103d8798000330164c103d87a80004bd7025eb812f5c0602e603060286ea80305261533012491ff6578706563740a202020205b0a202020202020496e707574207b0a20202020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b0a202020202020202020207472616e73616374696f6e5f69643a206e756c6c33322c0a202020202020202020206f75747075745f696e6465783a20302c0a20202020202020207d2c0a20202020202020206f75747075743a204f7574707574207b0a20202020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a2020202020202020202076616c75653a206173736574732e6672776f6d5f6c6f76656c61636528315f3030305f303030292c0a20202020202020202020646174756d3a204e6f446174756d2c0a202020202020202020207265666572656e63655f7363726970743a204e6f6e652c0a20202020202020207d2c0a2020202020207d2c0a202020205d203d3d20696e70757473001653330103375e6e9ccc054dd39980a9ba9005330154c1064561696b656e00330154c1012d004bd701980a9ba733015375200a6602a981084763617264616e6f00330154c10101004bd701980a9ba733015375200c6602a981054474756e6100330154c1091b00005af3107a4000004bd7025eb80dd399198008009bab301730183018301830183014375401844a66602c002297ae0132333222323300100100322533301c00110031323301e374e6603c6ea4018cc078c06c004cc078c0700052f5c0660060066040004603c0026eb8c054004dd5980b00099801801980d001180c0008a4c2a660229201a86578706563740a202020205b0a202020202020286f746865725f706f6c6963795f69642c202261696b656e222c202d3134292c0a202020202020286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a202020202020286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030292c0a202020205d203d3d206173736574732e666c617474656e286d696e7429001633232323232323232253330183370e600c00290030a99980c19baf300c3301d300c3301d300b48811c00000000000000000000000000000000000000000000000000000000003301d374c6014904044bd1980ea60126d87a9f5820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ecff003301d4c103d87a80004bd7025eb80cc0100052000153330183375e60186603a60186603a6600660169111c000000000000000000000000000000000000000000000000000000000048811c00000000000000000000000000000000000000000000000000000000003301d374c666600466660046014904044bd00724410474756e610048202034a1f8af0b403522010561696b656e0048150cc075300103d87980003301d4c103d87a80004bd7025eb80cc0100052002153330183375e60186603a60186603a6600660186603a66e9520023301d4c011e581c00000000000000000000000000000000000000000000000000000000004bd701980ea60103d87a80004bd702451c00000000000000000000000000000000000000000000000000000000003301d374c66660046014904044bd006a450763617264616e6f0048008cc075300103d87980003301d4c122d8799f581c68ad54b3a8124d9fe5caaaf2011a85d72096e696a2fb3d7f86c41717ff004bd7025eb80cc0100052004149854cc0652401ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f736372697074286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a2020202020202020646174756d3a204e6f44619c74756d2c0a20202020202020207265666572656e63655f7363726970743a20536f6d65280a2020202020202020202023223638616435346233613831323464396665356361616166323031316138356437323039366536393661326662336437663836633431373137222c0a2020202020202020292c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20322900161533019491ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030290a20932020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202261696b656e222c203432292c0a2020202020202020646174756d3a204e6f446174756d2c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20312900161533019491f56578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030292c0a2020202020202020646174756d3a20446174756d4861736828766f69645f68617368292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c2030290016153301949120657870656374206c6973742e6c656e677468286f75747075747329203d3d203300162222533301a301100110041323233001001006225333021001133022337606ea4018dd3001a5eb7bdb1804c8c8c8c94ccc084cdc800500109981319bb037520146e9801c01454ccc084cdc78050010992999811180c98121baa001133027337606ea402cc0a0c094dd5000802080219299981129998130008a5114a0298103d87a80001301633027374c00297ae03233001001002225333027001133028337606ea402cdd400525eb7bdb1804c8c8c8c94ccc09ccdc800780109981619bb0375201e6ea003801454ccc09ccdc78078010992999814180f98151baa00113302d337606ea4040c0b8c0acdd50008020802192999814180f8008a6103d87a80001301c3302d375000297ae03370000201c26605866ec0dd48011ba800133006006003375a60520066eb8c09c008c0ac008c0a40044cc098cdd81ba9002374c0026600c00c0066eacc08c00cdd7181080118128011811800991900118058009980f99bb037520046ea00052f5bded8c044601666038603a60346ea8008cc070c02ccc070c02ccc070c02ccc070dd4800a5eb812f5c097ae04bd701800800911299980d0010a60103d87a8000132325333018300f0031300c3301d0024bd70099980280280099b8000348004c07800cc070008c004004894ccc05c00452000133700900119801001180d000980080091299980a8008a4c264a66602c00229309919299980a19b90375c602c60340086eb8c0580084cc014014cc06400800454cc055241326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f726465720016301a002301800130180013758602a602c602c60246ea802894ccc03cc01800452f5bded8c0264646600200297adef6c60225333016001133017337609801014000374c00697adef6c6013232323253330163372091010000213301b337609801014000374c00e00a2a66602c66e3d2210000213301b337609801014000374c00e00626603666ec0dd48011ba600133006006003375660300066eb8c058008c068008c060004c8cc0040052f5bded8c044a66602a00226602c66ec13001014000375000697adef6c6013232323253330153372091010000213301a337609801014000375000e00a2a66602a66e3d2210000213301a337609801014000375000e00626603466ec0dd48011ba800133006006003375a602e0066eb8c054008c064008c05c0048c008cc04cc008cc04cdd4800a5eb80cc04d30103d87a80004bd701ba548000c94ccc0400040284c8c94ccc04800403054ccc048c0540044c8c94ccc040c01cc048dd5001099299999980c8010a999808980418099baa002153330153014375400420020200200200200200206eb8c058c04cdd500100718090019808001006180a00118090009bab3011301230123012301230123012301230123012300e375400c6eb8c040c034dd50011b874800058c038c03c008c034004c034008c02c004c01cdd50008a4c2a6600a9211856616c696461746f722072657475726e65642066616c736500136561533003490139657870656374205b50616972284d696e74286f746865725f706f6c6963795f6964292c2064617461292c205f5d203d2072656465656d657273001615330024911265787065637420566f6964203d206461746100165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "514bebb1441c98fa4a56cd08982897f66eb332868d562a7e07c03736" }, { - "title": "mint.mint_2", + "title": "mint.test_1.else", + "compiledCode": "590fa3010100323232323232323232323225333004323232323253323300a3001300c375400426464646464646464649454ccc048cdd79ba63301733760981225820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec004c0103d87980004bd6f7b630180c180c980c980c980c980c980c980c980c980c980c980a9baa00d149854cc04d240137657870656374205b5061697228766f69645f686173682c20766f6964295d203d3d20646963742e746f5f706169727328646174756d7329001653330113375e6e9ccc058c014cc059300127d8799f5820000000000000000000000000000000000000000000000000000000000000000000ff0033016300533016300448811c000000000000000000000000000000000000000000000000000000000033016374c6006904044bd1980b260103d8798000330164c103d87a80004bd7025eb812f5c0602e603060286ea80305261533012491ff6578706563740a202020205b0a202020202020496e707574207b0a20202020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b0a202020202020202020207472616e73616374696f6e5f69643a206e756c6c33322c0a202020202020202020206f75747075745f696e6465783a20302c0a20202020202020207d2c0a20202020202020206f75747075743a204f7574707574207b0a20202020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a2020202020202020202076616c75653a206173736574732e6672776f6d5f6c6f76656c61636528315f3030305f303030292c0a20202020202020202020646174756d3a204e6f446174756d2c0a202020202020202020207265666572656e63655f7363726970743a204e6f6e652c0a20202020202020207d2c0a2020202020207d2c0a202020205d203d3d20696e70757473001653330103375e6e9ccc054dd39980a9ba9005330154c1064561696b656e00330154c1012d004bd701980a9ba733015375200a6602a981084763617264616e6f00330154c10101004bd701980a9ba733015375200c6602a981054474756e6100330154c1091b00005af3107a4000004bd7025eb80dd399198008009bab301730183018301830183014375401844a66602c002297ae0132333222323300100100322533301c00110031323301e374e6603c6ea4018cc078c06c004cc078c0700052f5c0660060066040004603c0026eb8c054004dd5980b00099801801980d001180c0008a4c2a660229201a86578706563740a202020205b0a202020202020286f746865725f706f6c6963795f69642c202261696b656e222c202d3134292c0a202020202020286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a202020202020286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030292c0a202020205d203d3d206173736574732e666c617474656e286d696e7429001633232323232323232253330183370e600c00290030a99980c19baf300c3301d300c3301d300b48811c00000000000000000000000000000000000000000000000000000000003301d374c6014904044bd1980ea60126d87a9f5820923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ecff003301d4c103d87a80004bd7025eb80cc0100052000153330183375e60186603a60186603a6600660169111c000000000000000000000000000000000000000000000000000000000048811c00000000000000000000000000000000000000000000000000000000003301d374c666600466660046014904044bd00724410474756e610048202034a1f8af0b403522010561696b656e0048150cc075300103d87980003301d4c103d87a80004bd7025eb80cc0100052002153330183375e60186603a60186603a6600660186603a66e9520023301d4c011e581c00000000000000000000000000000000000000000000000000000000004bd701980ea60103d87a80004bd702451c00000000000000000000000000000000000000000000000000000000003301d374c66660046014904044bd006a450763617264616e6f0048008cc075300103d87980003301d4c122d8799f581c68ad54b3a8124d9fe5caaaf2011a85d72096e696a2fb3d7f86c41717ff004bd7025eb80cc0100052004149854cc0652401ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f736372697074286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202263617264616e6f222c2031292c0a2020202020202020646174756d3a204e6f44619c74756d2c0a20202020202020207265666572656e63655f7363726970743a20536f6d65280a2020202020202020202023223638616435346233613831323464396665356361616166323031316138356437323039366536393661326662336437663836633431373137222c0a2020202020202020292c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20322900161533019491ff6578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238290a202020202020202020207c3e2063726564656e7469616c2e776974685f64656c65676174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030290a202020202020202020207c3e206173736574732e616464286f75725f706f6c6963795f69642c202274756e61222c20313030303030303030303030303030290a20932020202020202020207c3e206173736574732e616464286f746865725f706f6c6963795f69642c202261696b656e222c203432292c0a2020202020202020646174756d3a204e6f446174756d2c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c20312900161533019491f56578706563740a20202020536f6d65280a2020202020204f7574707574207b0a2020202020202020616464726573733a2063726564656e7469616c2e66726f6d5f766572696669636174696f6e5f6b6579286e756c6c3238292c0a202020202020202076616c75653a206173736574732e66726f6d5f6c6f76656c61636528315f3030305f303030292c0a2020202020202020646174756d3a20446174756d4861736828766f69645f68617368292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a2020202029203d3d206c6973742e6174286f7574707574732c2030290016153301949120657870656374206c6973742e6c656e677468286f75747075747329203d3d203300162222533301a301100110041323233001001006225333021001133022337606ea4018dd3001a5eb7bdb1804c8c8c8c94ccc084cdc800500109981319bb037520146e9801c01454ccc084cdc78050010992999811180c98121baa001133027337606ea402cc0a0c094dd5000802080219299981129998130008a5114a0298103d87a80001301633027374c00297ae03233001001002225333027001133028337606ea402cdd400525eb7bdb1804c8c8c8c94ccc09ccdc800780109981619bb0375201e6ea003801454ccc09ccdc78078010992999814180f98151baa00113302d337606ea4040c0b8c0acdd50008020802192999814180f8008a6103d87a80001301c3302d375000297ae03370000201c26605866ec0dd48011ba800133006006003375a60520066eb8c09c008c0ac008c0a40044cc098cdd81ba9002374c0026600c00c0066eacc08c00cdd7181080118128011811800991900118058009980f99bb037520046ea00052f5bded8c044601666038603a60346ea8008cc070c02ccc070c02ccc070c02ccc070dd4800a5eb812f5c097ae04bd701800800911299980d0010a60103d87a8000132325333018300f0031300c3301d0024bd70099980280280099b8000348004c07800cc070008c004004894ccc05c00452000133700900119801001180d000980080091299980a8008a4c264a66602c00229309919299980a19b90375c602c60340086eb8c0580084cc014014cc06400800454cc055241326b65797320696e206173736f63696174697665206c697374206172656e277420696e20617363656e64696e67206f726465720016301a002301800130180013758602a602c602c60246ea802894ccc03cc01800452f5bded8c0264646600200297adef6c60225333016001133017337609801014000374c00697adef6c6013232323253330163372091010000213301b337609801014000374c00e00a2a66602c66e3d2210000213301b337609801014000374c00e00626603666ec0dd48011ba600133006006003375660300066eb8c058008c068008c060004c8cc0040052f5bded8c044a66602a00226602c66ec13001014000375000697adef6c6013232323253330153372091010000213301a337609801014000375000e00a2a66602a66e3d2210000213301a337609801014000375000e00626603466ec0dd48011ba800133006006003375a602e0066eb8c054008c064008c05c0048c008cc04cc008cc04cdd4800a5eb80cc04d30103d87a80004bd701ba548000c94ccc0400040284c8c94ccc04800403054ccc048c0540044c8c94ccc040c01cc048dd5001099299999980c8010a999808980418099baa002153330153014375400420020200200200200200206eb8c058c04cdd500100718090019808001006180a00118090009bab3011301230123012301230123012301230123012300e375400c6eb8c040c034dd50011b874800058c038c03c008c034004c034008c02c004c01cdd50008a4c2a6600a9211856616c696461746f722072657475726e65642066616c736500136561533003490139657870656374205b50616972284d696e74286f746865725f706f6c6963795f6964292c2064617461292c205f5d203d2072656465656d657273001615330024911265787065637420566f6964203d206461746100165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "514bebb1441c98fa4a56cd08982897f66eb332868d562a7e07c03736" + }, + { + "title": "mint.test_2.mint", "redeemer": { "title": "_tmp2", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "58930101003232323232323225333333008001153330033370e900018029baa001153330073006375400224a666008a6600a9201105f5f5f5f5f6d696e745f325f5f5f5f5f0014a22930a99802a4811856616c696461746f722072657475726e65642066616c73650013656002002002002002002153300249010b5f746d70323a20566f696400165734ae7155ceaab9e5573eae91", - "hash": "0c8eaf490c53afbf27e3d84a3b57da51fbafe5aa78443fcec2dc262e" + "compiledCode": "58a70101003232323232323225333002323232323253330073370e900018049baa0011323253300a49010e736c6668696f65723777387972750014a2a66601066e1d2000300a37540062a66601860166ea800c5261616375c601860146ea800458c02cc030008c028004c028008c020004c014dd50008a4c2a660069211856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae855d101", + "hash": "0c7fdf894714b91be17feb6d255619d0c45c14075faf7f9ccce61d78" }, { - "title": "proposing_all.guardrails", + "title": "mint.test_2.else", + "compiledCode": "58a70101003232323232323225333002323232323253330073370e900018049baa0011323253300a49010e736c6668696f65723777387972750014a2a66601066e1d2000300a37540062a66601860166ea800c5261616375c601860146ea800458c02cc030008c028004c028008c020004c014dd50008a4c2a660069211856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae855d101", + "hash": "0c7fdf894714b91be17feb6d255619d0c45c14075faf7f9ccce61d78" + }, + { + "title": "proposing_all.guardrails.propose", "redeemer": { - "title": "_tmp1", + "title": "_redeemer", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "590c9f0101003232323232323232323232323232322533333301000115332330093001300b37540042a66601a60186ea8008494ccc028c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c92899299980e980a980f9baa001132533301e3012375a602860426ea800454ccc078cdd7980698109baa0014c122d8799f581c00000000000000000000000000000000000000000000000000000000ff001533301e3375e601860426ea8005300103d87f8000149854cc07d2412e6578706563742070726f6365647572652e676f7665726e616e63655f616374696f6e203d3d204e696365506f6c6c0016153301f4913a6578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20566572696669636174696f6e4b6579286e756c6c323829001601d30233020375400203666018022900819804198058082401c4a66603866ebd30012dd87e9fd87a80d8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00001149854cc0752401996578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a20536f6d65286e756c6c323829207d2c0a202020202020202020207d203d3d20616374696f6e0016330073300a00f4803094ccc06ccdd7a6010ed87e9fd87a80d8799fd87a80ffff00001149854cc0712401916578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a204e6f6e65207d2c0a202020202020202020207d203d3d20616374696f6e0016330063300900e480288c94ccc06cc04cc074dd50008a99980d99baf3374a90041981026103d87a8000330204c1249fd8799f581c00000000000000000000000000000000000000000000000000000000ffff00330204c126a1d8799f581c00000000000000000000000000000000000000000000000000000000ff1901f400330203021301e375400297ae0002149854cc071241e96578706563740a20202020202020202020436f6e737469747574696f6e616c436f6d6d6974746565207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020657669637465645f6d656d626572733a205b566572696669636174696f6e4b6579286e756c6c3238295d2c0a20202020202020202020202061646465645f6d656d626572733a205b5061697228566572696669636174696f6e4b6579286e756c6c3238292c20353030295d2c0a20202020202020202020202071756f72756d2c0a202020202020202020207d203d3d20616374696f6e0016153301c4912865787065637420536f6d652871756f72756d29203d20726174696f6e616c2e6e657728312c2032290016533301a4a0298103d87a80001533301a4a0260186603e60186603e6ea120013301f37509001a5eb812f5c0260186603e60186603e9810101003301f4c10102004bd7025eb80cc014cc0200352008253330193375e98107d87c9fd87a80ff00001149854cc069240130657870656374204e6f436f6e666964656e6365207b20616e636573746f723a204e6f6e65207d203d3d20616374696f6e0016330043300700c4801894ccc060cdc3a400860346ea800454ccc060c040c068dd5180f180f980d9baa0011498048048cc00ccc01802d2004253330173375e98012fd87b9fa1d8799f581c11111111111111111111111111111111111111111111111111111111ff1a000f4240d87a80ff00001149854cc0612401ff6578706563740a2020202020202020202054726561737572795769746864726177616c207b0a20202020202020202020202062656e656669636961726965733a205b0a202020202020202020202020202050616972280a20202020202020202020202020202020566572696669636174696f6e4b6579280a20202020202020202020202020202020202023223131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131222c0a20202020202020202020202020202020292c0a20202020202020202020202020202020315f3030305f3030302c0a202020202020202020204920202020292c0a2020202020202020202020205d2c0a20202020202020202020202067756172647261696c733a204e6f6e652c0a202020202020202020207d203d3d20616374696f6e0016330023300500a4800894ccc058cdd7a60135d87a9fd8799fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8799f0b00ffff00001149854cc05d24019d6578706563740a2020202020202020202048617264466f726b207b0a202020202020202020202020616e636573746f723a20536f6d6528476f7665726e616e6365416374696f6e4964286e756c6c33322c203029292c0a2020202020202020202020206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831312c2030292c0a202020202020202020207d203d3d20616374696f6e001633001330040094800094ccc054cdd7a6010dd87a9fd87a80d8799f0a00ffff00001149854cc05924015b6578706563740a2020202020202020202048617264466f726b207b20616e636573746f723a204e6f6e652c206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831302c203029207d203d3d20616374696f6e0016225333015300d30173754004264a66602c60146eb4c030c064dd50008a99980b19baf300530193754002980122d87a9f581c00000000000000000000000000000000000000000000000000000000ff00130023004301937540022a6602e921316578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20536372697074286e756c6c3238290016015301b3018375400402646032603460340024603060320026002002444a66602c0042980103d87a8000132325333014300c00313006330190024bd70099980280280099b8000348004c06800cc060008dd2a400064a666024002014264a666026602c00426464a66602266e1d200a3013375400426464a66602666e1d2006375a6032004264646464a66602e60166eb4c07401054ccc05ccdd780126122d87a9f581c00000000000000000000000000000000000000000000000000000000ff00153330173370e9002180c9baa0011533333301f00715333017300f3019375400e2a66603660346ea801c52601401401401401401415330184901346578706563742054726561737572795769746864726177616c207b202e2e207d203d20676f7665726e616e63655f616374696f6e00161533018491276578706563742072657475726e5f61646472657373203d3d20536372697074286e756c6c323829001615330184911b657870656374206465706f736974203d3d20325f3030305f3030300016301c301d002301b001301b0013016375400201e6030603200260286ea8008034c04c008c04400402cc050004dd59809980a180a180a180a180a180a180a180a180a18081baa3003301037540086e1d208092f401375860226024602460246024602460246024602460246024602460246024601c6ea8c004c038dd5001118088008a4c2a660169211856616c696461746f722072657475726e65642066616c73650013656004370e90000018018018018018a99803a4813f6578706563742054726561737572795769746864726177616c207b2067756172647261696c733a20536f6d65282e2e292c202e2e207d203d20616374696f6e001615330064910b5f746d70313a20566f6964001615330054918d657870656374205b0a20202020506169722850726f706f7365280a202020202020332c0a20202020202050726f706f73616c50726f636564757265207b206465706f7369742c2072657475726e5f616464726573732c20676f7665726e616e63655f616374696f6e207d2c0a20202020292c0a2020202064617461292c0a20205d203d2072656465656d657273001615330044911265787065637420566f6964203d2064617461001615330034912265787065637420536f6d652870726f63656475726529203d2070726f63656475726500161533002491256578706563742070726f6365647572652e6465706f736974203d3d20325f3030305f30303000165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "60f0f27c1b8abf91b947b4eec7a9ae1741cc7065ad778c2bfb4ec44d" + "compiledCode": "590cb00101003232323232323232323232323232253330073232323232533300c3370e900518071baa00113232323232323232323232323232323232323232323232324a264a666048602a604c6ea80044c94ccc094c04cdd6980718141baa001153330253375e601a60506ea800530122d8799f581c00000000000000000000000000000000000000000000000000000000ff00153330253375e601860506ea8005300103d87f8000149854cc0992412e6578706563742070726f6365647572652e676f7665726e616e63655f616374696f6e203d3d204e696365506f6c6c001615330264913a6578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20566572696669636174696f6e4b6579286e756c6c3238290016024302a302737540020446601a02490081980419806008a401c4a66604666ebd30012dd87e9fd87a80d8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00001149854cc0912401996578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a20536f6d65286e756c6c323829207d2c0a202020202020202020207d203d3d20616374696f6e0016330073300b0104803094ccc088cdd7a6010ed87e9fd87a80d8799fd87a80ffff00001149854cc08d2401916578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a204e6f6e65207d2c0a202020202020202020207d203d3d20616374696f6e0016330063300a00f480288c94ccc088c04cc090dd50008a99981119baf3374a900419813a6103d87a8000330274c1249fd8799f581c00000000000000000000000000000000000000000000000000000000ffff00330274c126a1d8799f581c00000000000000000000000000000000000000000000000000000000ff1901f4003302730283025375400297ae0002149854cc08d241e96578706563740a20202020202020202020436f6e737469747574696f6e616c436f6d6d6974746565207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020657669637465645f6d656d626572733a205b566572696669636174696f6e4b6579286e756c6c3238295d2c0a20202020202020202020202061646465645f6d656d626572733a205b5061697228566572696669636174696f6e4b6579286e756c6c3238292c20353030295d2c0a20202020202020202020202071756f72756d2c0a202020202020202020207d203d3d20616374696f6e001615330234912865787065637420536f6d652871756f72756d29203d20726174696f6e616c2e6e657728312c203229001653330214a0298103d87a8000153330214a02601a6604c601a6604c6ea120013302637509001a5eb812f5c02601a6604c601a6604c981010100330264c10102004bd7025eb80cc014cc0240392008253330203375e98107d87c9fd87a80ff00001149854cc085240130657870656374204e6f436f6e666964656e6365207b20616e636573746f723a204e6f6e65207d203d3d20616374696f6e0016330043300800d4801894ccc07ccdc3a400860426ea800454ccc07cc040c084dd51812981318111baa0011498068068cc00ccc01c03120042533301e3375e98012fd87b9fa1d8799f581c11111111111111111111111111111111111111111111111111111111ff1a000f4240d87a80ff00001149854cc07d2401ff6578706563740a2020202020202020202054726561737572795769746864726177616c207b0a20202020202020202020202062656e656669636961726965733a205b0a202020202020202020202020202050616972280a20202020202020202020202020202020566572696669636174696f6e4b6579280a20202020202020202020202020202020202023223131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131222c0a20202020202020202020202020202020292c0a20202020202020202020202020202020315f3030305f3030302c0a202020202020202020204920202020292c0a2020202020202020202020205d2c0a20202020202020202020202067756172647261696c733a204e6f6e652c0a202020202020202020207d203d3d20616374696f6e0016330023300600b4800894ccc074cdd7a60135d87a9fd8799fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8799f0b00ffff00001149854cc07924019d6578706563740a2020202020202020202048617264466f726b207b0a202020202020202020202020616e636573746f723a20536f6d6528476f7665726e616e6365416374696f6e4964286e756c6c33322c203029292c0a2020202020202020202020206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831312c2030292c0a202020202020202020207d203d3d20616374696f6e0016330013300500a4800094ccc070cdd7a6010dd87a9fd87a80d8799f0a00ffff00001149854cc07524015b6578706563740a2020202020202020202048617264466f726b207b20616e636573746f723a204e6f6e652c206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831302c203029207d203d3d20616374696f6e001622533301c300d301e3754004264a66603a60166eb4c018c080dd50008a99980e99baf300530203754002980122d87a9f581c00000000000000000000000000000000000000000000000000000000ff00130023004302037540022a6603c921316578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20536372697074286e756c6c323829001601c3022301f375400403446040604260420024603e60400024603c0026002002444a6660380042980103d87a800013232533301a300b003130063301f0024bd70099980280280099b8000348004c08000cc078008dd2a400064a666030002020264a666032603800426464a66602e66e1d200a3019375400426464a66603266e1d2006375a603e004264646464a66603a60166eb4c08c01054ccc074cdd780126122d87a9f581c00000000000000000000000000000000000000000000000000000000ff001533301d3370e9002180f9baa001153333330250071533301d300e301f375400e2a66604260406ea801c52601a01a01a01a01a01a153301e4901346578706563742054726561737572795769746864726177616c207b202e2e207d203d20676f7665726e616e63655f616374696f6e0016153301e491276578706563742072657475726e5f61646472657373203d3d20536372697074286e756c6c3238290016153301e4911b657870656374206465706f736974203d3d20325f3030305f30303000163022302300230210013021001301c375400202a603c603e00260346ea800804cc064008c05c004044c068004dd5980c980d180d180d180d180d180d180d180d180d180b1baa00b370e9040497a009bac3017301830183018301830183018301830183018301830183018301830143754012a666020600260246ea801854ccc050c04cdd50030a4c2c2c6e1d200030143015002375a6026002601e6ea800458c044c048008c040004c040008c038004c028dd50008a4c2a660109211856616c696461746f722072657475726e65642066616c73650013656153300649013f6578706563742054726561737572795769746864726177616c207b2067756172647261696c733a20536f6d65282e2e292c202e2e207d203d20616374696f6e001615330054918d657870656374205b0a20202020506169722850726f706f7365280a202020202020332c0a20202020202050726f706f73616c50726f636564757265207b206465706f7369742c2072657475726e5f616464726573732c20676f7665726e616e63655f616374696f6e207d2c0a20202020292c0a2020202064617461292c0a20205d203d2072656465656d657273001615330044911265787065637420566f6964203d2064617461001615330034912265787065637420536f6d652870726f63656475726529203d2070726f63656475726500161533002491256578706563742070726f6365647572652e6465706f736974203d3d20325f3030305f30303000165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "83a4d8791f26b72e8f7d370eaff68f9306b1423712dd464412d1cfab" }, { - "title": "proposing_pparams.guardrails", + "title": "proposing_all.guardrails.else", + "compiledCode": "590cb00101003232323232323232323232323232253330073232323232533300c3370e900518071baa00113232323232323232323232323232323232323232323232324a264a666048602a604c6ea80044c94ccc094c04cdd6980718141baa001153330253375e601a60506ea800530122d8799f581c00000000000000000000000000000000000000000000000000000000ff00153330253375e601860506ea8005300103d87f8000149854cc0992412e6578706563742070726f6365647572652e676f7665726e616e63655f616374696f6e203d3d204e696365506f6c6c001615330264913a6578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20566572696669636174696f6e4b6579286e756c6c3238290016024302a302737540020446601a02490081980419806008a401c4a66604666ebd30012dd87e9fd87a80d8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffff00001149854cc0912401996578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a20536f6d65286e756c6c323829207d2c0a202020202020202020207d203d3d20616374696f6e0016330073300b0104803094ccc088cdd7a6010ed87e9fd87a80d8799fd87a80ffff00001149854cc08d2401916578706563740a202020202020202020204e6577436f6e737469747574696f6e207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020636f6e737469747574696f6e3a20436f6e737469747574696f6e207b2067756172647261696c733a204e6f6e65207d2c0a202020202020202020207d203d3d20616374696f6e0016330063300a00f480288c94ccc088c04cc090dd50008a99981119baf3374a900419813a6103d87a8000330274c1249fd8799f581c00000000000000000000000000000000000000000000000000000000ffff00330274c126a1d8799f581c00000000000000000000000000000000000000000000000000000000ff1901f4003302730283025375400297ae0002149854cc08d241e96578706563740a20202020202020202020436f6e737469747574696f6e616c436f6d6d6974746565207b0a202020202020202020202020616e636573746f723a204e6f6e652c0a202020202020202020202020657669637465645f6d656d626572733a205b566572696669636174696f6e4b6579286e756c6c3238295d2c0a20202020202020202020202061646465645f6d656d626572733a205b5061697228566572696669636174696f6e4b6579286e756c6c3238292c20353030295d2c0a20202020202020202020202071756f72756d2c0a202020202020202020207d203d3d20616374696f6e001615330234912865787065637420536f6d652871756f72756d29203d20726174696f6e616c2e6e657728312c203229001653330214a0298103d87a8000153330214a02601a6604c601a6604c6ea120013302637509001a5eb812f5c02601a6604c601a6604c981010100330264c10102004bd7025eb80cc014cc0240392008253330203375e98107d87c9fd87a80ff00001149854cc085240130657870656374204e6f436f6e666964656e6365207b20616e636573746f723a204e6f6e65207d203d3d20616374696f6e0016330043300800d4801894ccc07ccdc3a400860426ea800454ccc07cc040c084dd51812981318111baa0011498068068cc00ccc01c03120042533301e3375e98012fd87b9fa1d8799f581c11111111111111111111111111111111111111111111111111111111ff1a000f4240d87a80ff00001149854cc07d2401ff6578706563740a2020202020202020202054726561737572795769746864726177616c207b0a20202020202020202020202062656e656669636961726965733a205b0a202020202020202020202020202050616972280a20202020202020202020202020202020566572696669636174696f6e4b6579280a20202020202020202020202020202020202023223131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131222c0a20202020202020202020202020202020292c0a20202020202020202020202020202020315f3030305f3030302c0a202020202020202020204920202020292c0a2020202020202020202020205d2c0a20202020202020202020202067756172647261696c733a204e6f6e652c0a202020202020202020207d203d3d20616374696f6e0016330023300600b4800894ccc074cdd7a60135d87a9fd8799fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8799f0b00ffff00001149854cc07924019d6578706563740a2020202020202020202048617264466f726b207b0a202020202020202020202020616e636573746f723a20536f6d6528476f7665726e616e6365416374696f6e4964286e756c6c33322c203029292c0a2020202020202020202020206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831312c2030292c0a202020202020202020207d203d3d20616374696f6e0016330013300500a4800094ccc070cdd7a6010dd87a9fd87a80d8799f0a00ffff00001149854cc07524015b6578706563740a2020202020202020202048617264466f726b207b20616e636573746f723a204e6f6e652c206e65775f76657273696f6e3a2050726f746f636f6c56657273696f6e2831302c203029207d203d3d20616374696f6e001622533301c300d301e3754004264a66603a60166eb4c018c080dd50008a99980e99baf300530203754002980122d87a9f581c00000000000000000000000000000000000000000000000000000000ff00130023004302037540022a6603c921316578706563742070726f6365647572652e72657475726e5f61646472657373203d3d20536372697074286e756c6c323829001601c3022301f375400403446040604260420024603e60400024603c0026002002444a6660380042980103d87a800013232533301a300b003130063301f0024bd70099980280280099b8000348004c08000cc078008dd2a400064a666030002020264a666032603800426464a66602e66e1d200a3019375400426464a66603266e1d2006375a603e004264646464a66603a60166eb4c08c01054ccc074cdd780126122d87a9f581c00000000000000000000000000000000000000000000000000000000ff001533301d3370e9002180f9baa001153333330250071533301d300e301f375400e2a66604260406ea801c52601a01a01a01a01a01a153301e4901346578706563742054726561737572795769746864726177616c207b202e2e207d203d20676f7665726e616e63655f616374696f6e0016153301e491276578706563742072657475726e5f61646472657373203d3d20536372697074286e756c6c3238290016153301e4911b657870656374206465706f736974203d3d20325f3030305f30303000163022302300230210013021001301c375400202a603c603e00260346ea800804cc064008c05c004044c068004dd5980c980d180d180d180d180d180d180d180d180d180b1baa00b370e9040497a009bac3017301830183018301830183018301830183018301830183018301830143754012a666020600260246ea801854ccc050c04cdd50030a4c2c2c6e1d200030143015002375a6026002601e6ea800458c044c048008c040004c040008c038004c028dd50008a4c2a660109211856616c696461746f722072657475726e65642066616c73650013656153300649013f6578706563742054726561737572795769746864726177616c207b2067756172647261696c733a20536f6d65282e2e292c202e2e207d203d20616374696f6e001615330054918d657870656374205b0a20202020506169722850726f706f7365280a202020202020332c0a20202020202050726f706f73616c50726f636564757265207b206465706f7369742c2072657475726e5f616464726573732c20676f7665726e616e63655f616374696f6e207d2c0a20202020292c0a2020202064617461292c0a20205d203d2072656465656d657273001615330044911265787065637420566f6964203d2064617461001615330034912265787065637420536f6d652870726f63656475726529203d2070726f63656475726500161533002491256578706563742070726f6365647572652e6465706f736974203d3d20325f3030305f30303000165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "83a4d8791f26b72e8f7d370eaff68f9306b1423712dd464412d1cfab" + }, + { + "title": "proposing_pparams.guardrails.propose", "redeemer": { - "title": "_tmp1", + "title": "_redeemer", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "591ad601010032323232323232323232323232323232323225333333013001153323300c3001300e37540042a666020601e6ea8008494ccc034c94ccc038cdc3a401460206ea80044c8c94ccc040c014dd6980b0010992999808980318099baa00113232323253330153370e9001180b9baa301b00415333015300a301737540022646464a66603066ebcccc00801520000014c106d8799f182cff00153330183375e66600400a9001000a6109d8799f1a00025ef5ff00153330183375e66600400a9002000a6109d8799f1a00016000ff00153330183375e66600400a9003000a6107d8799f194000ff00153330183375e66600400a9004000a6107d8799f19044cff00153330183375e66600400a9005000a6109d8799f1a001e8480ff00153330183375e66600400a9006000a6109d8799f1a1dcd6500ff00153330183375e66600400a9007000a6105d8799f12ff00153330183375e66600400a9008000a6107d8799f1901f4ff0013232323232533301d3375e666004014900900098041981119801a400c900a25eb8054ccc074cdd799980100524028002601066044660069003241a01e97ae01533301d3375e666004014900b00098041981119801a4004900525eb8054ccc074cdd79998038052404000c980107d8799f190154ff001533301d3375e66600e014901100326107d8799f1910d6ff001533301d3375e66600401490121000a60103d87a80001533301d3375e66600401490131299999981300080e80e899299981180080f0991929998128008100992999813181480109806998139803001998139803000a5eb80084c09c004c09c008c094004dd600080e80e98041981118041981119801a4104129068079981119801a414416904044bd25eb812f5c0264a66603c66ebcccc00c02d20280014c116d8799fd8799f1a00d59f801b00000002540be400ffff001533301e3375e6660060169015000a6116d8799fd8799f1a03b20b801b00000004a817c800ffff001533301e3375e6660100169016003a6107d8799f191388ff001533301e3375e6660100169017003a6106d8799f1896ff001533301e3375e6660100169018003a6105d8799f03ff001533301e3375e66600601690191299999981380080e00e099299981200080e89919299981300080f899192999814000810899192999815000811899192999816000812899299981698180010980a19817180680499817180a198171806803998171806802a5eb80cc0b8c03400ccc0b8c050cc0b8c034004cc0b930103d87980003302e4c103d87980003302e4c103d87980003302e4c103d87980004bd7025eb80098c0b8004c0b8008c0b0004c0b0008c0a8004c0a8008c0a0004c0a0008c098004dd600080e00e26141d8799fd8799fd8799f18331864ffd8799fd8799f0d1819ffd8799f18351864ffffd8799f181b1832ffd8799fd8799f0b14ffd87980d87980d87980d87980ffffff001533301e3375e646464646464666012022901a129981319b964901186472657020766f74696e67207468726573686f6c64733a20003732660040029101001533333302d001021021132533302a00102213232533302c00102413232533302e00102613232533303000102813232533303200102a13232533303400102c13232533303600102e13232533303800103013232533303a00103213232533303c001034132533303d3040002130243303e301d0133303e30243303e301d0113303e301d00f4bd701981f180e8069981f180e8059981f18121981f260103d87980003303e301d0093303e301d0073303e301d0053303e301d0034bd701981f180e800a5eb800d4c0f8004c0f8008c0f0004c0f0008c0e8004c0e8008c0e0004c0e0008c0d8004c0d8008c0d0004c0d0008c0c8004c0c8008c0c0004c0c0008c0b8004c0b8008c0b0004dd6000810810980080091129999199981700189919191919191980600100099b8a489012800002533302a337100069007099b80483c80400c54ccc0a8cdc4001a410004266e00cdc0241002800690068b2999816800899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d290000522333009009002300600122333009009002001375860560046eb4c0a4004c8cdd81ba83029001374e60540026ea800c4c94ccc0ac0044cdc52441027b7d00003133714911037b5f200032323300100100322533302e00110031533302e3031001132333009009302d001337149101023a2000333009009302e0010043030001132333009009302d001337149101023a2000333009009302e001300633003003303200230300013371491102207d000033756006264a666056002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001337006e3400920013371491101270000322253330293371000490000800899191919980300319b8000548004cdc599b80002533302c33710004900a0a40c02903719b8b33700002a66605866e2000520141481805206e0043370c004901019b8300148080cdc70020011bae0022222323300100100522533302b00110051533302b302e001133003302d001005133004302d00133002002302e001223233001001003225333024301900113371491101300000315333024337100029000099b8a489012d0033002002300c00113300533708002900a19b8b3370066e1400520144818000cc0040048894ccc084cdc4801240002002266600600666e1000920143371666e00cdc2801240289030000a615bd8799fd8799fd8799f18431864ffd8799fd8799f18431864ffd8799f0305ffffd8799f0304ffd8799f0305ffd8799fd87980d8799f18431864ffd8799f18431864ffd8799f18431864ffd8799f0304ffffd8799f18431864ffffff001533301e3375e666010016901b003a6105d8799f07ff001533301e3375e666010016901c003a6106d8799f1892ff001533301e3375e666010016901d003a6105d8799f06ff001533301e3375e666010016901e003a610dd8799f1b000000174876e800ff001533301e3375e666010016901f003a6109d8799f1a1dcd6500ff001533301e3375e6660100169020003a6105d8799f14ff001533301e3375e6660060169021001180499811998022403c900125eb805288a9980fa4817d6578706563740a20202020202028206e65775f706172616d6574657273207c3e207265666572656e63655f736372697074735f746965725f6665655f696e697469616c5f666163746f722029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c2831352c2031292c0a202020202020290016153301f491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6d61785f69646c655f74696d652029203d3d20536f6d65283230290016153301f491576578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6465706f7369742029203d3d20536f6d65283530305f3030305f303030290016153301f491576578706563740a20202020202028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6465706f7369742029203d3d20536f6d65283130305f3030305f3030305f303030290016153301f491446578706563742028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6c69666574696d652029203d3d20536f6d652836290016153301f491546578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f636f6e737469747574696f6e616c5f636f6d6d69747465655f6d616e646174652029203d3d20536f6d6528313436290016153301f491496578706563742028206e65775f706172616d6574657273207c3e206d696e5f636f6e737469747574696f6e616c5f636f6d6d69747465655f73697a652029203d3d20536f6d652837290016153301f491786578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a2020202020202020647265705f7468726573686f6c647328292c0a202020202020290016153301f491736578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6f70657261746f725f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a202020202020202073706f5f7468726573686f6c647328292c0a202020202020290016153301f4913d6578706563742028206e65775f706172616d6574657273207c3e206d61785f636f6c6c61746572616c5f696e707574732029203d3d20536f6d652833290016153301f4913f6578706563742028206e65775f706172616d6574657273207c3e20636f6c6c61746572616c5f70657263656e746167652029203d3d20536f6d6528313530290016153301f491396578706563742028206e65775f706172616d6574657273207c3e206d61785f76616c75655f73697a652029203d3d20536f6d652835303030290016153301f4918c6578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2036323030303030302c206370753a203230303030303030303030207d2c0a202020202020290016153301f491926578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2031343030303030302c206370753a203130303030303030303030207d2c0a2020202020202900162533333302600101c01c132533302300101d132533333302800101e01e01e132325333026001020132533333302b0010210210211325333028302b0031300f330293750008660526ea00052f5c00446eb4004084c0a0004c0a000cdd680080f18128009bac00101c01c153301e4901d56578706563740a20202020202028206e65775f706172616d6574657273207c3e207363726970745f657865637574696f6e5f7072696365732029203d3d20536f6d65280a2020202020202020536372697074457865637574696f6e507269636573207b0a202020202020202020206d656d6f72793a206578706563745f726174696f6e616c283537372c20315f303030292c0a202020202020202020206370753a206578706563745f726174696f6e616c283732312c20315f3030305f303030292c0a20202020202020207d2c0a202020202020290016153301e491306578706563742028206e65775f706172616d6574657273207c3e20636f73745f6d6f64656c732029203d3d204e6f6e650016153301e491476578706563742028206e65775f706172616d6574657273207c3e206d696e5f7574786f5f6465706f7369745f636f656666696369656e742029203d3d20536f6d652834333130290016153301e4913d6578706563742028206e65775f706172616d6574657273207c3e206d696e5f7374616b655f706f6f6c5f636f73742029203d3d20536f6d6528333430290016153301e491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2074726561737572795f657870616e73696f6e2029203d3d20536f6d65286578706563745f726174696f6e616c28312c203529290016153301e491696578706563740a20202020202028206e65775f706172616d6574657273207c3e206d6f6e65746172795f657870616e73696f6e2029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c20315f303030292c0a202020202020290016153301e4916f6578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f706c656467655f696e666c75656e63652029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c203130292c0a202020202020290016253333330250010170171325333022001018132533333302700101901901913232533302500101b132533333302a00101c01c01c1325333027302a003132533302430193026375400226054604e6ea8004074cc028010004074dd680080e181380098138019bad0010193024001375800202e02e444646600200200844a666048002298103d87a8000132323253330233370e00e6eb4c09400c4c038cc0a0c0180052f5c026600a00a004604a0046050004604c0024464a66603a6024603e6ea80044c08cc080dd500080b1980180100091299980d98080008a60103d87a80001533301b33710002900009803198101803198101ba83003002330203750600600297ae04bd7009803198101803198101ba800233020375000297ae04bd701b814800054cc0652401476578706563742028206e65775f706172616d6574657273207c3e20646573697265645f6e756d6265725f6f665f7374616b655f706f6f6c732029203d3d20536f6d65283530302900161533019491466578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f7265746972656d656e745f686f72697a6f6e2029203d3d20536f6d652831382900161533019491446578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6465706f7369742029203d3d20536f6d65283530305f3030305f3030302900161533019491486578706563742028206e65775f706172616d6574657273207c3e207374616b655f63726564656e7469616c5f6465706f7369742029203d3d20536f6d6528325f3030305f3030302900161533019491416578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f6865616465725f73697a652029203d3d20536f6d6528315f3130302900161533019491416578706563742028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f73697a652029203d3d20536f6d652831365f3338342900161533019491406578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f626f64795f73697a652029203d3d20536f6d652839305f31313229001615330194913e6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f6e7374616e742029203d3d20536f6d65283135355f33383129001615330194913c6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f656666696369656e742029203d3d20536f6d65283434290016253333330200010130130131375a002026444646600200200844a66603e002298103d87a80001323232533301e3370e00e6eb4c08000c4c024cc08cdd41803000a5eb804cc014014008c080008c08c008c084004dd2a4000018018603460360046eacc064004c064004c050dd5000804180b180b980b98099baa001007301530160013011375400200a60266028602860206ea8004526153300e49011856616c696461746f722072657475726e65642066616c73650013656004370e90000018018018018018a998052481e86578706563742050726f706f73696e67280a202020202020302c0a20202020202050726f706f73616c50726f636564757265207b0a2020202020202020676f7665726e616e63655f616374696f6e3a2050726f746f636f6c506172616d6574657273207b0a20202020202020202020616e636573746f723a204e6f6e652c0a2020202020202020202067756172647261696c733a20536f6d65282e2e292c0a202020202020202020206e65775f706172616d65746572732c0a20202020202020207d2c0a20202020202020202e2e0a2020202020207d2c0a2020202029203d206374782e696e666f001615330094910b5f746d70313a20566f6964001615330084913565787065637420536f6d65287229203d20726174696f6e616c2e6e6577286e756d657261746f722c2064656e6f6d696e61746f72290016153300749132657870656374205b6e756d657261746f722c2064656e6f6d696e61746f725d3a204c6973743c496e743e203d20706172616d001615330064911965787065637420706172616d3a20496e74203d20706172616d00161533005491ff657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e2c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f6e6574776f726b5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f65636f6e6f6d69635f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f746a6563686e6963616c5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f676f7665726e616e63655f67726f75702c0a2020202074726561737572795f7769746864726177616c2c0a20205d3a204c6973743c446174613e203d20706172616d00161533004491c4657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f73656375726974795f67726f75702c0a20205d3a204c6973743c446174613e203d20706172616d0016153300349127657870656374205b6d656d6f72792c206370755d3a204c6973743c496e743e203d20706172616d0016153300249128657870656374205b6d656d6f72792c206370755d3a204c6973743c446174613e203d20706172616d00165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "d0c1c15d5bbd5711902cc8ab659d1ee3af41e44bb7ece80cd9225b48" + "compiledCode": "591a8c01010032323232323232323232323232323232322533300a3232323232533300f3370e900518089baa001132323232325333014300330163754002264646464a66603066e1d2002301a3754603c0082a666030600e60346ea80044c8c8c94ccc06ccdd7999801002a4000002980106d8799f182cff001533301b3375e66600400a9001000a6109d8799f1a00025ef5ff001533301b3375e66600400a9002000a6109d8799f1a00016000ff001533301b3375e66600400a9003000a6107d8799f194000ff001533301b3375e66600400a9004000a6107d8799f19044cff001533301b3375e66600400a9005000a6109d8799f1a001e8480ff001533301b3375e66600400a9006000a6109d8799f1a1dcd6500ff001533301b3375e66600400a9007000a6105d8799f12ff001533301b3375e66600400a9008000a6107d8799f1901f4ff001323232323253330203375e666004014900900098041981299801a400c900a25eb8054ccc080cdd79998010052402800260106604a660069003241a01e97ae0153330203375e666004014900b00098041981299801a4004900525eb8054ccc080cdd79998038052404000c980107d8799f190154ff00153330203375e66600e014901100326107d8799f1910d6ff00153330203375e66600401490121000a60103d87a8000153330203375e66600401490131299999981480081001009929998130008108991929998140008118992999814981600109806998151803001998151803000a5eb80090c0a8004c0a8008c0a0004dd600081001018041981298041981299801a4104129068079981299801a414416904044bd25eb812f5c0264a66604266ebcccc00c02d20280014c116d8799fd8799f1a00d59f801b00000002540be400ffff00153330213375e6660060169015000a6116d8799fd8799f1a03b20b801b00000004a817c800ffff00153330213375e6660100169016003a6107d8799f191388ff00153330213375e6660100169017003a6106d8799f1896ff00153330213375e6660100169018003a6105d8799f03ff00153330213375e66600601690191299999981500080f80f8992999813800810099192999814800811099192999815800812099192999816800813099192999817800814099299981818198010980a19818980680499818980a198189806803998189806802a5eb80cc0c4c03400ccc0c4c050cc0c4c034004cc0c530103d8798000330314c103d8798000330314c103d8798000330314c103d87980004bd7025eb800a4c0c4004c0c4008c0bc004c0bc008c0b4004c0b4008c0ac004c0ac008c0a4004dd600080f80fa6141d8799fd8799fd8799f18331864ffd8799fd8799f0d1819ffd8799f18351864ffffd8799f181b1832ffd8799fd8799f0b14ffd87980d87980d87980d87980ffffff00153330213375e646464646464666012022901a129981499b964901186472657020766f74696e67207468726573686f6c64733a200037326600400291010015333333030001024024132533302d00102513232533302f00102713232533303100102913232533303300102b13232533303500102d13232533303700102f13232533303900103113232533303b00103313232533303d00103513232533303f001037132533304030430021302433041301d01333041302433041301d01133041301d00f4bd7019820980e80699820980e80599820981219820a60103d879800033041301d00933041301d00733041301d00533041301d0034bd7019820980e800a5eb800e0c104004c104008c0fc004c0fc008c0f4004c0f4008c0ec004c0ec008c0e4004c0e4008c0dc004c0dc008c0d4004c0d4008c0cc004c0cc008c0c4004c0c4008c0bc004dd6000812012180080091129999199981880189919191919191980600100099b8a489012800002533302d337100069007099b80483c80400c54ccc0b4cdc4001a410004266e00cdc0241002800690068b2999818000899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d2900005223330090090023006001223330090090020013758605c0046eb4c0b0004c8cdd81ba8302c001374e605a0026ea800c4c94ccc0b80044cdc52441027b7d00003133714911037b5f200032323300100100322533303100110031533303130340011323330090093030001337149101023a2000333009009303100100430330011323330090093030001337149101023a20003330090093031001300633003003303500230330013371491102207d000033756006264a66605c002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001337006e34009200133714911012700003222533302c3371000490000800899191919980300319b8000548004cdc599b80002533302f33710004900a0a40c02903719b8b33700002a66605e66e2000520141481805206e0043370c004901019b8300148080cdc70020011bae0022222323300100100522533302e00110051533302e303100113300330300010051330043030001330020023031001223233001001003225333027301600113371491101300000315333027337100029000099b8a489012d0033002002300c00113300533708002900a19b8b3370066e1400520144818000cc0040048894ccc090cdc4801240002002266600600666e1000920143371666e00cdc2801240289030000a615bd8799fd8799fd8799f18431864ffd8799fd8799f18431864ffd8799f0305ffffd8799f0304ffd8799f0305ffd8799fd87980d8799f18431864ffd8799f18431864ffd8799f18431864ffd8799f0304ffffd8799f18431864ffffff00153330213375e666010016901b003a6105d8799f07ff00153330213375e666010016901c003a6106d8799f1892ff00153330213375e666010016901d003a6105d8799f06ff00153330213375e666010016901e003a610dd8799f1b000000174876e800ff00153330213375e666010016901f003a6109d8799f1a1dcd6500ff00153330213375e6660100169020003a6105d8799f14ff00153330213375e6660060169021001180499813198022403c900125eb805288a9981124817d6578706563740a20202020202028206e65775f706172616d6574657273207c3e207265666572656e63655f736372697074735f746965725f6665655f696e697469616c5f666163746f722029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c2831352c2031292c0a2020202020202900161533022491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6d61785f69646c655f74696d652029203d3d20536f6d652832302900161533022491576578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6465706f7369742029203d3d20536f6d65283530305f3030305f3030302900161533022491576578706563740a20202020202028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6465706f7369742029203d3d20536f6d65283130305f3030305f3030305f3030302900161533022491446578706563742028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6c69666574696d652029203d3d20536f6d6528362900161533022491546578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f636f6e737469747574696f6e616c5f636f6d6d69747465655f6d616e646174652029203d3d20536f6d65283134362900161533022491496578706563742028206e65775f706172616d6574657273207c3e206d696e5f636f6e737469747574696f6e616c5f636f6d6d69747465655f73697a652029203d3d20536f6d6528372900161533022491786578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a2020202020202020647265705f7468726573686f6c647328292c0a2020202020202900161533022491736578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6f70657261746f725f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a202020202020202073706f5f7468726573686f6c647328292c0a20202020202029001615330224913d6578706563742028206e65775f706172616d6574657273207c3e206d61785f636f6c6c61746572616c5f696e707574732029203d3d20536f6d65283329001615330224913f6578706563742028206e65775f706172616d6574657273207c3e20636f6c6c61746572616c5f70657263656e746167652029203d3d20536f6d65283135302900161533022491396578706563742028206e65775f706172616d6574657273207c3e206d61785f76616c75655f73697a652029203d3d20536f6d65283530303029001615330224918c6578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2036323030303030302c206370753a203230303030303030303030207d2c0a2020202020202900161533022491926578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2031343030303030302c206370753a203130303030303030303030207d2c0a2020202020202900162533333302900101f01f1325333026001020132533333302b001021021021132325333029001023132533333302e001024024024132533302b302e0031300f3302c3750008660586ea00052f5c004a6eb4004090c0ac004c0ac00cdd680081098140009bac00101f01f15330214901d56578706563740a20202020202028206e65775f706172616d6574657273207c3e207363726970745f657865637574696f6e5f7072696365732029203d3d20536f6d65280a2020202020202020536372697074457865637574696f6e507269636573207b0a202020202020202020206d656d6f72793a206578706563745f726174696f6e616c283537372c20315f303030292c0a202020202020202020206370753a206578706563745f726174696f6e616c283732312c20315f3030305f303030292c0a20202020202020207d2c0a2020202020202900161533021491306578706563742028206e65775f706172616d6574657273207c3e20636f73745f6d6f64656c732029203d3d204e6f6e6500161533021491476578706563742028206e65775f706172616d6574657273207c3e206d696e5f7574786f5f6465706f7369745f636f656666696369656e742029203d3d20536f6d65283433313029001615330214913d6578706563742028206e65775f706172616d6574657273207c3e206d696e5f7374616b655f706f6f6c5f636f73742029203d3d20536f6d65283334302900161533021491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2074726561737572795f657870616e73696f6e2029203d3d20536f6d65286578706563745f726174696f6e616c28312c2035292900161533021491696578706563740a20202020202028206e65775f706172616d6574657273207c3e206d6f6e65746172795f657870616e73696f6e2029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c20315f303030292c0a20202020202029001615330214916f6578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f706c656467655f696e666c75656e63652029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c203130292c0a2020202020202900162533333302800101a01a132533302500101b132533333302a00101c01c01c13232533302800101e132533333302d00101f01f01f132533302a302d00313253330273016302937540022605a60546ea8004080cc028010004080dd680080f981500098150019bad00101c30270013758002034034444646600200200844a66604e002298103d87a8000132323253330263370e00e6eb4c0a000c4c038cc0acc0180052f5c026600a00a0046050004605600460520024464a666040601e60446ea80044c098c08cdd500080c9980180100091299980f18068008a60103d87a80001533301e33710002900009803198119803198119ba83003002330233750600600297ae04bd7009803198119803198119ba800233023375000297ae04bd701b814800054cc0712401476578706563742028206e65775f706172616d6574657273207c3e20646573697265645f6e756d6265725f6f665f7374616b655f706f6f6c732029203d3d20536f6d6528353030290016153301c491466578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f7265746972656d656e745f686f72697a6f6e2029203d3d20536f6d65283138290016153301c491446578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6465706f7369742029203d3d20536f6d65283530305f3030305f303030290016153301c491486578706563742028206e65775f706172616d6574657273207c3e207374616b655f63726564656e7469616c5f6465706f7369742029203d3d20536f6d6528325f3030305f303030290016153301c491416578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f6865616465725f73697a652029203d3d20536f6d6528315f313030290016153301c491416578706563742028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f73697a652029203d3d20536f6d652831365f333834290016153301c491406578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f626f64795f73697a652029203d3d20536f6d652839305f313132290016153301c4913e6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f6e7374616e742029203d3d20536f6d65283135355f333831290016153301c4913c6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f656666696369656e742029203d3d20536f6d65283434290016253333330230010160160161375a00202c444646600200200844a666044002298103d87a8000132323253330213370e00e6eb4c08c00c4c024cc098dd41803000a5eb804cc014014008c08c008c098008c090004dd2a4000020020603a603c0046eacc070004c070004c05cdd5000806180c980d180d180b1baa3019301a004533301230013014375400a2a66602c602a6ea80145261616370e90001bad3016001301237540022c6028602a004602600260260046022002601a6ea8004526153300b49011856616c696461746f722072657475726e65642066616c7365001365615330094901b96578706563742050726f706f73616c50726f636564757265207b0a202020202020676f7665726e616e63655f616374696f6e3a2050726f746f636f6c506172616d6574657273207b0a2020202020202020616e636573746f723a204e6f6e652c0a202020202020202067756172647261696c733a20536f6d65282e2e292c0a20202020202020206e65775f706172616d65746572732c0a2020202020207d2c0a2020202020202e2e0a202020207d203d2070726f706f73616c001615330084913565787065637420536f6d65287229203d20726174696f6e616c2e6e6577286e756d657261746f722c2064656e6f6d696e61746f72290016153300749132657870656374205b6e756d657261746f722c2064656e6f6d696e61746f725d3a204c6973743c496e743e203d20706172616d001615330064911965787065637420706172616d3a20496e74203d20706172616d00161533005491ff657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e2c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f6e6574776f726b5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f65636f6e6f6d69635f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f746a6563686e6963616c5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f676f7665726e616e63655f67726f75702c0a2020202074726561737572795f7769746864726177616c2c0a20205d3a204c6973743c446174613e203d20706172616d00161533004491c4657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f73656375726974795f67726f75702c0a20205d3a204c6973743c446174613e203d20706172616d0016153300349127657870656374205b6d656d6f72792c206370755d3a204c6973743c496e743e203d20706172616d0016153300249128657870656374205b6d656d6f72792c206370755d3a204c6973743c446174613e203d20706172616d00165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "628d246855dda6aef139c7a1bec7d37ff1db213bfd28d3ae9fd52300" }, { - "title": "simple_spend.spend", + "title": "proposing_pparams.guardrails.else", + "compiledCode": "591a8c01010032323232323232323232323232323232322533300a3232323232533300f3370e900518089baa001132323232325333014300330163754002264646464a66603066e1d2002301a3754603c0082a666030600e60346ea80044c8c8c94ccc06ccdd7999801002a4000002980106d8799f182cff001533301b3375e66600400a9001000a6109d8799f1a00025ef5ff001533301b3375e66600400a9002000a6109d8799f1a00016000ff001533301b3375e66600400a9003000a6107d8799f194000ff001533301b3375e66600400a9004000a6107d8799f19044cff001533301b3375e66600400a9005000a6109d8799f1a001e8480ff001533301b3375e66600400a9006000a6109d8799f1a1dcd6500ff001533301b3375e66600400a9007000a6105d8799f12ff001533301b3375e66600400a9008000a6107d8799f1901f4ff001323232323253330203375e666004014900900098041981299801a400c900a25eb8054ccc080cdd79998010052402800260106604a660069003241a01e97ae0153330203375e666004014900b00098041981299801a4004900525eb8054ccc080cdd79998038052404000c980107d8799f190154ff00153330203375e66600e014901100326107d8799f1910d6ff00153330203375e66600401490121000a60103d87a8000153330203375e66600401490131299999981480081001009929998130008108991929998140008118992999814981600109806998151803001998151803000a5eb80090c0a8004c0a8008c0a0004dd600081001018041981298041981299801a4104129068079981299801a414416904044bd25eb812f5c0264a66604266ebcccc00c02d20280014c116d8799fd8799f1a00d59f801b00000002540be400ffff00153330213375e6660060169015000a6116d8799fd8799f1a03b20b801b00000004a817c800ffff00153330213375e6660100169016003a6107d8799f191388ff00153330213375e6660100169017003a6106d8799f1896ff00153330213375e6660100169018003a6105d8799f03ff00153330213375e66600601690191299999981500080f80f8992999813800810099192999814800811099192999815800812099192999816800813099192999817800814099299981818198010980a19818980680499818980a198189806803998189806802a5eb80cc0c4c03400ccc0c4c050cc0c4c034004cc0c530103d8798000330314c103d8798000330314c103d8798000330314c103d87980004bd7025eb800a4c0c4004c0c4008c0bc004c0bc008c0b4004c0b4008c0ac004c0ac008c0a4004dd600080f80fa6141d8799fd8799fd8799f18331864ffd8799fd8799f0d1819ffd8799f18351864ffffd8799f181b1832ffd8799fd8799f0b14ffd87980d87980d87980d87980ffffff00153330213375e646464646464666012022901a129981499b964901186472657020766f74696e67207468726573686f6c64733a200037326600400291010015333333030001024024132533302d00102513232533302f00102713232533303100102913232533303300102b13232533303500102d13232533303700102f13232533303900103113232533303b00103313232533303d00103513232533303f001037132533304030430021302433041301d01333041302433041301d01133041301d00f4bd7019820980e80699820980e80599820981219820a60103d879800033041301d00933041301d00733041301d00533041301d0034bd7019820980e800a5eb800e0c104004c104008c0fc004c0fc008c0f4004c0f4008c0ec004c0ec008c0e4004c0e4008c0dc004c0dc008c0d4004c0d4008c0cc004c0cc008c0c4004c0c4008c0bc004dd6000812012180080091129999199981880189919191919191980600100099b8a489012800002533302d337100069007099b80483c80400c54ccc0b4cdc4001a410004266e00cdc0241002800690068b2999818000899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d2900005223330090090023006001223330090090020013758605c0046eb4c0b0004c8cdd81ba8302c001374e605a0026ea800c4c94ccc0b80044cdc52441027b7d00003133714911037b5f200032323300100100322533303100110031533303130340011323330090093030001337149101023a2000333009009303100100430330011323330090093030001337149101023a20003330090093031001300633003003303500230330013371491102207d000033756006264a66605c002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001337006e34009200133714911012700003222533302c3371000490000800899191919980300319b8000548004cdc599b80002533302f33710004900a0a40c02903719b8b33700002a66605e66e2000520141481805206e0043370c004901019b8300148080cdc70020011bae0022222323300100100522533302e00110051533302e303100113300330300010051330043030001330020023031001223233001001003225333027301600113371491101300000315333027337100029000099b8a489012d0033002002300c00113300533708002900a19b8b3370066e1400520144818000cc0040048894ccc090cdc4801240002002266600600666e1000920143371666e00cdc2801240289030000a615bd8799fd8799fd8799f18431864ffd8799fd8799f18431864ffd8799f0305ffffd8799f0304ffd8799f0305ffd8799fd87980d8799f18431864ffd8799f18431864ffd8799f18431864ffd8799f0304ffffd8799f18431864ffffff00153330213375e666010016901b003a6105d8799f07ff00153330213375e666010016901c003a6106d8799f1892ff00153330213375e666010016901d003a6105d8799f06ff00153330213375e666010016901e003a610dd8799f1b000000174876e800ff00153330213375e666010016901f003a6109d8799f1a1dcd6500ff00153330213375e6660100169020003a6105d8799f14ff00153330213375e6660060169021001180499813198022403c900125eb805288a9981124817d6578706563740a20202020202028206e65775f706172616d6574657273207c3e207265666572656e63655f736372697074735f746965725f6665655f696e697469616c5f666163746f722029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c2831352c2031292c0a2020202020202900161533022491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6d61785f69646c655f74696d652029203d3d20536f6d652832302900161533022491576578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f6465706f7369742029203d3d20536f6d65283530305f3030305f3030302900161533022491576578706563740a20202020202028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6465706f7369742029203d3d20536f6d65283130305f3030305f3030305f3030302900161533022491446578706563742028206e65775f706172616d6574657273207c3e20676f7665726e616e63655f70726f706f73616c5f6c69666574696d652029203d3d20536f6d6528362900161533022491546578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f636f6e737469747574696f6e616c5f636f6d6d69747465655f6d616e646174652029203d3d20536f6d65283134362900161533022491496578706563742028206e65775f706172616d6574657273207c3e206d696e5f636f6e737469747574696f6e616c5f636f6d6d69747465655f73697a652029203d3d20536f6d6528372900161533022491786578706563740a20202020202028206e65775f706172616d6574657273207c3e2064656c65676174655f726570726573656e7461746976655f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a2020202020202020647265705f7468726573686f6c647328292c0a2020202020202900161533022491736578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6f70657261746f725f766f74696e675f7468726573686f6c64732029203d3d20536f6d65280a202020202020202073706f5f7468726573686f6c647328292c0a20202020202029001615330224913d6578706563742028206e65775f706172616d6574657273207c3e206d61785f636f6c6c61746572616c5f696e707574732029203d3d20536f6d65283329001615330224913f6578706563742028206e65775f706172616d6574657273207c3e20636f6c6c61746572616c5f70657263656e746167652029203d3d20536f6d65283135302900161533022491396578706563742028206e65775f706172616d6574657273207c3e206d61785f76616c75655f73697a652029203d3d20536f6d65283530303029001615330224918c6578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2036323030303030302c206370753a203230303030303030303030207d2c0a2020202020202900161533022491926578706563740a20202020202028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f657865637574696f6e5f756e6974732029203d3d20536f6d65280a2020202020202020457865637574696f6e556e697473207b206d656d6f72793a2031343030303030302c206370753a203130303030303030303030207d2c0a2020202020202900162533333302900101f01f1325333026001020132533333302b001021021021132325333029001023132533333302e001024024024132533302b302e0031300f3302c3750008660586ea00052f5c004a6eb4004090c0ac004c0ac00cdd680081098140009bac00101f01f15330214901d56578706563740a20202020202028206e65775f706172616d6574657273207c3e207363726970745f657865637574696f6e5f7072696365732029203d3d20536f6d65280a2020202020202020536372697074457865637574696f6e507269636573207b0a202020202020202020206d656d6f72793a206578706563745f726174696f6e616c283537372c20315f303030292c0a202020202020202020206370753a206578706563745f726174696f6e616c283732312c20315f3030305f303030292c0a20202020202020207d2c0a2020202020202900161533021491306578706563742028206e65775f706172616d6574657273207c3e20636f73745f6d6f64656c732029203d3d204e6f6e6500161533021491476578706563742028206e65775f706172616d6574657273207c3e206d696e5f7574786f5f6465706f7369745f636f656666696369656e742029203d3d20536f6d65283433313029001615330214913d6578706563742028206e65775f706172616d6574657273207c3e206d696e5f7374616b655f706f6f6c5f636f73742029203d3d20536f6d65283334302900161533021491546578706563740a20202020202028206e65775f706172616d6574657273207c3e2074726561737572795f657870616e73696f6e2029203d3d20536f6d65286578706563745f726174696f6e616c28312c2035292900161533021491696578706563740a20202020202028206e65775f706172616d6574657273207c3e206d6f6e65746172795f657870616e73696f6e2029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c20315f303030292c0a20202020202029001615330214916f6578706563740a20202020202028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f706c656467655f696e666c75656e63652029203d3d20536f6d65280a20202020202020206578706563745f726174696f6e616c28332c203130292c0a2020202020202900162533333302800101a01a132533302500101b132533333302a00101c01c01c13232533302800101e132533333302d00101f01f01f132533302a302d00313253330273016302937540022605a60546ea8004080cc028010004080dd680080f981500098150019bad00101c30270013758002034034444646600200200844a66604e002298103d87a8000132323253330263370e00e6eb4c0a000c4c038cc0acc0180052f5c026600a00a0046050004605600460520024464a666040601e60446ea80044c098c08cdd500080c9980180100091299980f18068008a60103d87a80001533301e33710002900009803198119803198119ba83003002330233750600600297ae04bd7009803198119803198119ba800233023375000297ae04bd701b814800054cc0712401476578706563742028206e65775f706172616d6574657273207c3e20646573697265645f6e756d6265725f6f665f7374616b655f706f6f6c732029203d3d20536f6d6528353030290016153301c491466578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f7265746972656d656e745f686f72697a6f6e2029203d3d20536f6d65283138290016153301c491446578706563742028206e65775f706172616d6574657273207c3e207374616b655f706f6f6c5f6465706f7369742029203d3d20536f6d65283530305f3030305f303030290016153301c491486578706563742028206e65775f706172616d6574657273207c3e207374616b655f63726564656e7469616c5f6465706f7369742029203d3d20536f6d6528325f3030305f303030290016153301c491416578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f6865616465725f73697a652029203d3d20536f6d6528315f313030290016153301c491416578706563742028206e65775f706172616d6574657273207c3e206d61785f7472616e73616374696f6e5f73697a652029203d3d20536f6d652831365f333834290016153301c491406578706563742028206e65775f706172616d6574657273207c3e206d61785f626c6f636b5f626f64795f73697a652029203d3d20536f6d652839305f313132290016153301c4913e6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f6e7374616e742029203d3d20536f6d65283135355f333831290016153301c4913c6578706563742028206e65775f706172616d6574657273207c3e206d696e5f6665655f636f656666696369656e742029203d3d20536f6d65283434290016253333330230010160160161375a00202c444646600200200844a666044002298103d87a8000132323253330213370e00e6eb4c08c00c4c024cc098dd41803000a5eb804cc014014008c08c008c098008c090004dd2a4000020020603a603c0046eacc070004c070004c05cdd5000806180c980d180d180b1baa3019301a004533301230013014375400a2a66602c602a6ea80145261616370e90001bad3016001301237540022c6028602a004602600260260046022002601a6ea8004526153300b49011856616c696461746f722072657475726e65642066616c7365001365615330094901b96578706563742050726f706f73616c50726f636564757265207b0a202020202020676f7665726e616e63655f616374696f6e3a2050726f746f636f6c506172616d6574657273207b0a2020202020202020616e636573746f723a204e6f6e652c0a202020202020202067756172647261696c733a20536f6d65282e2e292c0a20202020202020206e65775f706172616d65746572732c0a2020202020207d2c0a2020202020202e2e0a202020207d203d2070726f706f73616c001615330084913565787065637420536f6d65287229203d20726174696f6e616c2e6e6577286e756d657261746f722c2064656e6f6d696e61746f72290016153300749132657870656374205b6e756d657261746f722c2064656e6f6d696e61746f725d3a204c6973743c496e743e203d20706172616d001615330064911965787065637420706172616d3a20496e74203d20706172616d00161533005491ff657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e2c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f6e6574776f726b5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f65636f6e6f6d69635f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f746a6563686e6963616c5f67726f75702c0a2020202070726f746f636f6c5f706172616d65746572735f676f7665726e616e63655f67726f75702c0a2020202074726561737572795f7769746864726177616c2c0a20205d3a204c6973743c446174613e203d20706172616d00161533004491c4657870656374205b0a202020206d6f74696f6e5f6f665f6e6f5f636f6e666964656e63652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465652c0a20202020636f6e737469747574696f6e616c5f636f6d6d69747465655f756e6465725f6e6f5f636f6e666964656e63652c0a20202020686172645f666f726b2c0a2020202070726f746f636f6c5f706172616d65746572735f73656375726974795f67726f75702c0a20205d3a204c6973743c446174613e203d20706172616d0016153300349127657870656374205b6d656d6f72792c206370755d3a204c6973743c496e743e203d20706172616d0016153300249128657870656374205b6d656d6f72792c206370755d3a204c6973743c446174613e203d20706172616d00165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "628d246855dda6aef139c7a1bec7d37ff1db213bfd28d3ae9fd52300" + }, + { + "title": "simple_spend.simple_spend.spend", "datum": { - "title": "_tmp1", + "title": "_datum", "schema": { "$ref": "#/definitions/Void" } }, "redeemer": { - "title": "_tmp2", + "title": "_redeemer", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "5909bd010100323232323232323232323232322533333300e00115332330073001300937540042a66601660146ea8008494cccccc04000454ccc020c008c028dd50008a99980618059baa001125333009323232323253330123758600660226ea8c014c044dd50030a9998091bac3014301530113754600a60226ea801854ccc048dd6180a180a980a980a980a980a980a980a980a98089baa30053011375400c2a66601c66e1d2054375a6028602a602a602a60226ea8c014c044dd5003099299980799baf4c101a0003015301630163016301630163016301630163016301630123754600c60246ea801c5288a9980824932657870656374205b5d203d3d20646963742e746f5f7061697273286374782e7472616e73616374696f6e2e646174756d73290016533300e3375e98012fa1d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8798000301430153015301530153015301530153015301530113754600a60226ea8018526153300f491ff6578706563740a202020205b0a20202020202050616972280a20202020202020205370656e64280a202020202020202020204f75747075745265666572656e6365207b0a2020202020202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202020202020202020206f75747075745f696e6465783a20302c0a202020202020202020207d2c0a2020202020202020292c0a2020202020202020766f696428292c0a202020202020292c0a202020205d203d3d207265640665656d6572730016153300f49120657870656374203432203d3d206374782e7472616e73616374696f6e2e6665650016153300f4912d657870656374205b5d203d206374782e7472616e73616374696f6e2e65787472615f7369676e61746f726965730016153300f4912c657870656374205b5d203d206374782e7472616e73616374696f6e2e7265666572656e63655f696e707574730016153300f49123657870656374205b5d203d206374782e7472616e73616374696f6e2e6f757470757473001632533301200100c132533301330160021323232325333013300d375a603260340042646464646464a66603266e1d2004301b3754603e0042a66466034600260386ea800854ccc068cdc7804245200000000000000000000000000000000000000000000000000000000000000000001533301a3375e6e98010dd3299980d25014bd6f7b6300991919800800a5eb7bdb180894ccc0840044cc088cdd82601014000374c00697adef6c60132323232533302133720910100002133026337609801014000374c00e00a2a66604266e3d22100002133026337609801014000374c00e00626604c66ec0dd48011ba600133006006003375660460066eb8c084008c094008c08c004c8cc0040052f5bded8c044a66604000226604266ec130010140004c01051a3b9aca00004bd6f7b630099191919299981019b90489000021330253376098010140004c01051a3b9aca0000005153330203371e9101000021330253376098010140004c01051a3b9aca0000003133025337606ea4008dd4000998030030019bad3022003375c60400046048004604400226464a6660386006603c6ea8c08800854ccc070c00cc078dd50008a4c03603660426044002603a6ea801854cc06d24013f657870656374207265736f6c7665645f696e7075745f76616c7565203d3d206173736574732e66726f6d5f6c6f76656c6163652831303030303030303030290016153301b491606578706563740a202020207472616e73616374696f6e5f6964203d3d20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030220016370e900100b80b980f180f800980f0011bab301c001301c002301a001301637540060226eb8c060004c050dd5180b801180b180b80098091baa00100d30140013758600860206ea8c010c040dd5002a99980619baf4c0132d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffd8799fd87980ffff003001300f37540082930a99806a49cd6578706563740a202020205370656e64696e67280a2020202020204f75747075745265666572656e6365207b0a20202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a20202020202020206f75747075745f696e6465783a20302c0a2020202020207d2c0a202020202020536f6d6528766f69642829292c0a2020202029203d3d20696e666f00162301230133013001533300a3371e910120c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b00375c602060226022602260226022602260226022602260226022601a6ea8c004c034dd50010a4c2a66016921546578706563740a2020202023226336666264333436363831613866383333376636623365353165366563393733663135303933363765616263336134346338343961663538613164383437316222203d3d206964001623010001149854cc0292411856616c696461746f722072657475726e65642066616c73650013656004004004004004004004370e90000018018018018018a99802a4810b5f746d70323a20566f6964001615330044910b5f746d70313a20566f696400161533003491ff657870656374205b0a20202020496e707574207b0a2020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b207472616e73616374696f6e5f69642c206f75747075745f696e6465783a2030207d2c0a2020202020206f75747075743a204f7574707574207b0a2020202020202020616464726573732c0a202020202020202076616c75653a207265736f6c7665645f696e7075745f76616c75652c0a2020202020202020646174756d3a20496e6c696e65446174756d285f292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a202020207d2c0a200b205d203d20696e7075747300161533002491566578706563742041646472657373207b207061796d656e745f63726564656e7469616c3a20536372697074285f292c207374616b655f63726564656e7469616c3a204e6f6e65207d203d0a202020206164647265737300165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "795cd91c67f5028dbe15907cdc13c12c9bf9059ed6939e34c2b3db15" + "compiledCode": "59090a0101003232323232323232323225333004323232323253323300a3001300c37540042646464646464a6660286eb0c058c05cc05cc04cdd50058a99980a1bac30163017301337540162a6660286eb0c058c05cc05cc05cc05cc05cc05cc05cc05cc04cdd50058a99980819b8748150dd6980b180b980b980b98099baa00b13253330113375e980101a0003017301830183018301830183018301830183018301830143754018294454cc04924012e657870656374205b5d203d3d20646963742e746f5f7061697273287472616e73616374696f6e2e646174756d7329001653330103375e98012fa1d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd87980003016301730173017301730173017301730173017301337540162930a99808a49ff6578706563740a202020205b0a20202020202050616972280a20202020202020205370656e64280a202020202020202020204f75747075745265666572656e6365207b0a2020202020202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202020202020202020206f75747075745f696e6465783a20302c0a202020202020202020207d2c0a2020202020202020292c0a2020202020202020766f696428292c0a202020202020292c0a202020205d203d3d207265640665656d657273001615330114911c657870656374203432203d3d207472616e73616374696f6e2e6665650016153301149129657870656374205b5d203d207472616e73616374696f6e2e65787472615f7369676e61746f726965730016153301149128657870656374205b5d203d207472616e73616374696f6e2e7265666572656e63655f696e70757473001615330114911f657870656374205b5d203d207472616e73616374696f6e2e6f757470757473001632533301400100e1325333015301800213232323253330153370e90001bad301b301c0021323232323232533301b3370e9002180e9baa30210021533301b3012301d37540022a66603666e3c01d221200000000000000000000000000000000000000000000000000000000000000000001533301b3375e6e9800cdd3299980da5014bd6f7b6300991919800800a5eb7bdb180894ccc0880044cc08ccdd82601014000374c00697adef6c60132323232533302233720910100002133027337609801014000374c00e00a2a66604466e3d22100002133027337609801014000374c00e00626604e66ec0dd48011ba600133006006003375660480066eb8c088008c098008c090004c8cc0040052f5bded8c044a66604200226604466ec130010140004c01051a3b9aca00004bd6f7b630099191919299981099b90489000021330263376098010140004c01051a3b9aca0000005153330213371e9101000021330263376098010140004c01051a3b9aca0000003133026337606ea4008dd4000998030030019bad3023003375c6042004604a004604600226464a66603a6028603e6ea8c08c00854ccc074c050c07cdd50008a4c03803860446046002603c6ea801454cc07124013f657870656374207265736f6c7665645f696e7075745f76616c7565203d3d206173736574732e66726f6d5f6c6f76656c6163652831303030303030303030290016153301c491606578706563740a202020207472616e73616374696f6e5f6964203d3d202322303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030302200160190193020302100130200023756603c002603c004603800260306ea800c04cdd7180d000980b1baa3019002301830190013014375400201e602c0026eb0c054c048dd5005299980719baf4c0127d8799f5820000000000000000000000000000000000000000000000000000000000000000000ff003014004149854cc03d24019c6578706563740a202020204f75747075745265666572656e6365207b0a2020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202020206f75747075745f696e6465783a20302c0a202020207d203d3d20696e666f0016533300d3371e910120c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b00375c60266028602860286028602860286028602860286028602860206ea8020526153300e491546578706563740a2020202023226336666264333436363831613866383333376636623365353165366563393733663135303933363765616263336134346338343961663538613164383437316222203d3d2069640016533300c3370e900018071baa00515333010300f375400a2930b0b1808980900098069baa002370e90010b1807180780118068009806801180580098039baa001149854cc0152411856616c696461746f722072657475726e65642066616c7365001365615330034901ff657870656374205b0a20202020496e707574207b0a2020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b207472616e73616374696f6e5f69642c206f75747075745f696e6465783a2030207d2c0a2020202020206f75747075743a204f7574707574207b0a2020202020202020616464726573732c0a202020202020202076616c75653a207265736f6c7665645f696e7075745f76616c75652c0a2020202020202020646174756d3a20496e6c696e65446174756d285f292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a202020207d2c0a200b205d203d20696e7075747300161533002491566578706563742041646472657373207b207061796d656e745f63726564656e7469616c3a20536372697074285f292c207374616b655f63726564656e7469616c3a204e6f6e65207d203d0a202020206164647265737300165734ae7155ceaab9e5573eae815d0aba21", + "hash": "a1061d09b0b83996b07d2f5496ee57c308160bc39115b26058831583" }, { - "title": "voting.script", + "title": "simple_spend.simple_spend.else", + "compiledCode": "59090a0101003232323232323232323225333004323232323253323300a3001300c37540042646464646464a6660286eb0c058c05cc05cc04cdd50058a99980a1bac30163017301337540162a6660286eb0c058c05cc05cc05cc05cc05cc05cc05cc05cc04cdd50058a99980819b8748150dd6980b180b980b980b98099baa00b13253330113375e980101a0003017301830183018301830183018301830183018301830143754018294454cc04924012e657870656374205b5d203d3d20646963742e746f5f7061697273287472616e73616374696f6e2e646174756d7329001653330103375e98012fa1d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd87980003016301730173017301730173017301730173017301337540162930a99808a49ff6578706563740a202020205b0a20202020202050616972280a20202020202020205370656e64280a202020202020202020204f75747075745265666572656e6365207b0a2020202020202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202020202020202020206f75747075745f696e6465783a20302c0a202020202020202020207d2c0a2020202020202020292c0a2020202020202020766f696428292c0a202020202020292c0a202020205d203d3d207265640665656d657273001615330114911c657870656374203432203d3d207472616e73616374696f6e2e6665650016153301149129657870656374205b5d203d207472616e73616374696f6e2e65787472615f7369676e61746f726965730016153301149128657870656374205b5d203d207472616e73616374696f6e2e7265666572656e63655f696e70757473001615330114911f657870656374205b5d203d207472616e73616374696f6e2e6f757470757473001632533301400100e1325333015301800213232323253330153370e90001bad301b301c0021323232323232533301b3370e9002180e9baa30210021533301b3012301d37540022a66603666e3c01d221200000000000000000000000000000000000000000000000000000000000000000001533301b3375e6e9800cdd3299980da5014bd6f7b6300991919800800a5eb7bdb180894ccc0880044cc08ccdd82601014000374c00697adef6c60132323232533302233720910100002133027337609801014000374c00e00a2a66604466e3d22100002133027337609801014000374c00e00626604e66ec0dd48011ba600133006006003375660480066eb8c088008c098008c090004c8cc0040052f5bded8c044a66604200226604466ec130010140004c01051a3b9aca00004bd6f7b630099191919299981099b90489000021330263376098010140004c01051a3b9aca0000005153330213371e9101000021330263376098010140004c01051a3b9aca0000003133026337606ea4008dd4000998030030019bad3023003375c6042004604a004604600226464a66603a6028603e6ea8c08c00854ccc074c050c07cdd50008a4c03803860446046002603c6ea801454cc07124013f657870656374207265736f6c7665645f696e7075745f76616c7565203d3d206173736574732e66726f6d5f6c6f76656c6163652831303030303030303030290016153301c491606578706563740a202020207472616e73616374696f6e5f6964203d3d202322303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030302200160190193020302100130200023756603c002603c004603800260306ea800c04cdd7180d000980b1baa3019002301830190013014375400201e602c0026eb0c054c048dd5005299980719baf4c0127d8799f5820000000000000000000000000000000000000000000000000000000000000000000ff003014004149854cc03d24019c6578706563740a202020204f75747075745265666572656e6365207b0a2020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202020206f75747075745f696e6465783a20302c0a202020207d203d3d20696e666f0016533300d3371e910120c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b00375c60266028602860286028602860286028602860286028602860206ea8020526153300e491546578706563740a2020202023226336666264333436363831613866383333376636623365353165366563393733663135303933363765616263336134346338343961663538613164383437316222203d3d2069640016533300c3370e900018071baa00515333010300f375400a2930b0b1808980900098069baa002370e90010b1807180780118068009806801180580098039baa001149854cc0152411856616c696461746f722072657475726e65642066616c7365001365615330034901ff657870656374205b0a20202020496e707574207b0a2020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b207472616e73616374696f6e5f69642c206f75747075745f696e6465783a2030207d2c0a2020202020206f75747075743a204f7574707574207b0a2020202020202020616464726573732c0a202020202020202076616c75653a207265736f6c7665645f696e7075745f76616c75652c0a2020202020202020646174756d3a20496e6c696e65446174756d285f292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a202020207d2c0a200b205d203d20696e7075747300161533002491566578706563742041646472657373207b207061796d656e745f63726564656e7469616c3a20536372697074285f292c207374616b655f63726564656e7469616c3a204e6f6e65207d203d0a202020206164647265737300165734ae7155ceaab9e5573eae815d0aba21", + "hash": "a1061d09b0b83996b07d2f5496ee57c308160bc39115b26058831583" + }, + { + "title": "voting.purposes.vote", "redeemer": { - "title": "_tmp0", + "title": "redeemer", "schema": { "$ref": "#/definitions/Data" } }, - "compiledCode": "590b6501010032323232323232323232323222533300632323232323232533300d3006300f37540022646464a666020601260246ea800854cc8cc044c004c04cdd5180b980a1baa0031533301500200e13253330163019003132323253330153005375a603660380042a66602a600a602e6ea800c54ccc054cdc7800a44120999999999999999999999999999999999999999999999999999999999999999900153330153375e98158d8799f9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa1d8799f582099999999999999999999999999999999999999999999999999999999999999991898ffd87980ffff003300a00c480084c94ccc058c03cc060dd50008991919299980c9804980d9baa002153330193009301b3754603e60386ea800854ccc07400405c54ccc064cdd7a61abd8799f9fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa3d8799f5820777777777777777777777777777777777777777777777777777777777777777702ffd87b80d8799f5820888888888888888888888888888888888888888888888888888888888888888801ffd87b80d8799f5820999999999999999999999999999999999999999999999999999999999999999900ffd87b80ffff003300e010480184c94ccc068c04cc070dd50008991919299980e99b8748010c07cdd5001099299981100100e8a99980f19b8f0014891c000000000000000000000000000000000000000000000000000000000014a22a6603e9211865787065637420706f6f6c5f6964203d3d206f6e6c7930730016375c604660406ea8008070dd5980f801180e8009919bb030210013021302200137586040603a6ea8004064cc0380412008153301a491ff6578706563740a202020202020536f6d65280a2020202020202020506169722844656c6567617465526570726573656e74617469766528566572696669636174696f6e4b6579286f6e6c79307329292c0a20202020202020205b0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7937732c2070726f706f73616c5f70726f6365647572653a2032207d2c0a202020202020202020204162737461696e292c0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7938732c2070726f706fb673616c5f70726f6365647572653a2031207d2c0a202020202020202020204162737461696e292c0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7939732c2070726f706f73616c5f70726f6365647572653a2030207d2c0a202020202020202020204162737461696e292c0a20202020202020205d292c0a20202020202029203d3d206c6973742e617428766f7465732c20332900160170173756603600460320026466ec0c074004c074c078004dd6180e180c9baa0010143300a00c4801054cc0592401ff6578706563740a202020202020536f6d65280a20202020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228566572696669636174696f6e4b6579286f6e6c79307329292c0a20202020202020205b0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b0a2020202020202020202020207472616e73616374696f6e3a206f6e6c7939732c0a20202020202020202020202070726f706f73616c5f70726f6365647572653a203135322c0a202020202020202020207d2c0a202020202020202020204e6f292c0a20202020202020205d292c0a20202020202029203d3d20116c6973742e617428766f7465732c203129001615330164911c657870656374207472616e73616374696f6e203d3d206f6e6c7939730016012012375c6034002602c6ea8c054008c05400403cc05c008dc3a400401a01a6eacc048008c040004c8cdd8180a000980a180a8009bac301330103754002014660020069000180080091129998088010a60103d87a800013232533300f300800313374a90001980a1ba73301430110023301430120024bd7025eb804ccc014014004c02400cc05400cc04c008dd5980798081808180818081808180818081808180818081808180818061baa300f300c375400866464646464644a66601e64a6666660300042a666020601260246ea80084c94ccc0540040084c94cccccc06800400c00c00c4c94ccc05cc06800c54ccc04ccdc3a40a80022a660286e64cc0180152210014a20080086eb400400cc05c004c04cdd5001000800800800800899299999980c0010a999808180498091baa00215333014301337540042a660226e64cc00d300103d879800048810014a20020020020020020022940526153301049010f6578706563742069735f76616c69640016300100122253332333301800313232323232323300c0020013371491010128000025333014337100069007099b80483c80400c54ccc050cdc4001a410004266e00cdc0241002800690068b299980b800899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d2900005223330090090023006001223330090090020013758602a0046eb4c04c004c8cdd81ba83013001374e60280026ea800c4c94ccc0540044cdc52441027b7d00003133714911037b5f2000323233001001003225333018001100315333018301b0011323330090093017001337149101023a20003330090093018001004301a0011323330090093017001337149101023a20003330090093018001300633003003301c002301a0013371491102207d000033756006264a66602a002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001300b371a00466e292201012700003222533301333710004900008008991919199803003180800299b8b33700004a66602c66e2000920141481805206e3371666e000054ccc058cdc4000a4028290300a40dc00866e18009202033706002901019b8e004002375c0044444646600200200a44a66602a002200a2a66602a6030002266006602e00200a266008602e00266004004603000244646600200200644a66601c600e002266e2922010130000031533300e337100029000099b8a489012d003300200233702900000089980299b8400148050cdc599b803370a002900a240c00066002002444a66601666e2400920001001133300300333708004900a19b8b3370066e14009201448180004c038c03cc02cdd50019b8748000dc0240022930a99803a4811856616c696461746f722072657475726e65642066616c7365001365615330044901ab65787065637420536f6d65280a2020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228536372697074282e2e29292c0a2020202020205b5061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e2c2070726f706f73616c5f70726f6365647572653a2031207d2c20596573295d292c0a2020202029203d206c6973742e617428766f7465732c203029001615330034915865787065637420536f6d6528506169722844656c6567617465526570726573656e74617469766528536372697074282e2e29292c205b5f2c202e2e5d2929203d0a2020202020206c6973742e617428766f7465732c203229001615330024914265787065637420536f6d652850616972285374616b65506f6f6c28706f6f6c5f6964292c205b5f2c202e2e5d2929203d206c6973742e617428766f7465732c20342900165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "1282253bfd18df713e867324c09c7cb9c2dea6d11e3fb9c1cfdb7057" + "compiledCode": "590c50010100323232323232323232323232253330053232323232533300a3370e900418061baa0011323232323232323253330123006301437540022646464a66602a6012602e6ea800854cc8cc058c004c060dd5180e180c9baa0031533301a002013132533301b301e0031323232533301a3005375a604060420042a666034600a60386ea800c54ccc068cdc7800a45209999999999999999999999999999999999999999999999999999999999999999001533301a3375e98158d8799f9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa1d8799f582099999999999999999999999999999999999999999999999999999999999999991898ffd87980ffff003300a00c480084c94ccc06cc03cc074dd50008991919299980f180498101baa0021533301e300930203754604860426ea800854ccc08800407054ccc078cdd7a61abd8799f9fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa3d8799f5820777777777777777777777777777777777777777777777777777777777777777702ffd87b80d8799f5820888888888888888888888888888888888888888888888888888888888888888801ffd87b80d8799f5820999999999999999999999999999999999999999999999999999999999999999900ffd87b80ffff003300e010480184c94ccc07cc04cc084dd50008991919299981119b8748010c090dd500109929998138010110a99981199b8f0014891c000000000000000000000000000000000000000000000000000000000014a22a660489211865787065637420706f6f6c5f6964203d3d206f6e6c7930730016375c6050604a6ea8008084dd5981200118110009919bb03026001302630270013758604a60446ea8004078cc0380412008153301f491ff6578706563740a202020202020536f6d65280a202020202020202050616972280a2020202020202020202044656c6567617465526570726573656e74617469766528566572696669636174696f6e4b6579286f6e6c79307329292c0a202020202020202020205b0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7937732c2070726f706f73616c5f70726f6365647572653a2032207d2c0a20202020202020202020202020204162737461696e2c0a202020202020202020202020292c0a2020202020202020202020205061ff6972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7938732c2070726f706f73616c5f70726f6365647572653a2031207d2c0a20202020202020202020202020204162737461696e2c0a202020202020202020202020292c0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7939732c2070726f706f73616c5f70726f6365647572653a2030207d2c0a20202020202020202020202020204162737461696e2c0a20202020202020202020392020292c0a202020202020202020205d2c0a2020202020202020292c0a20202020202029203d3d206c6973742e617428766f7465732c203329001601c01c37566040004603c0026466ec0c088004c088c08c004dd61810980f1baa0010193300a00c4801054cc06d2401ff6578706563740a202020202020536f6d65280a202020202020202050616972280a20202020202020202020436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228566572696669636174696f6e4b6579286f6e6c79307329292c0a202020202020202020205b0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b0a202020202020202020202020202020207472616e73616374696f6e3a206f6e6c7939732c0a2020202020202020202020202020202070726f706f73616c5f70726f6365647572653a203135322c0a2020202020202020202020202059207d2c0a20202020202020202020202020204e6f2c0a202020202020202020202020292c0a202020202020202020205d2c0a2020202020202020292c0a20202020202029203d3d206c6973742e617428766f7465732c2031290016153301b4911c657870656374207472616e73616374696f6e203d3d206f6e6c7939730016017017375c603e00260366ea8c068008c068004050c070008dc3a40040240246eacc05c008c054004c8cdd8180c800980c980d0009bac30183015375400201e6600200690001800800911299980b0010a60103d87a8000132325333014300800313374a90001980c9ba73301930160023301930170024bd7025eb804ccc014014004c02400cc06800cc060008dd5980a180a980a980a980a980a980a980a980a980a980a980a980a98089baa008323232323232533301332533333301c00c15333014300830163754018264a666032002004264a66666603c002006006006264a666036603c0062a66602e66e1d2054001153301837326600a01e9110014a20080086eb400400cc06c004c05cdd5006000800800800800899299999980e0060a99980a1804180b1baa00c15333018301737540182a6602a6e64cc009300103d879800048810014a20020020020020020022940526153301449010f6578706563742069735f76616c69640016300100122253332333301d00313232323232323300c0020013371491010128000025333019337100069007099b80483c80400c54ccc064cdc4001a410004266e00cdc0241002800690068b299980e000899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d290000522333009009002300600122333009009002001375860340046eb4c060004c8cdd81ba83018001374e60320026ea800c4c94ccc0680044cdc52441027b7d00003133714911037b5f200032323300100100322533301d00110031533301d3020001132333009009301c001337149101023a2000333009009301d001004301f001132333009009301c001337149101023a2000333009009301d0013006330030033021002301f0013371491102207d000033756006264a666034002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001300b371a00466e292201012700003222533301833710004900008008991919199803003180800299b8b33700004a66603666e2000920141481805206e3371666e000054ccc06ccdc4000a4028290300a40dc00866e18009202033706002901019b8e004002375c0044444646600200200a44a666034002200a2a666034603a002266006603800200a266008603800266004004603a00244646600200200644a666026600e002266e29220101300000315333013337100029000099b8a489012d003300200233702900000089980299b8400148050cdc599b803370a002900a240c00066002002444a66602066e2400920001001133300300333708004900a19b8b3370066e14009201448180004dc3a40006e0120013010300d37540022c601e6020004601c002601c004601800260106ea800452615330064911856616c696461746f722072657475726e65642066616c7365001365615330044901ab65787065637420536f6d65280a2020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228536372697074282e2e29292c0a2020202020205b5061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e2c2070726f706f73616c5f70726f6365647572653a2031207d2c20596573295d292c0a2020202029203d206c6973742e617428766f7465732c203029001615330034915865787065637420536f6d6528506169722844656c6567617465526570726573656e74617469766528536372697074282e2e29292c205b5f2c202e2e5d2929203d0a2020202020206c6973742e617428766f7465732c203229001615330024914265787065637420536f6d652850616972285374616b65506f6f6c28706f6f6c5f6964292c205b5f2c202e2e5d2929203d206c6973742e617428766f7465732c20342900165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "298b027639e9340c10c241a8193ab099a46840548c61930c32398a7c" }, { - "title": "withdraw.spend", + "title": "voting.purposes.else", + "compiledCode": "590c50010100323232323232323232323232253330053232323232533300a3370e900418061baa0011323232323232323253330123006301437540022646464a66602a6012602e6ea800854cc8cc058c004c060dd5180e180c9baa0031533301a002013132533301b301e0031323232533301a3005375a604060420042a666034600a60386ea800c54ccc068cdc7800a45209999999999999999999999999999999999999999999999999999999999999999001533301a3375e98158d8799f9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa1d8799f582099999999999999999999999999999999999999999999999999999999999999991898ffd87980ffff003300a00c480084c94ccc06cc03cc074dd50008991919299980f180498101baa0021533301e300930203754604860426ea800854ccc08800407054ccc078cdd7a61abd8799f9fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa3d8799f5820777777777777777777777777777777777777777777777777777777777777777702ffd87b80d8799f5820888888888888888888888888888888888888888888888888888888888888888801ffd87b80d8799f5820999999999999999999999999999999999999999999999999999999999999999900ffd87b80ffff003300e010480184c94ccc07cc04cc084dd50008991919299981119b8748010c090dd500109929998138010110a99981199b8f0014891c000000000000000000000000000000000000000000000000000000000014a22a660489211865787065637420706f6f6c5f6964203d3d206f6e6c7930730016375c6050604a6ea8008084dd5981200118110009919bb03026001302630270013758604a60446ea8004078cc0380412008153301f491ff6578706563740a202020202020536f6d65280a202020202020202050616972280a2020202020202020202044656c6567617465526570726573656e74617469766528566572696669636174696f6e4b6579286f6e6c79307329292c0a202020202020202020205b0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7937732c2070726f706f73616c5f70726f6365647572653a2032207d2c0a20202020202020202020202020204162737461696e2c0a202020202020202020202020292c0a2020202020202020202020205061ff6972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7938732c2070726f706f73616c5f70726f6365647572653a2031207d2c0a20202020202020202020202020204162737461696e2c0a202020202020202020202020292c0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7939732c2070726f706f73616c5f70726f6365647572653a2030207d2c0a20202020202020202020202020204162737461696e2c0a20202020202020202020392020292c0a202020202020202020205d2c0a2020202020202020292c0a20202020202029203d3d206c6973742e617428766f7465732c203329001601c01c37566040004603c0026466ec0c088004c088c08c004dd61810980f1baa0010193300a00c4801054cc06d2401ff6578706563740a202020202020536f6d65280a202020202020202050616972280a20202020202020202020436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228566572696669636174696f6e4b6579286f6e6c79307329292c0a202020202020202020205b0a20202020202020202020202050616972280a2020202020202020202020202020476f7665726e616e6365416374696f6e4964207b0a202020202020202020202020202020207472616e73616374696f6e3a206f6e6c7939732c0a2020202020202020202020202020202070726f706f73616c5f70726f6365647572653a203135322c0a2020202020202020202020202059207d2c0a20202020202020202020202020204e6f2c0a202020202020202020202020292c0a202020202020202020205d2c0a2020202020202020292c0a20202020202029203d3d206c6973742e617428766f7465732c2031290016153301b4911c657870656374207472616e73616374696f6e203d3d206f6e6c7939730016017017375c603e00260366ea8c068008c068004050c070008dc3a40040240246eacc05c008c054004c8cdd8180c800980c980d0009bac30183015375400201e6600200690001800800911299980b0010a60103d87a8000132325333014300800313374a90001980c9ba73301930160023301930170024bd7025eb804ccc014014004c02400cc06800cc060008dd5980a180a980a980a980a980a980a980a980a980a980a980a980a98089baa008323232323232533301332533333301c00c15333014300830163754018264a666032002004264a66666603c002006006006264a666036603c0062a66602e66e1d2054001153301837326600a01e9110014a20080086eb400400cc06c004c05cdd5006000800800800800899299999980e0060a99980a1804180b1baa00c15333018301737540182a6602a6e64cc009300103d879800048810014a20020020020020020022940526153301449010f6578706563742069735f76616c69640016300100122253332333301d00313232323232323300c0020013371491010128000025333019337100069007099b80483c80400c54ccc064cdc4001a410004266e00cdc0241002800690068b299980e000899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d290000522333009009002300600122333009009002001375860340046eb4c060004c8cdd81ba83018001374e60320026ea800c4c94ccc0680044cdc52441027b7d00003133714911037b5f200032323300100100322533301d00110031533301d3020001132333009009301c001337149101023a2000333009009301d001004301f001132333009009301c001337149101023a2000333009009301d0013006330030033021002301f0013371491102207d000033756006264a666034002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001300b371a00466e292201012700003222533301833710004900008008991919199803003180800299b8b33700004a66603666e2000920141481805206e3371666e000054ccc06ccdc4000a4028290300a40dc00866e18009202033706002901019b8e004002375c0044444646600200200a44a666034002200a2a666034603a002266006603800200a266008603800266004004603a00244646600200200644a666026600e002266e29220101300000315333013337100029000099b8a489012d003300200233702900000089980299b8400148050cdc599b803370a002900a240c00066002002444a66602066e2400920001001133300300333708004900a19b8b3370066e14009201448180004dc3a40006e0120013010300d37540022c601e6020004601c002601c004601800260106ea800452615330064911856616c696461746f722072657475726e65642066616c7365001365615330044901ab65787065637420536f6d65280a2020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228536372697074282e2e29292c0a2020202020205b5061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e2c2070726f706f73616c5f70726f6365647572653a2031207d2c20596573295d292c0a2020202029203d206c6973742e617428766f7465732c203029001615330034915865787065637420536f6d6528506169722844656c6567617465526570726573656e74617469766528536372697074282e2e29292c205b5f2c202e2e5d2929203d0a2020202020206c6973742e617428766f7465732c203229001615330024914265787065637420536f6d652850616972285374616b65506f6f6c28706f6f6c5f6964292c205b5f2c202e2e5d2929203d206c6973742e617428766f7465732c20342900165734ae7155ceaab9e5573eae815d0aba257481", + "hash": "298b027639e9340c10c241a8193ab099a46840548c61930c32398a7c" + }, + { + "title": "withdraw.thing.spend", "datum": { - "title": "_tmp0", + "title": "_datum", "schema": { "$ref": "#/definitions/Void" } }, "redeemer": { - "title": "_tmp1", + "title": "_rdmr", "schema": { - "$ref": "#/definitions/RedeemerWrapper$Void" + "$ref": "#/definitions/Void" } }, - "compiledCode": "5908150101003232323232323232323232322232533333300f00215323330083001300a37540062a660129212052756e6e696e672032206172672076616c696461746f7220776974686472617700135333333010004153330083001300a37540082a66601860166ea8010494ccc024c8c94ccc02ccdc3a4008601a6ea80044c94ccc030cdc3a4004601c6ea80044c8c94cc8cc03ccdd798009980a26010ad8799fd87980d87a80ff00330143001330143374a90011980a2601091b000001739c890420004bd701980a199807a504c103d87a80004c0103d87980004bd7025eb80c054c058c058c058c058c058c058c058c048dd5180118091baa007132323253330123375e980154d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffffffffff00330010034800054ccc048cdd7a613ad8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034800854ccc048cdd7a613ad8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034801054ccc048cdd79ba6330173376066e95200233017375200c97ae04c1010000330174bded8c0122d8799f581c00000000000000000000000000000000000000000000000000000000ff0001010e004bd6f7b630180c180c980c980c980c980c980c980a9baa300530153754014294454cc04d2401706578706563740a2020202020205b5061697228536372697074286d795f7363726970745f68617368292c2030292c205061697228566572696669636174696f6e4b6579286f6e6c793073292c203134295d203d3d206374782e7472616e73616374696f6e2e7769746864726177616c7300161533013491b96578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20536372697074286f6e6c793173292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20322900161533013491c26578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20312900161533013491c16578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528496e6c696e6528536372697074286f6e6c7931732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20302900163001001222533301700214c103d87a8000132325333015300e003130073301a0024bd70099980280280099b8000348004c06c00cc064008c8cc004004dd6180398099baa30033013375401044a66602a002297ae0133016300430143754602e0026600400460300026e952000153300f4901566578706563740a202020202020696e74657276616c2e656e746972656c795f6265666f7265283135393630353930393230303029203d3d206374782e7472616e73616374696f6e2e76616c69646974795f72616e6765001623014001375c6024601e6ea800402cc044c038dd5000805180098069baa0022301030113011001149854cc0292411856616c696461746f722072657475726e65642066616c7365001365600600600600600600600315330094911d52756e6e696e672033206172672076616c696461746f72207370656e6400135333333010004153330083001300a37540082a66601860166ea8010494cccccc04400454ccc024c008c02cdd50008a99980698061baa00112533300a4a22930a99805a491856616c696461746f722072657475726e65642066616c73650013656006006006006006006006006006006006006300e300b37540066e1d2000153300800116153300800116153300800116153300800116490191496e636f72726563742072656465656d6572207479706520666f722076616c696461746f72207370656e642e0a2020202020202020202020202020202020202020446f75626c6520636865636b20796f7520686176652077726170706564207468652072656465656d657220747970652061732073706563696669656420696e20796f757220706c757475732e6a736f6e0015330044910b5f746d70313a20566f6964001615330034910b5f746d70303a20566f69640016153300249135657870656374205769746864726177696e6728536372697074286d795f7363726970745f686173682929203d206374782e696e666f00165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "21fac9728b25964132635f0eb1931afea5e21572e2fd3766a05a648d" + "compiledCode": "5906690101003232323232323232253330023232323232325323330093370e9001001099191919251533300c3004300e375400e2a666020601e6ea801c5261616301130120023010001300c37540062a66601266e1d200400213232533300b3370e900118069baa00213253323300d3375e60026602498010ad8799fd87980d87a80ff00330123001330123374a9001198092601091b000001739c890420004bd7019809199806a504c103d87a80004c0103d87980004bd7025eb80c04cc050c050c050c050c050c050c050c040dd50050991919299980819baf4c0154d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffffffffff00330010034800054ccc040cdd7a613ad8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034800854ccc040cdd7a613ad8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034801054ccc040cdd79ba6330153376066e95200233015375200a97ae04c1010000330154bded8c0122d8799f581c00000000000000000000000000000000000000000000000000000000ff0001010e004bd6f7b630180b180b980b980b980b980b980b98099baa00d14a22a6602292016c6578706563740a2020202020205b5061697228536372697074286d795f7363726970745f68617368292c2030292c205061697228566572696669636174696f6e4b6579286f6e6c793073292c203134295d203d3d207472616e73616374696f6e2e7769746864726177616c7300161533011491b96578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20536372697074286f6e6c793173292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20322900161533011491c26578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20312900161533011491c16578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528496e6c696e6528536372697074286f6e6c7931732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20302900163001001222533301500214c103d87a8000132325333013300b00313007330180024bd70099980280280099b8000348004c06400cc05c008c8cc004004dd6180a180a980a98089baa00b22533301300114bd7009980a180a98091baa3015001330020023016001374a90000a99806a4814c65787065637420696e74657276616c2e656e746972656c795f6265666f7265283135393630353930393230303029203d3d207472616e73616374696f6e2e76616c69646974795f72616e67650016375c6022601c6ea800854cc03124012a65787065637420536372697074286d795f7363726970745f6861736829203d2063726564656e7469616c0016533300a3002300c375400a2a66601c601a6ea80145261616300f300c37540062c6e1d2000300937540026018601a004601600260160046012002600a6ea800452615330034911856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae815d0aba201", + "hash": "04137c5312a5b62c6bd9282e5c41e82d0f8b3da15fee6628552fe189" }, { - "title": "withdraw.withdraw", + "title": "withdraw.thing.withdraw", "redeemer": { - "title": "_tmp0", + "title": "_rdmr", "schema": { "$ref": "#/definitions/Void" } }, - "compiledCode": "5908150101003232323232323232323232322232533333300f00215323330083001300a37540062a660129212052756e6e696e672032206172672076616c696461746f7220776974686472617700135333333010004153330083001300a37540082a66601860166ea8010494ccc024c8c94ccc02ccdc3a4008601a6ea80044c94ccc030cdc3a4004601c6ea80044c8c94cc8cc03ccdd798009980a26010ad8799fd87980d87a80ff00330143001330143374a90011980a2601091b000001739c890420004bd701980a199807a504c103d87a80004c0103d87980004bd7025eb80c054c058c058c058c058c058c058c058c048dd5180118091baa007132323253330123375e980154d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffffffffff00330010034800054ccc048cdd7a613ad8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034800854ccc048cdd7a613ad8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034801054ccc048cdd79ba6330173376066e95200233017375200c97ae04c1010000330174bded8c0122d8799f581c00000000000000000000000000000000000000000000000000000000ff0001010e004bd6f7b630180c180c980c980c980c980c980c980a9baa300530153754014294454cc04d2401706578706563740a2020202020205b5061697228536372697074286d795f7363726970745f68617368292c2030292c205061697228566572696669636174696f6e4b6579286f6e6c793073292c203134295d203d3d206374782e7472616e73616374696f6e2e7769746864726177616c7300161533013491b96578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20536372697074286f6e6c793173292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20322900161533013491c26578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20312900161533013491c16578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528496e6c696e6528536372697074286f6e6c7931732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20302900163001001222533301700214c103d87a8000132325333015300e003130073301a0024bd70099980280280099b8000348004c06c00cc064008c8cc004004dd6180398099baa30033013375401044a66602a002297ae0133016300430143754602e0026600400460300026e952000153300f4901566578706563740a202020202020696e74657276616c2e656e746972656c795f6265666f7265283135393630353930393230303029203d3d206374782e7472616e73616374696f6e2e76616c69646974795f72616e6765001623014001375c6024601e6ea800402cc044c038dd5000805180098069baa0022301030113011001149854cc0292411856616c696461746f722072657475726e65642066616c7365001365600600600600600600600315330094911d52756e6e696e672033206172672076616c696461746f72207370656e6400135333333010004153330083001300a37540082a66601860166ea8010494cccccc04400454ccc024c008c02cdd50008a99980698061baa00112533300a4a22930a99805a491856616c696461746f722072657475726e65642066616c73650013656006006006006006006006006006006006006300e300b37540066e1d2000153300800116153300800116153300800116153300800116490191496e636f72726563742072656465656d6572207479706520666f722076616c696461746f72207370656e642e0a2020202020202020202020202020202020202020446f75626c6520636865636b20796f7520686176652077726170706564207468652072656465656d657220747970652061732073706563696669656420696e20796f757220706c757475732e6a736f6e0015330044910b5f746d70313a20566f6964001615330034910b5f746d70303a20566f69640016153300249135657870656374205769746864726177696e6728536372697074286d795f7363726970745f686173682929203d206374782e696e666f00165734ae7155ceaab9e5573eae815d0aba257481", - "hash": "21fac9728b25964132635f0eb1931afea5e21572e2fd3766a05a648d" + "compiledCode": "5906690101003232323232323232253330023232323232325323330093370e9001001099191919251533300c3004300e375400e2a666020601e6ea801c5261616301130120023010001300c37540062a66601266e1d200400213232533300b3370e900118069baa00213253323300d3375e60026602498010ad8799fd87980d87a80ff00330123001330123374a9001198092601091b000001739c890420004bd7019809199806a504c103d87a80004c0103d87980004bd7025eb80c04cc050c050c050c050c050c050c050c040dd50050991919299980819baf4c0154d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffffffffff00330010034800054ccc040cdd7a613ad8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034800854ccc040cdd7a613ad8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034801054ccc040cdd79ba6330153376066e95200233015375200a97ae04c1010000330154bded8c0122d8799f581c00000000000000000000000000000000000000000000000000000000ff0001010e004bd6f7b630180b180b980b980b980b980b980b98099baa00d14a22a6602292016c6578706563740a2020202020205b5061697228536372697074286d795f7363726970745f68617368292c2030292c205061697228566572696669636174696f6e4b6579286f6e6c793073292c203134295d203d3d207472616e73616374696f6e2e7769746864726177616c7300161533011491b96578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20536372697074286f6e6c793173292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20322900161533011491c26578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20312900161533011491c16578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528496e6c696e6528536372697074286f6e6c7931732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20302900163001001222533301500214c103d87a8000132325333013300b00313007330180024bd70099980280280099b8000348004c06400cc05c008c8cc004004dd6180a180a980a98089baa00b22533301300114bd7009980a180a98091baa3015001330020023016001374a90000a99806a4814c65787065637420696e74657276616c2e656e746972656c795f6265666f7265283135393630353930393230303029203d3d207472616e73616374696f6e2e76616c69646974795f72616e67650016375c6022601c6ea800854cc03124012a65787065637420536372697074286d795f7363726970745f6861736829203d2063726564656e7469616c0016533300a3002300c375400a2a66601c601a6ea80145261616300f300c37540062c6e1d2000300937540026018601a004601600260160046012002600a6ea800452615330034911856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae815d0aba201", + "hash": "04137c5312a5b62c6bd9282e5c41e82d0f8b3da15fee6628552fe189" + }, + { + "title": "withdraw.thing.else", + "compiledCode": "5906690101003232323232323232253330023232323232325323330093370e9001001099191919251533300c3004300e375400e2a666020601e6ea801c5261616301130120023010001300c37540062a66601266e1d200400213232533300b3370e900118069baa00213253323300d3375e60026602498010ad8799fd87980d87a80ff00330123001330123374a9001198092601091b000001739c890420004bd7019809199806a504c103d87a80004c0103d87980004bd7025eb80c04cc050c050c050c050c050c050c050c040dd50050991919299980819baf4c0154d8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffffffffff00330010034800054ccc040cdd7a613ad8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034800854ccc040cdd7a613ad8799fd8799fd87a9f581c11111111111111111111111111111111111111111111111111111111ffd8799fd87a9f1a00261ec3181b03ffffffff00330010034801054ccc040cdd79ba6330153376066e95200233015375200a97ae04c1010000330154bded8c0122d8799f581c00000000000000000000000000000000000000000000000000000000ff0001010e004bd6f7b630180b180b980b980b980b980b980b98099baa00d14a22a6602292016c6578706563740a2020202020205b5061697228536372697074286d795f7363726970745f68617368292c2030292c205061697228566572696669636174696f6e4b6579286f6e6c793073292c203134295d203d3d207472616e73616374696f6e2e7769746864726177616c7300161533011491b96578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20536372697074286f6e6c793173292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20322900161533011491c26578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528506f696e74657228323439383234332c2032372c203329292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20312900161533011491c16578706563740a202020202020536f6d65280a202020202020202041646472657373207b0a202020202020202020207061796d656e745f63726564656e7469616c3a20566572696669636174696f6e4b6579286f6e6c793073292c0a202020202020202020207374616b655f63726564656e7469616c3a20536f6d6528496e6c696e6528536372697074286f6e6c7931732929292c0a20202020202020207d2c0a20202020202029203d3d206c6973742e6174286164647265737365732c20302900163001001222533301500214c103d87a8000132325333013300b00313007330180024bd70099980280280099b8000348004c06400cc05c008c8cc004004dd6180a180a980a98089baa00b22533301300114bd7009980a180a98091baa3015001330020023016001374a90000a99806a4814c65787065637420696e74657276616c2e656e746972656c795f6265666f7265283135393630353930393230303029203d3d207472616e73616374696f6e2e76616c69646974795f72616e67650016375c6022601c6ea800854cc03124012a65787065637420536372697074286d795f7363726970745f6861736829203d2063726564656e7469616c0016533300a3002300c375400a2a66601c601a6ea80145261616300f300c37540062c6e1d2000300937540026018601a004601600260160046012002600a6ea800452615330034911856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae815d0aba201", + "hash": "04137c5312a5b62c6bd9282e5c41e82d0f8b3da15fee6628552fe189" } ], "definitions": { @@ -128,21 +168,6 @@ "title": "Data", "description": "Any Plutus data." }, - "RedeemerWrapper$Void": { - "title": "Wrapped Redeemer", - "description": "A redeemer wrapped in an extra constructor to make multi-validator detection possible on-chain.", - "anyOf": [ - { - "dataType": "constructor", - "index": 1, - "fields": [ - { - "$ref": "#/definitions/Void" - } - ] - } - ] - }, "Void": { "title": "Unit", "description": "The nullary constructor.", diff --git a/examples/acceptance_tests/script_context/v3/validators/certificates.ak b/examples/acceptance_tests/script_context/v3/validators/certificates.ak index 5d5721c8..feffda0f 100644 --- a/examples/acceptance_tests/script_context/v3/validators/certificates.ak +++ b/examples/acceptance_tests/script_context/v3/validators/certificates.ak @@ -1,14 +1,14 @@ use aiken/collection/list use cardano/certificate.{ AlwaysAbstain, AlwaysNoConfidence, AuthorizeConstitutionalCommitteeProxy, - DelegateBlockProduction, DelegateBoth, DelegateCredential, DelegateVote, - RegisterAndDelegateCredential, RegisterCredential, + Certificate, DelegateBlockProduction, DelegateBoth, DelegateCredential, + DelegateVote, RegisterAndDelegateCredential, RegisterCredential, RegisterDelegateRepresentative, RegisterStakePool, Registered, RetireFromConstitutionalCommittee, RetireStakePool, UnregisterCredential, UnregisterDelegateRepresentative, UpdateDelegateRepresentative, } use cardano/credential.{Script, VerificationKey} -use cardano/transaction.{Publishing, ScriptContext, ScriptInfo} +use cardano/transaction.{Transaction} const only0s = #"00000000000000000000000000000000000000000000000000000000" @@ -19,15 +19,19 @@ const only2s = #"22222222222222222222222222222222222222222222222222222222" const only9s = #"9999999999999999999999999999999999999999999999999999999999999999" -validator { - fn script(_tmp1: Void, ctx: ScriptContext) -> Bool { - assert_script_info(ctx.info) +validator purposes { + publish( + _redeemer: Void, + certificate: Certificate, + transaction: Transaction, + ) -> Bool { + assert_script_info(certificate) - let certificates = ctx.transaction.certificates + let certificates = transaction.certificates - expect Some(10_000_000) = ctx.transaction.current_treasury_amount + expect Some(10_000_000) = transaction.current_treasury_amount - expect Some(14) = ctx.transaction.treasury_donation + expect Some(14) = transaction.treasury_donation expect Some(RegisterCredential { credential: Script(only2s), deposit: None }) == list.at( @@ -67,7 +71,7 @@ validator { Some( RegisterCredential { credential: VerificationKey(only0s), - deposit: Some(3_000_000), + deposit: None, }, ) == list.at(certificates, 5) @@ -75,7 +79,7 @@ validator { Some( UnregisterCredential { credential: VerificationKey(only0s), - refund: Some(3_000_000), + refund: None, }, ) == list.at(certificates, 6) @@ -197,10 +201,14 @@ validator { True } + + else(_ctx) { + fail + } } -fn assert_script_info(info: ScriptInfo) { - expect Publishing(20, DelegateCredential { credential, delegate }) = info +fn assert_script_info(certificate: Certificate) { + expect DelegateCredential { credential, delegate } = certificate expect DelegateBlockProduction { stake_pool: only1s } == delegate expect Script(..) = credential Void diff --git a/examples/acceptance_tests/script_context/v3/validators/mint.ak b/examples/acceptance_tests/script_context/v3/validators/mint.ak index 51b1d80f..093dc900 100644 --- a/examples/acceptance_tests/script_context/v3/validators/mint.ak +++ b/examples/acceptance_tests/script_context/v3/validators/mint.ak @@ -3,8 +3,8 @@ use aiken/collection/list use cardano/assets.{PolicyId, Value} use cardano/credential use cardano/transaction.{ - DatumHash, Input, Mint, Minting, NoDatum, Output, OutputReference, - ScriptContext, ScriptInfo, ScriptPurpose, + DatumHash, Input, Mint, NoDatum, Output, OutputReference, ScriptPurpose, + Transaction, } const null28 = #"00000000000000000000000000000000000000000000000000000000" @@ -15,16 +15,24 @@ const null32 = const void_hash = #"923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" -validator { - fn mint_1(_tmp2: Data, ctx: ScriptContext) { - let our_policy_id = assert_script_info(ctx.info) - let other_policy_id = assert_redeemers(ctx.transaction.redeemers) - assert_outputs(ctx.transaction.outputs, our_policy_id, other_policy_id) - assert_mint(ctx.transaction.mint, our_policy_id, other_policy_id) - assert_reference_inputs(ctx.transaction.reference_inputs) - assert_datums(ctx.transaction.datums) +validator test_1 { + mint(_rdmr: Data, our_policy_id: PolicyId, transaction: Transaction) { + let other_policy_id = assert_redeemers(transaction.redeemers) + + assert_outputs(transaction.outputs, our_policy_id, other_policy_id) + + assert_mint(transaction.mint, our_policy_id, other_policy_id) + + assert_reference_inputs(transaction.reference_inputs) + + assert_datums(transaction.datums) + True } + + else(_ctx) { + fail + } } fn assert_reference_inputs(inputs: List) -> Void { @@ -46,11 +54,6 @@ fn assert_reference_inputs(inputs: List) -> Void { Void } -fn assert_script_info(info: ScriptInfo) -> PolicyId { - expect Minting(policy_id) = info - policy_id -} - fn assert_redeemers(redeemers: Pairs) -> PolicyId { expect [Pair(Mint(other_policy_id), data), _] = redeemers expect Void = data @@ -120,9 +123,22 @@ fn assert_mint(mint: Value, our_policy_id: PolicyId, other_policy_id: PolicyId) Void } -validator { - fn mint_2(_tmp2: Void, _ctx: ScriptContext) { - trace @"_____mint_2_____" +// NOTE: It is imperative that test2 has a lower hash value than test1; as +// otherwise the redeemer will point to the wrong redeemer. So the trace +// below is meant to generate a small-enough hash... If this test fails +// after some code-gen changes, it's probably because the new hash is +// larger. +/// +// How to fix? +// Change the traced string down below in hope to get a +// smaller hash. +validator test_2 { + mint(_tmp2: Void, _policy_id: PolicyId, _transaction: Transaction) { + trace @"slfhioer7w8yru" True } + + else(_ctx) { + fail + } } diff --git a/examples/acceptance_tests/script_context/v3/validators/proposing_all.ak b/examples/acceptance_tests/script_context/v3/validators/proposing_all.ak index 7ca68dde..81f620b3 100644 --- a/examples/acceptance_tests/script_context/v3/validators/proposing_all.ak +++ b/examples/acceptance_tests/script_context/v3/validators/proposing_all.ak @@ -6,18 +6,22 @@ use cardano/governance.{ HardFork, NewConstitution, NicePoll, NoConfidence, ProposalProcedure, ProtocolVersion, TreasuryWithdrawal, } -use cardano/transaction.{Propose, Redeemer, ScriptContext, ScriptPurpose} +use cardano/transaction.{Propose, Redeemer, ScriptPurpose, Transaction} const null28 = #"00000000000000000000000000000000000000000000000000000000" const null32 = #"0000000000000000000000000000000000000000000000000000000000000000" -validator { - fn guardrails(_tmp1: Void, ctx: ScriptContext) -> Bool { - let procedures = ctx.transaction.proposal_procedures +validator guardrails { + propose( + _redeemer: Void, + _: ProposalProcedure, + transaction: Transaction, + ) -> Bool { + let procedures = transaction.proposal_procedures - assert_redeemers(ctx.transaction.redeemers) + assert_redeemers(transaction.redeemers) assert_proposal_procedure( list.at(procedures, 0), @@ -118,6 +122,10 @@ validator { True } + + else(_ctx) { + fail + } } fn assert_redeemers(redeemers: Pairs) -> Void { diff --git a/examples/acceptance_tests/script_context/v3/validators/proposing_pparams.ak b/examples/acceptance_tests/script_context/v3/validators/proposing_pparams.ak index 72f984dc..72d398c0 100644 --- a/examples/acceptance_tests/script_context/v3/validators/proposing_pparams.ak +++ b/examples/acceptance_tests/script_context/v3/validators/proposing_pparams.ak @@ -17,21 +17,22 @@ use cardano/governance/protocol_parameters.{ stake_pool_operator_voting_thresholds, stake_pool_pledge_influence, stake_pool_retirement_horizon, treasury_expansion, } -use cardano/transaction.{Proposing, ScriptContext} +use cardano/transaction.{Transaction} -validator { - fn guardrails(_tmp1: Void, ctx: ScriptContext) -> Bool { - expect Proposing( - 0, - ProposalProcedure { - governance_action: ProtocolParameters { - ancestor: None, - guardrails: Some(..), - new_parameters, - }, - .. +validator guardrails { + propose( + _redeemer: Void, + proposal: ProposalProcedure, + _transaction: Transaction, + ) -> Bool { + expect ProposalProcedure { + governance_action: ProtocolParameters { + ancestor: None, + guardrails: Some(..), + new_parameters, }, - ) = ctx.info + .. + } = proposal expect ( new_parameters |> min_fee_coefficient ) == Some(44) @@ -127,6 +128,10 @@ validator { True } + + else(_ctx) { + fail + } } fn expect_rational(numerator: Int, denominator: Int) -> Rational { diff --git a/examples/acceptance_tests/script_context/v3/validators/simple_spend.ak b/examples/acceptance_tests/script_context/v3/validators/simple_spend.ak index fe628189..76fa6112 100644 --- a/examples/acceptance_tests/script_context/v3/validators/simple_spend.ak +++ b/examples/acceptance_tests/script_context/v3/validators/simple_spend.ak @@ -2,32 +2,40 @@ use aiken/collection/dict use cardano/assets use cardano/credential.{Address, Script} use cardano/transaction.{ - InlineDatum, Input, Output, OutputReference, ScriptContext, ScriptInfo, - ScriptPurpose, Spend, Spending, + InlineDatum, Input, Output, OutputReference, ScriptPurpose, Spend, Transaction, } -validator { - fn spend(_tmp1: Void, _tmp2: Void, ctx: ScriptContext) { - assert_transaction_id(ctx.transaction.id) +validator simple_spend { + spend( + _datum: Option, + _redeemer: Void, + output_ref: OutputReference, + transaction: Transaction, + ) { + assert_transaction_id(transaction.id) - assert_script_info(ctx.info) + assert_script_info(output_ref) - assert_inputs(ctx.transaction.inputs) + assert_inputs(transaction.inputs) - expect [] = ctx.transaction.outputs + expect [] = transaction.outputs - expect [] = ctx.transaction.reference_inputs + expect [] = transaction.reference_inputs - expect [] = ctx.transaction.extra_signatories + expect [] = transaction.extra_signatories - expect 42 == ctx.transaction.fee + expect 42 == transaction.fee - assert_redeemers(ctx.transaction.redeemers) + assert_redeemers(transaction.redeemers) - expect [] == dict.to_pairs(ctx.transaction.datums) + expect [] == dict.to_pairs(transaction.datums) True } + + else(_ctx) { + fail + } } fn assert_transaction_id(id: ByteArray) { @@ -36,15 +44,12 @@ fn assert_transaction_id(id: ByteArray) { Void } -fn assert_script_info(info: ScriptInfo) { +fn assert_script_info(info: OutputReference) { expect - Spending( - OutputReference { - transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000", - output_index: 0, - }, - Some(void()), - ) == info + OutputReference { + transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000", + output_index: 0, + } == info Void } diff --git a/examples/acceptance_tests/script_context/v3/validators/voting.ak b/examples/acceptance_tests/script_context/v3/validators/voting.ak index cce7c58f..5ee617ba 100644 --- a/examples/acceptance_tests/script_context/v3/validators/voting.ak +++ b/examples/acceptance_tests/script_context/v3/validators/voting.ak @@ -2,9 +2,9 @@ use aiken/collection/list use cardano/credential.{Script, VerificationKey} use cardano/governance.{ Abstain, ConstitutionalCommitteeMember, DelegateRepresentative, - GovernanceActionId, No, StakePool, Yes, + GovernanceActionId, No, StakePool, Voter, Yes, } -use cardano/transaction.{ScriptContext} +use cardano/transaction.{Transaction} type Foo { Foo(Int) @@ -21,11 +21,11 @@ const only8s = const only9s = #"9999999999999999999999999999999999999999999999999999999999999999" -validator { - fn script(_tmp0: Data, ctx: ScriptContext) { - assert_redeemer(ctx.redeemer) +validator purposes { + vote(redeemer: Data, _voter: Voter, transaction: Transaction) { + assert_redeemer(redeemer) - let votes = ctx.transaction.votes + let votes = transaction.votes expect Some( Pair(ConstitutionalCommitteeMember(Script(..)), @@ -35,14 +35,18 @@ validator { expect Some( - Pair(ConstitutionalCommitteeMember(VerificationKey(only0s)), - [ - Pair(GovernanceActionId { - transaction: only9s, - proposal_procedure: 152, - }, - No), - ]), + Pair( + ConstitutionalCommitteeMember(VerificationKey(only0s)), + [ + Pair( + GovernanceActionId { + transaction: only9s, + proposal_procedure: 152, + }, + No, + ), + ], + ), ) == list.at(votes, 1) expect Some(Pair(DelegateRepresentative(Script(..)), [_, ..])) = @@ -50,15 +54,23 @@ validator { expect Some( - Pair(DelegateRepresentative(VerificationKey(only0s)), - [ - Pair(GovernanceActionId { transaction: only7s, proposal_procedure: 2 }, - Abstain), - Pair(GovernanceActionId { transaction: only8s, proposal_procedure: 1 }, - Abstain), - Pair(GovernanceActionId { transaction: only9s, proposal_procedure: 0 }, - Abstain), - ]), + Pair( + DelegateRepresentative(VerificationKey(only0s)), + [ + Pair( + GovernanceActionId { transaction: only7s, proposal_procedure: 2 }, + Abstain, + ), + Pair( + GovernanceActionId { transaction: only8s, proposal_procedure: 1 }, + Abstain, + ), + Pair( + GovernanceActionId { transaction: only9s, proposal_procedure: 0 }, + Abstain, + ), + ], + ), ) == list.at(votes, 3) expect Some(Pair(StakePool(pool_id), [_, ..])) = list.at(votes, 4) @@ -66,6 +78,10 @@ validator { True } + + else(_ctx) { + fail + } } fn assert_redeemer(data: Data) { diff --git a/examples/acceptance_tests/script_context/v3/validators/withdraw.ak b/examples/acceptance_tests/script_context/v3/validators/withdraw.ak index 211f774b..f8d663ae 100644 --- a/examples/acceptance_tests/script_context/v3/validators/withdraw.ak +++ b/examples/acceptance_tests/script_context/v3/validators/withdraw.ak @@ -1,24 +1,25 @@ use aiken/collection/list use aiken/interval -use cardano/credential.{Address, Inline, Pointer, Script, VerificationKey} -use cardano/transaction.{ScriptContext, Withdrawing} +use cardano/credential.{ + Address, Credential, Inline, Pointer, Script, VerificationKey, +} +use cardano/transaction.{Transaction} const only0s = #"00000000000000000000000000000000000000000000000000000000" const only1s = #"11111111111111111111111111111111111111111111111111111111" -validator { - fn spend(_tmp0: Void, _tmp1: Void, _ctx: Data) { +validator thing { + spend(_datum: Option, _rdmr: Void, _oref: Data, _tx: Data) { True } - fn withdraw(_tmp0: Void, ctx: ScriptContext) { - expect Withdrawing(Script(my_script_hash)) = ctx.info + withdraw(_rdmr: Void, credential: Credential, transaction: Transaction) { + expect Script(my_script_hash) = credential - expect - interval.entirely_before(1596059092000) == ctx.transaction.validity_range + expect interval.entirely_before(1596059092000) == transaction.validity_range - let addresses = list.map(ctx.transaction.outputs, fn(out) { out.address }) + let addresses = list.map(transaction.outputs, fn(out) { out.address }) expect Some( @@ -45,8 +46,12 @@ validator { ) == list.at(addresses, 2) expect - [Pair(Script(my_script_hash), 0), Pair(VerificationKey(only0s), 14)] == ctx.transaction.withdrawals + [Pair(Script(my_script_hash), 0), Pair(VerificationKey(only0s), 14)] == transaction.withdrawals True } + + else(_ctx) { + fail + } } diff --git a/examples/gift_card/aiken.lock b/examples/gift_card/aiken.lock index 2f7651e9..312fac93 100644 --- a/examples/gift_card/aiken.lock +++ b/examples/gift_card/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1714852860, nanos_since_epoch = 160588000 }, "5ee55dc5ccf269bb493f4cacb32096f0191a6adb2ef39d62a1f79b8c5a8fcc7f"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724778883, nanos_since_epoch = 61117000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/gift_card/aiken.toml b/examples/gift_card/aiken.toml index 1d19f44b..1df9fde6 100644 --- a/examples/gift_card/aiken.toml +++ b/examples/gift_card/aiken.toml @@ -10,5 +10,5 @@ platform = 'github' [[dependencies]] name = 'aiken-lang/stdlib' -version = 'main' +version = 'v2' source = 'github' diff --git a/examples/gift_card/validators/multi.ak b/examples/gift_card/validators/multi.ak index 2d78aa34..41af34cd 100644 --- a/examples/gift_card/validators/multi.ak +++ b/examples/gift_card/validators/multi.ak @@ -1,35 +1,32 @@ use aiken/builtin -use aiken/bytearray -use aiken/dict +use aiken/collection/dict +use aiken/collection/list use aiken/hash.{blake2b_256} -use aiken/list -use aiken/transaction.{ - InlineDatum, Input, Output, ScriptContext, Spend, Transaction, +use aiken/primitive/bytearray +use cardano/assets.{PolicyId} +use cardano/credential.{Address, PaymentCredential, Script} +use cardano/transaction.{ + InlineDatum, Input, Output, OutputReference, Transaction, } as tx -use aiken/transaction/credential.{Address, PaymentCredential, ScriptCredential} -use aiken/transaction/value -type Action { +pub type Action { Mint(Int) Burn } -type SpendTokenName = +pub type SpendTokenName = ByteArray -validator(creator: ByteArray) { - fn redeem( +validator redeem(creator: ByteArray) { + spend( // Each spend input checks for a token name matching the datum being burned - datum: SpendTokenName, + datum: Option, _r: Data, - ctx: ScriptContext, + own_ref: OutputReference, + transaction: Transaction, ) { - let ScriptContext { transaction, purpose } = ctx - let Transaction { inputs, mint, .. } = transaction - expect Spend(own_ref) = purpose - expect Some(own_input) = list.find(inputs, fn(input) { input.output_reference == own_ref }) @@ -38,48 +35,46 @@ validator(creator: ByteArray) { .. } = own_input - expect ScriptCredential(own_validator_hash) = payment_credential + expect Script(own_validator_hash) = payment_credential + expect Some(datum) = datum ( mint - |> value.from_minted_value - |> value.quantity_of(own_validator_hash, datum) + |> assets.quantity_of(own_validator_hash, datum) ) == -1 } - fn gift_card(rdmr: Action, ctx: ScriptContext) -> Bool { - // get values from transaction and purpose - let ScriptContext { transaction, purpose } = ctx - - expect tx.Mint(policy_id) = purpose - + mint(rdmr: Action, policy_id: PolicyId, transaction: Transaction) { let Transaction { inputs, mint, extra_signatories, outputs, .. } = transaction let minted_assets = mint - |> value.from_minted_value - |> value.tokens(policy_id) + |> assets.tokens(policy_id) |> dict.to_pairs() when rdmr is { Mint(total) -> { expect [input, ..] = inputs + // Base is created from serializing a utxo ref being spent. Thus this guarantees a unique base let base = builtin.serialise_data(input.output_reference) + // Create a list of expected token names let expected_minted_token_names = create_expected_minted_nfts(base, total, []) + // Check contract creator is a signer of this tx let signature_check = list.any(extra_signatories, fn(n) { creator == n }) + // Support multiple gift card creation by allowing a // 'number of tokens minted' == 'outputs with datum being token name' signature_check && check_mint_and_outputs( minted_assets, outputs, expected_minted_token_names, - ScriptCredential(policy_id), + Script(policy_id), ) } Burn -> @@ -92,6 +87,10 @@ validator(creator: ByteArray) { ) } } + + else(_) { + fail + } } fn insert(self: List, e: a, compare: fn(a, a) -> Ordering) -> List { diff --git a/examples/gift_card/validators/oneshot.ak b/examples/gift_card/validators/oneshot.ak index a1fcc4fe..2ce4001c 100644 --- a/examples/gift_card/validators/oneshot.ak +++ b/examples/gift_card/validators/oneshot.ak @@ -1,50 +1,51 @@ -use aiken/dict -use aiken/list -use aiken/transaction.{OutputReference, ScriptContext, Transaction} as tx -use aiken/transaction/value +use aiken/collection/dict +use aiken/collection/list +use cardano/assets.{PolicyId} +use cardano/transaction.{OutputReference, Transaction} as tx -type Action { +pub type Action { Mint Burn } -validator(token_name: ByteArray, utxo_ref: OutputReference) { - fn gift_card(rdmr: Action, ctx: ScriptContext) -> Bool { - let ScriptContext { transaction, purpose } = ctx - - expect tx.Mint(policy_id) = purpose - +validator gift_card(token_name: ByteArray, utxo_ref: OutputReference) { + mint(rdmr: Action, policy_id: PolicyId, transaction: Transaction) { let Transaction { inputs, mint, .. } = transaction expect [Pair(asset_name, amount)] = mint - |> value.from_minted_value - |> value.tokens(policy_id) + |> assets.tokens(policy_id) |> dict.to_pairs() when rdmr is { Mint -> { expect Some(_input) = list.find(inputs, fn(input) { input.output_reference == utxo_ref }) + amount == 1 && asset_name == token_name } Burn -> amount == -1 && asset_name == token_name } } + + else(_) { + fail + } } -validator(token_name: ByteArray, policy_id: ByteArray) { - fn redeem(_d: Data, _r: Data, ctx: ScriptContext) -> Bool { - let ScriptContext { transaction, .. } = ctx - +validator redeem(token_name: ByteArray, policy_id: ByteArray) { + spend(_d, _r, _o_ref: Data, transaction: Transaction) { let Transaction { mint, .. } = transaction expect [Pair(asset_name, amount)] = mint - |> value.from_minted_value - |> value.tokens(policy_id) + |> assets.tokens(policy_id) |> dict.to_pairs() amount == -1 && asset_name == token_name } + + else(_) { + fail + } } diff --git a/examples/hello_world/aiken.lock b/examples/hello_world/aiken.lock index 21fbf8f4..166359d7 100644 --- a/examples/hello_world/aiken.lock +++ b/examples/hello_world/aiken.lock @@ -3,14 +3,14 @@ [[requirements]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" [[packages]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1716400776, nanos_since_epoch = 210636000 }, "6b89f2c51314a7bc2cc377d37c9eade9a4239086fe636ac6030c6979182f1247"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1724595875, nanos_since_epoch = 142190000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] diff --git a/examples/hello_world/aiken.toml b/examples/hello_world/aiken.toml index 3b523f22..db7cce2f 100644 --- a/examples/hello_world/aiken.toml +++ b/examples/hello_world/aiken.toml @@ -1,9 +1,10 @@ name = "aiken-lang/hello_world" version = "1.0.0" +plutusVersion = "v3" licences = ["Apache-2.0"] description = "Aiken contracts for project 'aiken-lang/hello_world'" [[dependencies]] name = "aiken-lang/stdlib" -version = "main" +version = "v2" source = "github" diff --git a/examples/hello_world/plutus.json b/examples/hello_world/plutus.json index a0fab843..835219be 100644 --- a/examples/hello_world/plutus.json +++ b/examples/hello_world/plutus.json @@ -6,12 +6,12 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.19-alpha+d56d518" + "version": "v1.0.31-alpha+0c9ea19" } }, "validators": [ { - "title": "hello_world.spend", + "title": "hello_world.hello_world.spend", "datum": { "title": "datum", "schema": { @@ -24,8 +24,13 @@ "$ref": "#/definitions/hello_world~1Redeemer" } }, - "compiledCode": "58f2010000323232323232323222232325333008323232533300b002100114a06644646600200200644a66602200229404c8c94ccc040cdc78010028a511330040040013014002375c60240026eb0c038c03cc03cc03cc03cc03cc03cc03cc03cc020c008c020014dd71801180400399b8f375c6002600e00a91010d48656c6c6f2c20576f726c6421002300d00114984d958c94ccc020cdc3a400000226464a66601a601e0042930b1bae300d00130060041630060033253330073370e900000089919299980618070010a4c2c6eb8c030004c01401058c01400c8c014dd5000918019baa0015734aae7555cf2ab9f5742ae881", - "hash": "6fb13cf9efdbe986e784d1983b21d3fb90231c1745925f536a820fb4" + "compiledCode": "59011d0100003232323232323225333002323232323253330073370e900118041baa0011323232533300a3370e900018059baa005132533300e0011613253333330120011616161613253330103012003132533300e3370e900018079baa005132533300f002100114a06644646600200200644a66602a00229404c94ccc04ccdc79bae301700200414a2266006006002602e0026eb0c048c04cc04cc04cc04cc04cc04cc04cc04cc040dd50059bae301230103754602460206ea801458cdc79bae3011300f375401091010d48656c6c6f2c20576f726c64210016375c002601e00260186ea801458c034c038008c030004c024dd50008b1805180580118048009804801180380098021baa00114984d9595cd2ab9d5573caae7d5d0aba25749", + "hash": "a03ed5b0e902c0ab66948c9529cdc8e637b5f0cccce60d2e94904581" + }, + { + "title": "hello_world.hello_world.else", + "compiledCode": "59011d0100003232323232323225333002323232323253330073370e900118041baa0011323232533300a3370e900018059baa005132533300e0011613253333330120011616161613253330103012003132533300e3370e900018079baa005132533300f002100114a06644646600200200644a66602a00229404c94ccc04ccdc79bae301700200414a2266006006002602e0026eb0c048c04cc04cc04cc04cc04cc04cc04cc04cc040dd50059bae301230103754602460206ea801458cdc79bae3011300f375401091010d48656c6c6f2c20576f726c64210016375c002601e00260186ea801458c034c038008c030004c024dd50008b1805180580118048009804801180380098021baa00114984d9595cd2ab9d5573caae7d5d0aba25749", + "hash": "a03ed5b0e902c0ab66948c9529cdc8e637b5f0cccce60d2e94904581" } ], "definitions": { diff --git a/examples/hello_world/validators/hello_world.ak b/examples/hello_world/validators/hello_world.ak index 334aa194..19ccf4ff 100644 --- a/examples/hello_world/validators/hello_world.ak +++ b/examples/hello_world/validators/hello_world.ak @@ -1,23 +1,32 @@ -use aiken/hash.{Blake2b_224, Hash} -use aiken/list -use aiken/transaction.{ScriptContext} -use aiken/transaction/credential.{VerificationKey} +use aiken/collection/list +use cardano/credential.{VerificationKeyHash} +use cardano/transaction.{OutputReference, Transaction} -type Datum { - owner: Hash, +pub type Datum { + owner: VerificationKeyHash, } -type Redeemer { +pub type Redeemer { msg: ByteArray, } -validator { - fn spend(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool { +validator hello_world { + spend( + datum: Option, + redeemer: Redeemer, + _: OutputReference, + transaction: Transaction, + ) -> Bool { let must_say_hello = redeemer.msg == "Hello, World!" - let must_be_signed = - list.has(context.transaction.extra_signatories, datum.owner) + expect Some(Datum { owner }) = datum + + let must_be_signed = list.has(transaction.extra_signatories, owner) must_say_hello && must_be_signed } + + else(_) { + fail + } }