Merge branch 'main' into waalge/bump-cargo2nix

This commit is contained in:
waalge 2023-03-09 09:44:11 +00:00
commit 6817510e2d
21 changed files with 781 additions and 239 deletions

View File

@ -6,6 +6,12 @@
- **aiken**: new command `blueprint convert` - **aiken**: new command `blueprint convert`
### Changed
- **aiken-lang**: block `Data` and `String` from unifying when casting
- **aiken-lang**: remove ability for a type with many variants with matching field labels and types to support field access
- **aiken-project**: tests filtering with `-m` during check now happens in `Project::collect_tests`
## [v0.0.29] - 2023-MM-DD ## [v0.0.29] - 2023-MM-DD
### Added ### Added

View File

@ -117,6 +117,11 @@ pub enum Air {
constr_index: usize, constr_index: usize,
}, },
AssertBool {
scope: Vec<u64>,
is_true: bool,
},
// When // When
When { When {
scope: Vec<u64>, scope: Vec<u64>,
@ -268,6 +273,7 @@ impl Air {
| Air::UnWrapData { scope, .. } | Air::UnWrapData { scope, .. }
| Air::WrapData { scope, .. } | Air::WrapData { scope, .. }
| Air::AssertConstr { scope, .. } | Air::AssertConstr { scope, .. }
| Air::AssertBool { scope, .. }
| Air::When { scope, .. } | Air::When { scope, .. }
| Air::Clause { scope, .. } | Air::Clause { scope, .. }
| Air::ListClause { scope, .. } | Air::ListClause { scope, .. }
@ -375,6 +381,7 @@ impl Air {
| Air::Let { .. } | Air::Let { .. }
| Air::WrapClause { .. } | Air::WrapClause { .. }
| Air::AssertConstr { .. } | Air::AssertConstr { .. }
| Air::AssertBool { .. }
| Air::Finally { .. } | Air::Finally { .. }
| Air::FieldsExpose { .. } => None, | Air::FieldsExpose { .. } => None,

View File

@ -1200,7 +1200,7 @@ pub fn find_and_replace_generics(tipo: &mut Arc<Type>, mono_types: &IndexMap<u64
} }
} }
pub fn get_generics_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> { pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
let mut generics_ids = vec![]; let mut generics_ids = vec![];
if let Some(id) = tipo.get_generic() { if let Some(id) = tipo.get_generic() {
@ -1213,7 +1213,7 @@ pub fn get_generics_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)>
.iter() .iter()
.zip(param.get_inner_types().iter()) .zip(param.get_inner_types().iter())
{ {
generics_ids.append(&mut get_generics_and_type(tipo, param_type)); generics_ids.append(&mut get_generic_id_and_type(tipo, param_type));
} }
generics_ids generics_ids
} }
@ -1990,7 +1990,7 @@ pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: IndexMap<DataTypeKey,
for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) { for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) {
let mut map = mono_types.into_iter().collect_vec(); let mut map = mono_types.into_iter().collect_vec();
map.append(&mut get_generics_and_type(tipo, &param)); map.append(&mut get_generic_id_and_type(tipo, &param));
mono_types = map.into_iter().collect(); mono_types = map.into_iter().collect();
} }

View File

@ -177,6 +177,7 @@ impl<'a> Environment<'a> {
}, },
); );
} }
Ok(Some(fields)) Ok(Some(fields))
} }
@ -1289,6 +1290,7 @@ impl<'a> Environment<'a> {
&& !(t1.is_unbound() || t2.is_unbound()) && !(t1.is_unbound() || t2.is_unbound())
&& !(t1.is_function() || t2.is_function()) && !(t1.is_function() || t2.is_function())
&& !(t1.is_generic() || t2.is_generic()) && !(t1.is_generic() || t2.is_generic())
&& !(t1.is_string() || t2.is_string())
{ {
return Ok(()); return Ok(());
} }
@ -1779,44 +1781,22 @@ fn get_compatible_record_fields<A>(
) -> Vec<(usize, &str, &Annotation)> { ) -> Vec<(usize, &str, &Annotation)> {
let mut compatible = vec![]; let mut compatible = vec![];
if constructors.len() > 1 {
return compatible;
}
let first = match constructors.get(0) { let first = match constructors.get(0) {
Some(first) => first, Some(first) => first,
None => return compatible, None => return compatible,
}; };
'next_argument: for (index, first_argument) in first.arguments.iter().enumerate() { for (index, first_argument) in first.arguments.iter().enumerate() {
// Fields without labels do not have accessors // Fields without labels do not have accessors
let label = match first_argument.label.as_ref() { let label = match first_argument.label.as_ref() {
Some(label) => label.as_str(), Some(label) => label.as_str(),
None => continue 'next_argument, None => continue,
}; };
// Check each variant to see if they have an field in the same position
// with the same label and the same type
for constructor in constructors.iter().skip(1) {
// The field must exist in all variants
let argument = match constructor.arguments.get(index) {
Some(argument) => argument,
None => continue 'next_argument,
};
// The labels must be the same
if argument.label != first_argument.label {
continue 'next_argument;
}
// The types must be the same
if !argument
.annotation
.is_logically_equal(&first_argument.annotation)
{
continue 'next_argument;
}
}
// The previous loop did not find any incompatible fields in the other
// variants so this field is compatible across variants and we should
// generate an accessor for it.
compatible.push((index, label, &first_argument.annotation)) compatible.push((index, label, &first_argument.annotation))
} }

View File

@ -264,8 +264,9 @@ You can use '{discard}' and numbers to distinguish between similar names.
}, },
#[error( #[error(
"I saw a {} fields in a context where there should be {}.\n", "I saw {} field{} in a context where there should be {}.\n",
given.if_supports_color(Stdout, |s| s.purple()), given.if_supports_color(Stdout, |s| s.purple()),
if *given <= 1 { "" } else { "s"},
expected.if_supports_color(Stdout, |s| s.purple()), expected.if_supports_color(Stdout, |s| s.purple()),
)] )]
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types"))] #[diagnostic(url("https://aiken-lang.org/language-tour/custom-types"))]
@ -744,7 +745,7 @@ Perhaps, try the following:
#[diagnostic(code("unknown::record_field"))] #[diagnostic(code("unknown::record_field"))]
#[diagnostic(help( #[diagnostic(help(
"{}", "{}",
suggest_neighbor(label, fields.iter(), "Did you forget to make it public?") suggest_neighbor(label, fields.iter(), "Did you forget to make it public?\n\nAlso record access is only supported on types with one constructor.")
))] ))]
UnknownRecordField { UnknownRecordField {
#[label] #[label]

View File

@ -26,7 +26,7 @@ use crate::{
builder::{ builder::{
check_replaceable_opaque_type, check_when_pattern_needs, constants_ir, check_replaceable_opaque_type, check_when_pattern_needs, constants_ir,
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor, convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
get_generics_and_type, handle_clause_guard, handle_func_dependencies_ir, get_generic_id_and_type, handle_clause_guard, handle_func_dependencies_ir,
handle_recursion_ir, list_access_to_uplc, lookup_data_type_by_tipo, monomorphize, handle_recursion_ir, list_access_to_uplc, lookup_data_type_by_tipo, monomorphize,
rearrange_clauses, replace_opaque_type, wrap_validator_args, AssignmentProperties, rearrange_clauses, replace_opaque_type, wrap_validator_args, AssignmentProperties,
ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
@ -2056,66 +2056,78 @@ impl<'a> CodeGenerator<'a> {
scope: scope.clone(), scope: scope.clone(),
check_last_item: false, check_last_item: false,
}); });
} else { } else if !tipo.is_bool() {
pattern_vec.push(Air::Let { pattern_vec.push(Air::Let {
scope: scope.clone(), scope: scope.clone(),
name: "_".to_string(), name: "_".to_string(),
}); });
} }
if matches!(assignment_properties.kind, AssignmentKind::Expect) { match assignment_properties.kind {
let data_type = AssignmentKind::Let => {
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); pattern_vec.append(values);
}
AssignmentKind::Expect => {
if tipo.is_bool() {
pattern_vec.push(Air::AssertBool {
scope,
is_true: constr_name == "True",
});
let (index, _) = data_type pattern_vec.append(values);
.constructors } else {
.iter() let data_type =
.enumerate() lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
.find(|(_, constr)| &constr.name == constr_name)
.unwrap();
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next()); let (index, _) = data_type
.constructors
.iter()
.enumerate()
.find(|(_, constr)| &constr.name == constr_name)
.unwrap();
pattern_vec.push(Air::Let { let constr_name = format!("__{}_{}", constr_name, self.id_gen.next());
scope: scope.clone(),
name: constr_name.clone(),
});
pattern_vec.append(values); pattern_vec.push(Air::Let {
scope: scope.clone(),
name: constr_name.clone(),
});
let mut scope = scope; pattern_vec.append(values);
scope.push(self.id_gen.next());
pattern_vec.push(Air::AssertConstr { let mut scope = scope;
scope: scope.clone(), scope.push(self.id_gen.next());
constr_index: index,
});
pattern_vec.push(Air::Var { pattern_vec.push(Air::AssertConstr {
scope: scope.clone(), scope: scope.clone(),
constructor: ValueConstructor::public( constr_index: index,
tipo.clone().into(), });
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: constr_name.clone(),
variant_name: String::new(),
});
pattern_vec.push(Air::Var { pattern_vec.push(Air::Var {
scope, scope: scope.clone(),
constructor: ValueConstructor::public( constructor: ValueConstructor::public(
tipo.clone().into(), tipo.clone().into(),
ValueConstructorVariant::LocalVariable { ValueConstructorVariant::LocalVariable {
location: Span::empty(), location: Span::empty(),
}, },
), ),
name: constr_name, name: constr_name.clone(),
variant_name: String::new(), variant_name: String::new(),
}); });
} else {
pattern_vec.append(values); pattern_vec.push(Air::Var {
scope,
constructor: ValueConstructor::public(
tipo.clone().into(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: constr_name,
variant_name: String::new(),
});
}
}
} }
pattern_vec.append(&mut nested_pattern); pattern_vec.append(&mut nested_pattern);
@ -3275,18 +3287,24 @@ impl<'a> CodeGenerator<'a> {
let param_types = constructor.tipo.arg_types().unwrap(); let param_types = constructor.tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new(); let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
let mut map = mono_types.into_iter().collect_vec();
for (index, arg) in function.arguments.iter().enumerate() { for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() { if arg.tipo.is_generic() {
let mut map = mono_types.into_iter().collect_vec();
let param_type = &param_types[index]; let param_type = &param_types[index];
map.append(&mut get_generics_and_type(&arg.tipo, param_type)); map.append(&mut get_generic_id_and_type(&arg.tipo, param_type));
mono_types = map.into_iter().collect();
} }
} }
if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut get_generic_id_and_type(&function.return_type, ret))
}
}
mono_types = map.into_iter().collect();
let (variant_name, func_ir) = let (variant_name, func_ir) =
monomorphize(func_ir, mono_types, &constructor.tipo); monomorphize(func_ir, mono_types, &constructor.tipo);
@ -3347,23 +3365,32 @@ impl<'a> CodeGenerator<'a> {
} else if let (Some(function), Type::Fn { .. }) = } else if let (Some(function), Type::Fn { .. }) =
(function, &*tipo) (function, &*tipo)
{ {
let param_types = tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> = let mut mono_types: IndexMap<u64, Arc<Type>> =
IndexMap::new(); IndexMap::new();
let mut map = mono_types.into_iter().collect_vec();
let param_types = tipo.arg_types().unwrap();
for (index, arg) in function.arguments.iter().enumerate() { for (index, arg) in function.arguments.iter().enumerate() {
if arg.tipo.is_generic() { if arg.tipo.is_generic() {
let mut map = mono_types.into_iter().collect_vec(); let param_type = &param_types[index];
map.append(&mut get_generics_and_type(
&arg.tipo,
&param_types[index],
));
mono_types = map.into_iter().collect(); map.append(&mut get_generic_id_and_type(
&arg.tipo, param_type,
));
} }
} }
if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut get_generic_id_and_type(
&function.return_type,
ret,
))
}
}
mono_types = map.into_iter().collect();
let mut func_ir = vec![]; let mut func_ir = vec![];
self.build_ir(&function.body, &mut func_ir, scope.to_vec()); self.build_ir(&function.body, &mut func_ir, scope.to_vec());
@ -4310,7 +4337,12 @@ impl<'a> CodeGenerator<'a> {
arg_vec.push(arg_stack.pop().unwrap()); arg_vec.push(arg_stack.pop().unwrap());
} }
for arg in arg_vec.iter() { for (index, arg) in arg_vec.into_iter().enumerate() {
let arg = if matches!(func, DefaultFunction::ChooseData) && index > 0 {
Term::Delay(arg.into())
} else {
arg
};
term = apply_wrap(term, arg.clone()); term = apply_wrap(term, arg.clone());
} }
@ -4425,6 +4457,58 @@ impl<'a> CodeGenerator<'a> {
DefaultFunction::MkCons => { DefaultFunction::MkCons => {
unimplemented!("Use brackets instead."); unimplemented!("Use brackets instead.");
} }
DefaultFunction::IfThenElse
| DefaultFunction::ChooseList
| DefaultFunction::Trace => unimplemented!("{func:#?}"),
DefaultFunction::ChooseData => {
let temp_vars = (0..func.arity())
.into_iter()
.map(|_| format!("__item_{}", self.id_gen.next()))
.collect_vec();
if count == 0 {
for (index, temp_var) in temp_vars.iter().enumerate() {
term = apply_wrap(
term,
if index > 0 {
Term::Delay(
Term::Var(
Name {
text: temp_var.clone(),
unique: 0.into(),
}
.into(),
)
.into(),
)
} else {
Term::Var(
Name {
text: temp_var.clone(),
unique: 0.into(),
}
.into(),
)
},
);
}
}
term = term.force_wrap();
if count == 0 {
for temp_var in temp_vars.into_iter().rev() {
term = Term::Lambda {
parameter_name: Name {
text: temp_var,
unique: 0.into(),
}
.into(),
body: term.into(),
};
}
}
}
_ => {} _ => {}
} }
arg_stack.push(term); arg_stack.push(term);
@ -4828,7 +4912,7 @@ impl<'a> CodeGenerator<'a> {
Term::Builtin(DefaultFunction::Trace).force_wrap(), Term::Builtin(DefaultFunction::Trace).force_wrap(),
Term::Constant( Term::Constant(
UplcConstant::String( UplcConstant::String(
"Asserted on incorrect constructor variant.".to_string(), "Expected on incorrect constructor variant.".to_string(),
) )
.into(), .into(),
), ),
@ -4851,6 +4935,31 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
} }
Air::AssertBool { is_true, .. } => {
let value = arg_stack.pop().unwrap();
let mut term = arg_stack.pop().unwrap();
let error_term = apply_wrap(
apply_wrap(
Term::Builtin(DefaultFunction::Trace).force_wrap(),
Term::Constant(
UplcConstant::String(
"Expected on incorrect boolean variant.".to_string(),
)
.into(),
),
),
Term::Delay(Term::Error.into()),
)
.force_wrap();
if is_true {
term = delayed_if_else(value, term, error_term);
} else {
term = delayed_if_else(value, error_term, term);
}
arg_stack.push(term);
}
Air::When { Air::When {
subject_name, tipo, .. subject_name, tipo, ..
} => { } => {

View File

@ -250,36 +250,22 @@ impl Annotated<Schema> {
Err(Error::new(ErrorContext::UnboundTypeVariable, type_info)) Err(Error::new(ErrorContext::UnboundTypeVariable, type_info))
} }
}, },
Type::Tuple { elems } => match &elems[..] { Type::Tuple { elems } => {
[left, right] => { let elems = elems
let left = Annotated::from_type(modules, left, type_parameters)? .iter()
.into_data(left) .map(|e| {
.map_err(|e| e.backtrack(type_info))?; Annotated::from_type(modules, e, type_parameters)
let right = Annotated::from_type(modules, right, type_parameters)? .and_then(|s| s.into_data(e).map(|s| s.annotated))
.into_data(right)
.map_err(|e| e.backtrack(type_info))?;
Ok(Schema::Data(Data::List(Items::Many(vec![
left.annotated,
right.annotated,
])))
.into())
}
_ => {
let elems = elems
.iter()
.map(|e| {
Annotated::from_type(modules, e, type_parameters)
.and_then(|s| s.into_data(e).map(|s| s.annotated))
})
.collect::<Result<Vec<_>, _>>()
.map_err(|e| e.backtrack(type_info))?;
Ok(Annotated {
title: Some("Tuple".to_owned()),
description: None,
annotated: Schema::Data(Data::List(Items::Many(elems))),
}) })
} .collect::<Result<Vec<_>, _>>()
}, .map_err(|e| e.backtrack(type_info))?;
Ok(Annotated {
title: Some("Tuple".to_owned()),
description: None,
annotated: Schema::Data(Data::List(Items::Many(elems))),
})
}
Type::Fn { .. } => Err(Error::new(ErrorContext::UnexpectedFunction, type_info)), Type::Fn { .. } => Err(Error::new(ErrorContext::UnexpectedFunction, type_info)),
} }
} }

View File

@ -470,6 +470,7 @@ mod test {
"title": "test_module.spend", "title": "test_module.spend",
"hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc", "hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc",
"datum": { "datum": {
"title": "Tuple",
"schema": { "schema": {
"dataType": "list", "dataType": "list",
"items": [ "items": [

View File

@ -575,22 +575,40 @@ fn new_timestamp() -> Duration {
} }
fn find_modules_prefix(modules: &[DocLink]) -> String { fn find_modules_prefix(modules: &[DocLink]) -> String {
modules do_find_modules_prefix("", modules)
}
fn do_find_modules_prefix(current_prefix: &str, modules: &[DocLink]) -> String {
let prefix = modules
.iter() .iter()
.fold(None, |previous_prefix, module| { .fold(None, |previous_prefix, module| {
let prefix = module let name = module.name.strip_prefix(current_prefix).unwrap_or_default();
.name let name = if name.starts_with('/') {
.split('/') name.strip_prefix('/').unwrap_or_default()
.next() } else {
.unwrap_or_default() name
.to_string(); };
let prefix = name.split('/').next().unwrap_or_default().to_string();
match previous_prefix { match previous_prefix {
None if prefix != module.name => Some(prefix), None if prefix != module.name => Some(prefix),
Some(..) if Some(prefix) == previous_prefix => previous_prefix, Some(..) if Some(prefix) == previous_prefix => previous_prefix,
_ => Some(String::new()), _ => Some(String::new()),
} }
}) })
.unwrap_or_default() .unwrap_or_default();
if prefix.is_empty() {
current_prefix.to_string()
} else {
let mut current_prefix = current_prefix.to_owned();
if !current_prefix.is_empty() {
current_prefix.push('/');
}
current_prefix.push_str(&prefix);
do_find_modules_prefix(&current_prefix, modules)
}
} }
#[test] #[test]
@ -602,7 +620,7 @@ fn find_modules_prefix_test() {
name: "aiken/list".to_string(), name: "aiken/list".to_string(),
path: String::new() path: String::new()
}]), }]),
"aiken".to_string() "aiken/list".to_string()
); );
assert_eq!( assert_eq!(
@ -620,7 +638,7 @@ fn find_modules_prefix_test() {
path: String::new() path: String::new()
}, },
DocLink { DocLink {
name: "aiken/byte_array".to_string(), name: "aiken/bytearray".to_string(),
path: String::new(), path: String::new(),
} }
]), ]),
@ -634,7 +652,56 @@ fn find_modules_prefix_test() {
path: String::new() path: String::new()
}, },
DocLink { DocLink {
name: "foo/byte_array".to_string(), name: "foo/bytearray".to_string(),
path: String::new(),
}
]),
"".to_string()
);
}
#[test]
fn find_modules_prefix_test_2() {
assert_eq!(
find_modules_prefix(&[
DocLink {
name: "aiken/trees/bst".to_string(),
path: String::new()
},
DocLink {
name: "aiken/trees/mt".to_string(),
path: String::new(),
}
]),
"aiken/trees".to_string()
);
assert_eq!(
find_modules_prefix(&[
DocLink {
name: "aiken/trees/bst".to_string(),
path: String::new()
},
DocLink {
name: "aiken/trees/mt".to_string(),
path: String::new(),
},
DocLink {
name: "aiken/sequences".to_string(),
path: String::new(),
}
]),
"aiken".to_string()
);
assert_eq!(
find_modules_prefix(&[
DocLink {
name: "aiken".to_string(),
path: String::new()
},
DocLink {
name: "aiken/prelude".to_string(),
path: String::new(), path: String::new(),
} }
]), ]),

View File

@ -175,7 +175,10 @@ where
let doc_files = docs::generate_all( let doc_files = docs::generate_all(
&self.root, &self.root,
&self.config, &self.config,
self.checked_modules.values().collect(), self.checked_modules
.values()
.filter(|CheckedModule { package, .. }| package == &self.config.name.to_string())
.collect(),
); );
for file in doc_files { for file in doc_files {
@ -288,13 +291,13 @@ where
verbose, verbose,
exact_match, exact_match,
} => { } => {
let tests = self.collect_tests(verbose)?; let tests = self.collect_tests(verbose, match_tests, exact_match)?;
if !tests.is_empty() { if !tests.is_empty() {
self.event_listener.handle_event(Event::RunningTests); self.event_listener.handle_event(Event::RunningTests);
} }
let results = self.eval_scripts(tests, match_tests, exact_match); let results = self.eval_scripts(tests);
let errors: Vec<Error> = results let errors: Vec<Error> = results
.iter() .iter()
@ -586,20 +589,84 @@ where
Ok(()) Ok(())
} }
fn collect_tests(&mut self, verbose: bool) -> Result<Vec<Script>, Error> { fn collect_tests(
&mut self,
verbose: bool,
match_tests: Option<Vec<String>>,
exact_match: bool,
) -> Result<Vec<Script>, Error> {
let mut scripts = Vec::new(); let mut scripts = Vec::new();
for module in self.checked_modules.values() {
if module.package != self.config.name.to_string() { let match_tests = match_tests.map(|mt| {
mt.into_iter()
.map(|match_test| {
let mut match_split_dot = match_test.split('.');
let match_module = if match_test.contains('.') || match_test.contains('/') {
match_split_dot.next().unwrap_or("")
} else {
""
};
let match_names = match_split_dot.next().map(|names| {
let names = names.replace(&['{', '}'][..], "");
let names_split_comma = names.split(',');
names_split_comma.map(str::to_string).collect()
});
(match_module.to_string(), match_names)
})
.collect::<Vec<(String, Option<Vec<String>>)>>()
});
for checked_module in self.checked_modules.values() {
if checked_module.package != self.config.name.to_string() {
continue; continue;
} }
for def in module.ast.definitions() {
for def in checked_module.ast.definitions() {
if let Definition::Test(func) = def { if let Definition::Test(func) = def {
scripts.push((module.input_path.clone(), module.name.clone(), func)) if let Some(match_tests) = &match_tests {
let is_match = match_tests.iter().any(|(module, names)| {
let matched_module =
module.is_empty() || checked_module.name.contains(module);
let matched_name = match names {
None => true,
Some(names) => names.iter().any(|name| {
if exact_match {
name == &func.name
} else {
func.name.contains(name)
}
}),
};
matched_module && matched_name
});
if is_match {
scripts.push((
checked_module.input_path.clone(),
checked_module.name.clone(),
func,
))
}
} else {
scripts.push((
checked_module.input_path.clone(),
checked_module.name.clone(),
func,
))
}
} }
} }
} }
let mut programs = Vec::new(); let mut programs = Vec::new();
for (input_path, module_name, func_def) in scripts { for (input_path, module_name, func_def) in scripts {
let Function { let Function {
arguments, arguments,
@ -660,12 +727,7 @@ where
Ok(programs) Ok(programs)
} }
fn eval_scripts( fn eval_scripts(&self, scripts: Vec<Script>) -> Vec<EvalInfo> {
&self,
scripts: Vec<Script>,
match_tests: Option<Vec<String>>,
exact_match: bool,
) -> Vec<EvalInfo> {
use rayon::prelude::*; use rayon::prelude::*;
// TODO: in the future we probably just want to be able to // TODO: in the future we probably just want to be able to
@ -675,55 +737,6 @@ where
cpu: i64::MAX, cpu: i64::MAX,
}; };
let scripts = if let Some(match_tests) = match_tests {
let match_tests: Vec<(&str, Option<Vec<String>>)> = match_tests
.iter()
.map(|match_test| {
let mut match_split_dot = match_test.split('.');
let match_module = if match_test.contains('.') || match_test.contains('/') {
match_split_dot.next().unwrap_or("")
} else {
""
};
let match_names = match_split_dot.next().map(|names| {
let names = names.replace(&['{', '}'][..], "");
let names_split_comma = names.split(',');
names_split_comma.map(str::to_string).collect()
});
(match_module, match_names)
})
.collect();
scripts
.into_iter()
.filter(|script| -> bool {
match_tests.iter().any(|(module, names)| {
let matched_module = module == &"" || script.module.contains(module);
let matched_name = match names {
None => true,
Some(names) => names.iter().any(|name| {
if exact_match {
name == &script.name
} else {
script.name.contains(name)
}
}),
};
matched_module && matched_name
})
})
.collect::<Vec<Script>>()
} else {
scripts
};
scripts scripts
.into_par_iter() .into_par_iter()
.map(|script| { .map(|script| {

View File

@ -0,0 +1,5 @@
# This file was generated by Aiken
# You typically do not need to edit this file
requirements = []
packages = []

View File

@ -0,0 +1,3 @@
name = 'aiken-lang/acceptance_test_065'
version = '0.0.0'
description = ''

View File

@ -0,0 +1,49 @@
use aiken/builtin
type MyData {
Integer(Int)
Bytes(ByteArray)
}
test foo() {
inspect(42) == Integer(42) && inspect(#"ff") == Bytes(#"ff")
}
fn inspect(data: Data) -> MyData {
expect result: MyData =
builtin.choose_data(
data,
inspect_constr(data),
inspect_map(data),
inspect_list(data),
inspect_integer(data),
inspect_bytearray(data),
)
result
}
fn inspect_constr(_data: Data) -> Data {
todo
}
fn inspect_map(_data: Data) -> Data {
todo
}
fn inspect_list(_data: Data) -> Data {
todo
}
fn inspect_integer(data: Data) -> Data {
let result: Data =
builtin.un_i_data(data)
|> Integer
result
}
fn inspect_bytearray(data: Data) -> Data {
let result: Data =
builtin.un_b_data(data)
|> Bytes
result
}

View File

@ -164,8 +164,8 @@
] ]
} }
}, },
"compiledCode": "59030501000032323232323232323232322225333006323232323232323232533300f3370e002900009925130090021533300f3370e0029001099191919299980999b87001480084c8c8cccc8888c8c8c8c8c9289812000980b19299980e99b8748000c080dd500088008a9980fa492a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c03120023017001300900213232323253330133370e0029001099191999911119191919192513024001301632533301d3370e900018101baa0011001153301f49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c031200230170013009002301137540026600c600e0129000119ba548000cc04ccdd2a4004660266ea40052f5c06602666e9520024bd7025eb8088cc010dd6198031803998031803801240009002119baf3300730080014800000888cc00cdd6198029803198029803001240009000119baf3300630073300630070014800920000023001001222533301000213374a900125eb804c8c94ccc034c00c0084cdd2a40006602600497ae013330050050010033014003301200222323330010014800000c888cccc030cdc3802001009919980200219b8000348008c0540040048c02cdd50008a4c2c6002002444a666012004293099802980098058011998018019806001000ab9a5736ae7155ceaab9e5573eae815d0aba201", "compiledCode": "59030501000032323232323232323232322225333006323232323232323232533300f3370e002900009925130090021533300f3370e0029001099191919299980999b87001480084c8c8cccc8888c8c8c8c8c9289812000980b19299980e99b8748000c080dd500088008a9980fa492a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c03120023017001300900213232323253330133370e0029001099191999911119191919192513024001301632533301d3370e900018101baa0011001153301f49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c031200230170013009002301137540026600c600e0129000119ba548000cc04ccdd2a4004660266ea40052f5c06602666e9520024bd7025eb8088cc010dd6198031803998031803801240009002119baf3300730080014800000888cc00cdd6198029803198029803001240009000119baf3300630073300630070014800920000023001001222533301000213374a900125eb804c8c94ccc034c00c0084cdd2a40006602600497ae013330050050010033014003301200222323330010014800000c888cccc030cdc3802001009919980200219b8000348008c0540040048c02cdd50008a4c2c6002002444a666012004293099802980098058011998018019806001000ab9a5736ae7155ceaab9e5573eae815d0aba201",
"hash": "c95b3842362b77afec21773b7c0b1f09e61bf5e4c58b685533e6d342" "hash": "b79dffa847f2b9a55cb6cee2bd6057251f45e6a252587c7f6f3545d0"
} }
] ]
} }

View File

@ -0,0 +1,13 @@
# 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"

View File

@ -0,0 +1,7 @@
name = "aiken-lang/acceptance_test_074"
version = "0.0.0"
[[dependencies]]
name = 'aiken-lang/stdlib'
version = 'main'
source = 'github'

View File

@ -0,0 +1,282 @@
use aiken/bytearray.{from_string}
use aiken/hash.{Hash, Sha2_256, sha2_256}
use aiken/list
use aiken/option.{choice, is_none}
/// Variant of MerkleTree with only hash but without actual value
pub type MerkleTree<a> {
Empty
Leaf { hash: Hash<Sha2_256, ByteArray> }
Node {
hash: Hash<Sha2_256, ByteArray>,
left: MerkleTree<a>,
right: MerkleTree<a>,
}
}
pub type Proof =
List<ProofItem>
pub type ProofItem {
Left { hash: Hash<Sha2_256, ByteArray> }
Right { hash: Hash<Sha2_256, ByteArray> }
}
// Function returning a hash of a given Merkle Tree element
pub fn root_hash(self: MerkleTree<a>) -> Hash<Sha2_256, ByteArray> {
when self is {
Empty -> #""
Leaf { hash } -> hash
Node { hash, .. } -> hash
}
}
/// Function atests whether two Merkle Tress are equal, this is the case when their root hashes match.
pub fn is_equal(left: MerkleTree<a>, right: MerkleTree<a>) -> Bool {
root_hash(left) == root_hash(right)
}
/// Function returns a total numbers of leaves in the tree.
pub fn size(self: MerkleTree<a>) -> Int {
when self is {
Empty -> 0
Leaf{..} -> 1
Node { left, right, .. } -> size(left) + size(right)
}
}
fn combine_hash(
left: Hash<Sha2_256, a>,
right: Hash<Sha2_256, a>,
) -> Hash<Sha2_256, a> {
sha2_256(bytearray.concat(left, right))
}
/// Function that returns whether merkle tree has any elements
pub fn is_empty(self: MerkleTree<a>) -> Bool {
when self is {
Empty -> True
_ -> False
}
}
fn do_proof(
self: MerkleTree<a>,
item_hash: Hash<Sha2_256, ByteArray>,
proof: Proof,
serialise_fn: fn(a) -> ByteArray,
) -> Option<Proof> {
when self is {
Empty -> None
Leaf { hash } ->
if hash == item_hash {
Some(proof)
} else {
None
}
Node { left, right, .. } -> {
let rh = root_hash(right)
let lh = root_hash(left)
let go_left: Option<Proof> =
do_proof(
left,
item_hash,
list.push(proof, Right { hash: rh }),
serialise_fn,
)
let go_right: Option<Proof> =
do_proof(
right,
item_hash,
list.push(proof, Left { hash: lh }),
serialise_fn,
)
choice([go_left, go_right])
}
}
}
/// Construct a membership 'Proof' from an element and a 'MerkleTree'. Returns
/// 'None' if the element isn't a member of the tree to begin with.
/// Note function will return Some([]) in case root of the tree is also it's only one and only element
pub fn get_proof(
self: MerkleTree<a>,
item: a,
serialise_fn: fn(a) -> ByteArray,
) -> Option<Proof> {
let empty: Proof = []
do_proof(self, sha2_256(serialise_fn(item)), empty, serialise_fn)
}
fn do_from_list(
items: List<a>,
len: Int,
serialise_fn: fn(a) -> ByteArray,
) -> MerkleTree<a> {
when items is {
[] -> Empty
[item] -> {
let hashed_item = sha2_256(serialise_fn(item))
Leaf { hash: hashed_item }
}
all -> {
let cutoff: Int = len / 2
let left =
all
|> list.take(cutoff)
|> do_from_list(cutoff, serialise_fn)
let right =
all
|> list.drop(cutoff)
|> do_from_list(len - cutoff, serialise_fn)
let hash = combine_hash(root_hash(left), root_hash(right))
Node { hash, left, right }
}
}
}
/// Construct a 'MerkleTree' from a list of elements.
/// Note that, while this operation is doable on-chain, it is expensive and
/// preferably done off-chain.
pub fn from_list(
items: List<a>,
serialise_fn: fn(a) -> ByteArray,
) -> MerkleTree<a> {
do_from_list(items, list.length(items), serialise_fn)
}
fn do_from_hashes_list(
items: List<Hash<Sha2_256, a>>,
len: Int,
) -> MerkleTree<a> {
when items is {
[] -> Empty
[hashed_item] -> Leaf { hash: hashed_item }
all -> {
let cutoff: Int = len / 2
let left =
all
|> list.take(cutoff)
|> do_from_hashes_list(cutoff)
let right =
all
|> list.drop(cutoff)
|> do_from_hashes_list(len - cutoff)
let hash = combine_hash(root_hash(left), root_hash(right))
Node { hash, left, right }
}
}
}
/// Construct a 'MerkleTree' from a list of hashes.
/// Note that, while this operation is doable on-chain, it is expensive and
/// preferably done off-chain.
pub fn from_hashes_list(items: List<Hash<Sha2_256, a>>) -> MerkleTree<a> {
do_from_hashes_list(items, list.length(items))
}
// Check whether a hashed element is part of a 'MerkleTree' using only its root hash
// and a 'Proof'. The proof is guaranteed to be in log(n) of the size of the
// tree, which is why we are interested in such data-structure in the first
// place.
pub fn member_from_hash(
item_hash: Hash<Sha2_256, a>,
root_hash: Hash<Sha2_256, a>,
proof: Proof,
serialise_fn: fn(a) -> ByteArray,
) -> Bool {
when proof is {
[] -> root_hash == item_hash
[head, ..tail] ->
when head is {
Left { hash: l } ->
member_from_hash(
combine_hash(l, item_hash),
root_hash,
tail,
serialise_fn,
)
Right { hash: r } ->
member_from_hash(
combine_hash(item_hash, r),
root_hash,
tail,
serialise_fn,
)
}
}
}
// Check whether an element is part of a 'MerkleTree' using only its root hash
// and a 'Proof'.
pub fn member(
item: a,
root_hash: Hash<Sha2_256, ByteArray>,
proof: Proof,
serialise_fn: fn(a) -> ByteArray,
) -> Bool {
let item_hash = sha2_256(serialise_fn(item))
member_from_hash(item_hash, root_hash, proof, serialise_fn)
}
pub fn member_from_tree(
tree: MerkleTree<a>,
item: a,
serialise_fn: fn(a) -> ByteArray,
) -> Bool {
let proof: Option<Proof> = get_proof(tree, item, serialise_fn)
let rh = root_hash(tree)
when proof is {
Some(p) -> member(item, rh, p, serialise_fn)
None -> False
}
}
// needed only for tests
fn create_string_item_serialise_fn() -> fn(String) -> ByteArray {
fn(x: String) { from_string(x) }
}
test from_hashes_list_5() {
let dog = @"dog"
let cat = @"cat"
let mouse = @"mouse"
let horse = @"horse"
let serialise_fn = create_string_item_serialise_fn()
let items = [dog, cat, mouse, horse]
let hashes_items = list.map(items, fn(item) { sha2_256(serialise_fn(item)) })
let mt = from_hashes_list(hashes_items)
let left_node_hash =
sha2_256(
bytearray.concat(sha2_256(serialise_fn(dog)), sha2_256(serialise_fn(cat))),
)
let right_node_hash =
sha2_256(
bytearray.concat(
sha2_256(serialise_fn(mouse)),
sha2_256(serialise_fn(horse)),
),
)
let root_hash = sha2_256(bytearray.concat(left_node_hash, right_node_hash))
Node {
hash: root_hash,
left: Node {
hash: left_node_hash,
left: Leaf { hash: sha2_256(serialise_fn(dog)) },
right: Leaf { hash: sha2_256(serialise_fn(cat)) },
},
right: Node {
hash: right_node_hash,
left: Leaf { hash: sha2_256(serialise_fn(mouse)) },
right: Leaf { hash: sha2_256(serialise_fn(horse)) },
},
} == mt
}

View File

@ -0,0 +1,5 @@
# This file was generated by Aiken
# You typically do not need to edit this file
requirements = []
packages = []

View File

@ -0,0 +1,3 @@
name = 'aiken-lang/acceptance_test_076'
version = '0.0.0'
description = ''

View File

@ -0,0 +1,5 @@
test expect_positive() {
let val = 5
expect True = val > 0
True
}

View File

@ -6,45 +6,19 @@
}, },
"validators": [ "validators": [
{ {
"title": "basic.spend", "title": "deploy.spend",
"datum": { "datum": {
"title": "Unit", "title": "Data",
"description": "The nullary constructor.", "description": "Any Plutus data.",
"schema": { "schema": {}
"anyOf": [
{
"dataType": "constructor",
"index": 0,
"fields": []
}
]
}
}, },
"redeemer": {
"title": "Unit",
"description": "The nullary constructor.",
"schema": {
"anyOf": [
{
"dataType": "constructor",
"index": 0,
"fields": []
}
]
}
},
"compiledCode": "5904600100003232323232323232323222253330063232323232300200132323232323233015333010323330113375e660146016002900b26126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a0944cc024c02802d20004c0103d87a80004c0103d879800033015333010323253330123370e002900109919299980a19baf3300d300e00148001300126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4cc034c038005200248000528180c80098060010b18099baa00133009300a00b48009300103d87a80004c0103d8798000330153330103232533301600116132533301700113232300c001330193330143375e6e98dd5998069807000a40046e98c0152080a8d6b9074c0103d87a80004c0103d8798000330193330143375e6601a601c6601a601c002900024000980122d8799f581c11111111111111111111111111111111111111111111111111111111ff004c0103d87a80004c0103d879800033019333014323253330163370e0029000099250301000214a2602e6ea8004cc034c038cc034c038005200048009300103d87a80004c0103d8798000330193330143375e6601a601c002900219ba5480012f5c098103d87a80004c0103d8798000330193330143375e6601a601c002900319ba5480092f5c098103d87a80004c0103d87980004bd70180c8010b180c8009bac3300a300b00148010cc024c02802d20004c0103d87a80004c0103d879800033015333010323375e6e98dd5998051805800a400c6e98c009205433009300a00b4800130103d87a80004c0103d87980004bd7011999111919000999991111999805002001801000a5eb7bdb180010004020cccc8888cccc03001000c0080052f5bded8c000400200e9101004881000013001001222225333016004133017337606ea400cdd300125eb7bdb1804c8c8c8c94ccc058cdd79980280380099ba5480012f5c026603666ec0dd48039ba6006008153330163371e00e00226603666ec0dd48039ba600600313301b337606ea4004dd3001199998048048018038030029bae30170033756602e004603400a603000844a66601c66e400080044cdd2a400097ae01533300e3371e004002266e9520024bd70099ba5480112f5c0600200244444a66602600826602866ec0dd48019ba80024bd6f7b630099191919299980999baf330050070013374a900025eb804cc060cdd81ba9007375000c0102a66602666e3c01c0044cc060cdd81ba9007375000c00626603066ec0dd48009ba800233333009009003007006005375c60280066eb4c050008c05c014c054010c004004894ccc0380045288991929998060010998020020008a5030120023370e900118061baa301000122323330010014800000c888cccc030cdc3802001009119980200219b8000348008c0500040048c028dd50008a4c2c6002002444a666010004293099802980098050011998018019805801000ab9a5736aae7555cf2ab9f5740ae855d101",
"hash": "42428cc55092a182161081f528491b8ec1fbd908c40eca9069c4d1be"
},
{
"title": "mint.mint",
"redeemer": { "redeemer": {
"title": "Data", "title": "Data",
"description": "Any Plutus data.", "description": "Any Plutus data.",
"schema": {} "schema": {}
}, },
"compiledCode": "590488010000323232323232323232323222533300532323232323001003300100122533300f00114a226464a6660180042660080080022940c04c008cdc3a4004601a6ea8c044004cc034ccc01cc8c8c8c8c8c8c94ccc04cc0580084c8c8cdc78018009bae3016001300932533300f3370e900018091baa0011001153301149012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300830090034800854cc0412401364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375c602800264646464600c00200200264640026644660100040020029110000137566600c600e6600c600e00290002401000e600200244a666020002297ae01323232323301537520026600c00c0066eb8c04400cdd59808801180a0011809000980080091129998078010a5eb7bdb1804c8c8c8c94ccc038cdc7802800880189980a19bb037520026e98008ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d333007323232323322323232323253330123370e00290010b0991919b87001483c850dd6980d0009806801180a1baa001332233008002001001488103666f6f0033223233223253330153370e00290010801099190009bab301d00130100033017375400400297adef6c6033223300b002001002001375666012601400690040009bae30150013008533300d3370e900018081baa0021002153300f49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633005300600748008cc014c01801d20003001001222533301100213374a900125eb804c8c8c8c94ccc040cdc7802800899ba548000cc058dd400125eb804ccc01c01c00c014dd718090019bad3012002301500330130023001001222533300f00213374a900125eb804c8c8c8c94ccc038cdc7802800899ba548000cc050dd300125eb804ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d3330073232323233223232533300f3375e006002266e1cc8c018004dd5998049805198049805002240009009240042940c054004c020c94ccc038cdc3a400060226ea8004400454cc0412412a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633223300700200137566600e60106600e60100049000240246600e6010004900100380418008009129998080008a400026466e0120023300300300130130013001001222533300f00213374a900125eb804c8c8c8c94ccc038cdd7802800899ba548000cc0500092f5c0266600e00e00600a6020006602000460260066022004980103d87a80004c0103d87980004bd701119199800800a4000006444666601666e1c0100080488ccc010010cdc0001a40046028002002460146ea8004526163001001222533300900214984cc014c004c02c008ccc00c00cc0300080055cd2b9b5738aae7555cf2ab9f5740ae855d11", "compiledCode": "5903e101000032323232323232323232322225333006323232323230020013301033300a32323375e0040026601893260103d87980000074c103d87a80004c0103d87980003301033300a32323232323232330123253330123370e002900009919299980c980e0010a4c2a6602c921364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375a603400260180042a660289212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e74001630143754002a66602266ebd30106d8799f182aff0000113370e64600a00200690020a50301700130093253330103370e900018099baa0011001153301249012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163322330060020010013237280026ecd30106d8799f182aff0037566600e60106600e6010012900024028600200244a6660260022900009919b8048008cc00c00c004c058004c0040048894ccc0480084cdd2a400497ae013232323253330113371e00a002266e952000330170024bd7009998038038018029bae30130033013002301600330140024c0103d87a80004c0103d87980003301033300a32533301000116132533301100116132323232533301032323009001330173330113375e660146016002900226126d87a9f5820fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273ff004c0103d87a80004c0103d8798000330173330113375e6601460160029003260122d8799f581ce37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4ff004c0103d87a80004c0103d87980004bd700010991918048009980b99980899baf3300a300b3300a300b0014800120024c012ad8799fd8799fd8799f581c66666666666666666666666666666666666666666666666666666666ffffff004c0103d87a80004c0103d879800033017333011323253330133370e0029002099251300d00216301537540026601460160029002260103d87a80004c0103d87980004bd700008a50301600430150041630140013013001375866006600866006600800a900024008980103d87a80004c0103d87980004bd7018008009129998078008a5113232533300c00213300400400114a0602600466e1d2002300d3754602200244646660020029000001911199980619b870040020132333004004337000069001180a800800918059baa001149858c0040048894ccc0240085261330053001300b002333003003300c0020015734ae6d5ce2ab9d5573caae7d5d02ba15745",
"hash": "dbc571e23778572680144ee7065334ab9545cc8111da1ea5dc85ac44" "hash": "3326c651fce284b443e23da9cc6f5864a1e496f2fc7774799fb897f9"
}, },
{ {
"title": "withdrawals.spend", "title": "withdrawals.spend",
@ -78,19 +52,45 @@
"hash": "6917ce2313801b854e38507b68d2c61afd70fca721804235e4760056" "hash": "6917ce2313801b854e38507b68d2c61afd70fca721804235e4760056"
}, },
{ {
"title": "deploy.spend", "title": "mint.mint",
"datum": {
"title": "Data",
"description": "Any Plutus data.",
"schema": {}
},
"redeemer": { "redeemer": {
"title": "Data", "title": "Data",
"description": "Any Plutus data.", "description": "Any Plutus data.",
"schema": {} "schema": {}
}, },
"compiledCode": "5903e101000032323232323232323232322225333006323232323230020013301033300a32323375e0040026601893260103d87980000074c103d87a80004c0103d87980003301033300a32323232323232330123253330123370e002900009919299980c980e0010a4c2a6602c921364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375a603400260180042a660289212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e74001630143754002a66602266ebd30106d8799f182aff0000113370e64600a00200690020a50301700130093253330103370e900018099baa0011001153301249012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163322330060020010013237280026ecd30106d8799f182aff0037566600e60106600e6010012900024028600200244a6660260022900009919b8048008cc00c00c004c058004c0040048894ccc0480084cdd2a400497ae013232323253330113371e00a002266e952000330170024bd7009998038038018029bae30130033013002301600330140024c0103d87a80004c0103d87980003301033300a32533301000116132533301100116132323232533301032323009001330173330113375e660146016002900226126d87a9f5820fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273ff004c0103d87a80004c0103d8798000330173330113375e6601460160029003260122d8799f581ce37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4ff004c0103d87a80004c0103d87980004bd700010991918048009980b99980899baf3300a300b3300a300b0014800120024c012ad8799fd8799fd8799f581c66666666666666666666666666666666666666666666666666666666ffffff004c0103d87a80004c0103d879800033017333011323253330133370e0029002099251300d00216301537540026601460160029002260103d87a80004c0103d87980004bd700008a50301600430150041630140013013001375866006600866006600800a900024008980103d87a80004c0103d87980004bd7018008009129998078008a5113232533300c00213300400400114a0602600466e1d2002300d3754602200244646660020029000001911199980619b870040020132333004004337000069001180a800800918059baa001149858c0040048894ccc0240085261330053001300b002333003003300c0020015734ae6d5ce2ab9d5573caae7d5d02ba15745", "compiledCode": "590488010000323232323232323232323222533300532323232323001003300100122533300f00114a226464a6660180042660080080022940c04c008cdc3a4004601a6ea8c044004cc034ccc01cc8c8c8c8c8c8c94ccc04cc0580084c8c8cdc78018009bae3016001300932533300f3370e900018091baa0011001153301149012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300830090034800854cc0412401364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375c602800264646464600c00200200264640026644660100040020029110000137566600c600e6600c600e00290002401000e600200244a666020002297ae01323232323301537520026600c00c0066eb8c04400cdd59808801180a0011809000980080091129998078010a5eb7bdb1804c8c8c8c94ccc038cdc7802800880189980a19bb037520026e98008ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d333007323232323322323232323253330123370e00290010b0991919b87001483c850dd6980d0009806801180a1baa001332233008002001001488103666f6f0033223233223253330153370e00290010801099190009bab301d00130100033017375400400297adef6c6033223300b002001002001375666012601400690040009bae30150013008533300d3370e900018081baa0021002153300f49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633005300600748008cc014c01801d20003001001222533301100213374a900125eb804c8c8c8c94ccc040cdc7802800899ba548000cc058dd400125eb804ccc01c01c00c014dd718090019bad3012002301500330130023001001222533300f00213374a900125eb804c8c8c8c94ccc038cdc7802800899ba548000cc050dd300125eb804ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d3330073232323233223232533300f3375e006002266e1cc8c018004dd5998049805198049805002240009009240042940c054004c020c94ccc038cdc3a400060226ea8004400454cc0412412a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633223300700200137566600e60106600e60100049000240246600e6010004900100380418008009129998080008a400026466e0120023300300300130130013001001222533300f00213374a900125eb804c8c8c8c94ccc038cdd7802800899ba548000cc0500092f5c0266600e00e00600a6020006602000460260066022004980103d87a80004c0103d87980004bd701119199800800a4000006444666601666e1c0100080488ccc010010cdc0001a40046028002002460146ea8004526163001001222533300900214984cc014c004c02c008ccc00c00cc0300080055cd2b9b5738aae7555cf2ab9f5740ae855d11",
"hash": "6bfde537ea8bcb1b566489979896ecc8f88c6edb2f791a4197e2d51f" "hash": "4621310698e9ee7830df98d79551eb5672cdee04247e28c8e1c1d494"
},
{
"title": "basic.spend",
"datum": {
"title": "Unit",
"description": "The nullary constructor.",
"schema": {
"anyOf": [
{
"dataType": "constructor",
"index": 0,
"fields": []
}
]
}
},
"redeemer": {
"title": "Unit",
"description": "The nullary constructor.",
"schema": {
"anyOf": [
{
"dataType": "constructor",
"index": 0,
"fields": []
}
]
}
},
"compiledCode": "59046f0100003232323232323232323222253330063232323232300200132323232323233015333010323330113375e660146016002900b26126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a0944cc024c02802d20004c0103d87a80004c0103d879800033015333010323253330123370e002900109919299980a19baf3300d300e00148001300126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4cc034c038005200248000528180c80098060010b18099baa00133009300a00b48009300103d87a80004c0103d8798000330153330103232533301600116132533301700113232300c001330193330143375e6e98dd5998069807000a40046e98c0152080a8d6b9074c0103d87a80004c0103d8798000330193330143375e6601a601c6601a601c002900024000980122d8799f581c11111111111111111111111111111111111111111111111111111111ff004c0103d87a80004c0103d879800033019333014323253330163370e0029000099250301000214a2602e6ea8004cc034c038cc034c038005200048009300103d87a80004c0103d8798000330193330143375e6601a601c002900219ba5480012f5c098103d87a80004c0103d8798000330193330143375e6601a601c002900319ba5480092f5c098103d87a80004c0103d87980004bd70180c8010b180c8009bac3300a300b00148010cc024c02802d20004c0103d87a80004c0103d879800033015333010323375e6e98dd5998051805800a400c6e98c009205433009300a00b4800130103d87a80004c0103d87980004bd701199911299980999b870014800052f5bded8c02646400266664444666601400800600400297adef6c6000400100833332222333300c0040030020014bd6f7b630001000803a45004881000013001001222225333016004133017337606ea400cdd300125eb7bdb1804c8c8c8c94ccc058cdd79980280380099ba5480012f5c026603666ec0dd48039ba6006008153330163371e00e00226603666ec0dd48039ba600600313301b337606ea4004dd3001199998048048018038030029bae30170033756602e004603400a603000844a66601c66e400080044cdd2a400097ae01533300e3371e004002266e9520024bd70099ba5480112f5c0600200244444a66602600826602866ec0dd48019ba80024bd6f7b630099191919299980999baf330050070013374a900025eb804cc060cdd81ba9007375000c0102a66602666e3c01c0044cc060cdd81ba9007375000c00626603066ec0dd48009ba800233333009009003007006005375c60280066eb4c050008c05c014c054010c004004894ccc0380045288991929998060010998020020008a5030120023370e900118061baa301000122323330010014800000c888cccc030cdc3802001009119980200219b8000348008c0500040048c028dd50008a4c2c6002002444a666010004293099802980098050011998018019805801000ab9a5736aae7555cf2ab9f5740ae855d101",
"hash": "911eb2bc725e7a51670338f2a12102785984d2569fa75b6ba4054c49"
} }
] ]
} }