Merge pull request #373 from aiken-lang/test-script-context-interactions
Test (some) script context interactions
This commit is contained in:
commit
d8ff9e23a4
|
@ -1,11 +1,11 @@
|
|||
use miette::IntoDiagnostic;
|
||||
use owo_colors::OwoColorize;
|
||||
use pallas_primitives::{
|
||||
babbage::{TransactionInput, TransactionOutput},
|
||||
babbage::{Redeemer, TransactionInput, TransactionOutput},
|
||||
Fragment,
|
||||
};
|
||||
use pallas_traverse::{Era, MultiEraTx};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::{fmt, fs, path::PathBuf, process};
|
||||
use uplc::{
|
||||
machine::cost_model::ExBudget,
|
||||
tx::{
|
||||
|
@ -54,6 +54,8 @@ pub fn exec(
|
|||
zero_slot,
|
||||
}: Args,
|
||||
) -> miette::Result<()> {
|
||||
eprintln!("{} script context", " Parsing".bold().purple(),);
|
||||
|
||||
let (tx_bytes, inputs_bytes, outputs_bytes) = if cbor {
|
||||
(
|
||||
fs::read(input).into_diagnostic()?,
|
||||
|
@ -76,6 +78,8 @@ pub fn exec(
|
|||
.or_else(|_| MultiEraTx::decode(Era::Alonzo, &tx_bytes))
|
||||
.into_diagnostic()?;
|
||||
|
||||
eprintln!("{} {}", " Simulating".bold().purple(), tx.hash());
|
||||
|
||||
let inputs = Vec::<TransactionInput>::decode_fragment(&inputs_bytes).unwrap();
|
||||
let outputs = Vec::<TransactionOutput>::decode_fragment(&outputs_bytes).unwrap();
|
||||
|
||||
|
@ -88,8 +92,6 @@ pub fn exec(
|
|||
})
|
||||
.collect();
|
||||
|
||||
println!("Simulating: {}", tx.hash());
|
||||
|
||||
if let Some(tx_babbage) = tx.as_babbage() {
|
||||
let slot_config = SlotConfig {
|
||||
zero_time,
|
||||
|
@ -97,13 +99,27 @@ pub fn exec(
|
|||
slot_length,
|
||||
};
|
||||
|
||||
let result =
|
||||
tx::eval_phase_two(tx_babbage, &resolved_inputs, None, None, &slot_config, true);
|
||||
let with_redeemer = |redeemer: &Redeemer| {
|
||||
println!(
|
||||
"{} {:?} → {}",
|
||||
" Redeemer".bold().purple(),
|
||||
redeemer.tag,
|
||||
redeemer.index
|
||||
)
|
||||
};
|
||||
|
||||
let result = tx::eval_phase_two(
|
||||
tx_babbage,
|
||||
&resolved_inputs,
|
||||
None,
|
||||
None,
|
||||
&slot_config,
|
||||
true,
|
||||
with_redeemer,
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(redeemers) => {
|
||||
println!("\nTotal Budget Used\n-----------------\n");
|
||||
|
||||
let total_budget_used =
|
||||
redeemers
|
||||
.iter()
|
||||
|
@ -112,11 +128,16 @@ pub fn exec(
|
|||
cpu: accum.cpu + curr.ex_units.steps as i64,
|
||||
});
|
||||
|
||||
println!("mem: {}", total_budget_used.mem);
|
||||
println!("cpu: {}", total_budget_used.cpu);
|
||||
println!(
|
||||
"\n{}",
|
||||
serde_json::to_string(&total_budget_used)
|
||||
.map_err(|_| fmt::Error)
|
||||
.into_diagnostic()?
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("\nError\n-----\n\n{err}\n");
|
||||
eprintln!("{} {}", " Error".bold().red(), err.red());
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ macro_rules! hashmap {
|
|||
}
|
||||
|
||||
/// Can be negative
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy, serde::Serialize)]
|
||||
pub struct ExBudget {
|
||||
pub mem: i64,
|
||||
pub cpu: i64,
|
||||
|
|
|
@ -35,6 +35,7 @@ pub fn eval_phase_two(
|
|||
initial_budget: Option<&ExBudget>,
|
||||
slot_config: &SlotConfig,
|
||||
run_phase_one: bool,
|
||||
with_redeemer: fn(&Redeemer) -> (),
|
||||
) -> Result<Vec<Redeemer>, Error> {
|
||||
let redeemers = tx.transaction_witness_set.redeemer.as_ref();
|
||||
|
||||
|
@ -52,6 +53,8 @@ pub fn eval_phase_two(
|
|||
let mut remaining_budget = *initial_budget.unwrap_or(&ExBudget::default());
|
||||
|
||||
for redeemer in rs.iter() {
|
||||
with_redeemer(redeemer);
|
||||
|
||||
let redeemer = eval::eval_redeemer(
|
||||
tx,
|
||||
utxos,
|
||||
|
@ -87,6 +90,7 @@ pub fn eval_phase_two_raw(
|
|||
initial_budget: (u64, u64),
|
||||
slot_config: (u64, u64, u32),
|
||||
run_phase_one: bool,
|
||||
with_redeemer: fn(&Redeemer) -> (),
|
||||
) -> Result<Vec<Vec<u8>>, Error> {
|
||||
let multi_era_tx = MultiEraTx::decode(Era::Babbage, tx_bytes)
|
||||
.or_else(|_| MultiEraTx::decode(Era::Alonzo, tx_bytes))?;
|
||||
|
@ -122,6 +126,7 @@ pub fn eval_phase_two_raw(
|
|||
Some(&budget),
|
||||
&sc,
|
||||
run_phase_one,
|
||||
with_redeemer,
|
||||
) {
|
||||
Ok(redeemers) => Ok(redeemers
|
||||
.iter()
|
||||
|
|
|
@ -283,15 +283,13 @@ fn build_redeemer_ptr(
|
|||
for (idx, x) in reward_accounts.iter().enumerate() {
|
||||
let cred = match Address::from_bytes(x).unwrap() {
|
||||
Address::Stake(a) => match a.payload() {
|
||||
StakePayload::Script(sh) => StakeCredential::Scripthash(*sh),
|
||||
StakePayload::Stake(_) => {
|
||||
return Err(Error::ScriptKeyHash);
|
||||
}
|
||||
StakePayload::Script(sh) => Some(StakeCredential::Scripthash(*sh)),
|
||||
StakePayload::Stake(_) => None,
|
||||
},
|
||||
_ => return Err(Error::BadWithdrawalAddress),
|
||||
};
|
||||
|
||||
if cred == *racnt {
|
||||
if cred == Some(racnt.to_owned()) {
|
||||
maybe_idx = Some(idx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,6 +246,7 @@ fn test_eval() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -516,6 +517,7 @@ fn test_eval_1() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -621,6 +623,7 @@ fn test_eval_2() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -885,6 +888,7 @@ fn test_eval_3() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -987,6 +991,7 @@ fn test_eval_4() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
@ -1069,6 +1074,7 @@ fn test_eval_5() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1173,6 +1179,7 @@ fn test_eval_6() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1277,6 +1284,7 @@ fn test_eval_7() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1532,6 +1540,7 @@ fn test_eval_8() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1632,6 +1641,7 @@ fn eval_missing_redeemer() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -1711,6 +1721,7 @@ fn eval_extraneous_redeemer() {
|
|||
Some(&initial_budget),
|
||||
&slot_config,
|
||||
false,
|
||||
|_| (),
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
for scenario in $(find . -maxdepth 1 -mindepth 1 -type d)
|
||||
do
|
||||
./run $scenario
|
||||
for scenario in $(find . -maxdepth 1 -mindepth 1 -regex ".*[0-9]\{3\}" -type d); do
|
||||
./run $scenario
|
||||
done
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ctx/**/*.cbor
|
|
@ -0,0 +1,18 @@
|
|||
# Script Context Tests
|
||||
|
||||
This project contains a few handcrafted 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]
|
||||
```
|
|
@ -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"
|
|
@ -0,0 +1,8 @@
|
|||
name = 'aiken-lang/acceptance_test_062'
|
||||
version = '0.0.0'
|
||||
description = ''
|
||||
|
||||
[[dependencies]]
|
||||
name = 'aiken-lang/stdlib'
|
||||
version = 'main'
|
||||
source = 'github'
|
|
@ -0,0 +1 @@
|
|||
81825820000000000000000000000000000000000000000000000000000000000000000000
|
|
@ -0,0 +1 @@
|
|||
81A300581D70{{ VALIDATOR_HASH }}011A3B9ACA00028201D81843D87980
|
|
@ -0,0 +1 @@
|
|||
84A70081825820000000000000000000000000000000000000000000000000000000000000000000018182581D60111111111111111111111111111111111111111111111111111111111A3B9ACA0002182A0B5820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D818258200000000000000000000000000000000000000000000000000000000000000000001082581D60000000000000000000000000000000000000000000000000000000001A3B9ACA001101A20581840000D87980821A000F42401A05F5E1000681{{ VALIDATOR }}F5F6
|
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{ 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
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
81825820000000000000000000000000000000000000000000000000000000000000000000
|
|
@ -0,0 +1 @@
|
|||
81A300581D70{{ VALIDATOR_HASH }}011A3B9ACA00028201D81843D87980
|
|
@ -0,0 +1 @@
|
|||
84A80081825820000000000000000000000000000000000000000000000000000000000000000000018182581D60111111111111111111111111111111111111111111111111111111111A3B9ACA0002182A05A2581DE022222222222222222222222222222222222222222222222222222222182A581DF05E1E8FA84F2B557DDC362329413CAA3FD89A1BE26BFD24BE05CE0A020E0B5820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D818258200000000000000000000000000000000000000000000000000000000000000000001082581D60000000000000000000000000000000000000000000000000000000001A3B9ACA001101A20582840000D87980821A000F42401A05F5E100840301D87980821A000F42401A05F5E1000682{{ VALIDATOR }}58AF58AD0100003232322225333004323253330063372E646E64004DD7198009801002240009210D48656C6C6F2C20576F726C64210013233300100137586600460066600460060089000240206EB8CC008C00C019200022253335573E004294054CCC024CDC79BAE300A00200114A226660060066016004002294088C8CCC0040052000003222333300A3370E008004016466600800866E0000D2002300D001001235573C6EA8004526165734AE855D11F5F6
|
|
@ -0,0 +1,40 @@
|
|||
[
|
||||
{ 0:
|
||||
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
|
||||
]
|
||||
|
||||
, 1:
|
||||
[ [h'6011111111111111111111111111111111111111111111111111111111', 1000000000]
|
||||
]
|
||||
|
||||
, 2: 42
|
||||
|
||||
, 5:
|
||||
{ h'e022222222222222222222222222222222222222222222222222222222': 42
|
||||
, h'f05e1e8fa84f2b557ddc362329413caa3fd89a1be26bfd24be05ce0a02': 14
|
||||
}
|
||||
|
||||
, 11: h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
|
||||
|
||||
, 13:
|
||||
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
|
||||
]
|
||||
|
||||
, 16:
|
||||
[ h'6000000000000000000000000000000000000000000000000000000000', 1000000000
|
||||
]
|
||||
|
||||
, 17: 1
|
||||
},
|
||||
|
||||
{ 5:
|
||||
[ [0, 0, 121([]), [1000000, 100000000]]
|
||||
, [3, 1, 121([]), [1000000, 100000000]]
|
||||
]
|
||||
|
||||
, 6: [ h'58ad0100003232322225333004323253330063372e646e64004dd7198009801002240009210d48656c6c6f2c20576f726c64210013233300100137586600460066600460060089000240206eb8cc008c00c019200022253335573e004294054ccc024cdc79bae300a00200114a226660060066016004002294088c8ccc0040052000003222333300a3370e008004016466600800866e0000d2002300d001001235573c6ea8004526165734ae855d11' ]
|
||||
|
||||
},
|
||||
true,
|
||||
null
|
||||
]
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"preamble": {
|
||||
"title": "aiken-lang/acceptance_test_062",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
"validators": [
|
||||
{
|
||||
"title": "withdrawals",
|
||||
"purpose": "spend",
|
||||
"datum": {
|
||||
"title": "Unit",
|
||||
"description": "The nullary constructor.",
|
||||
"anyOf": [
|
||||
{
|
||||
"dataType": "constructor",
|
||||
"index": 0,
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"redeemer": {
|
||||
"title": "Unit",
|
||||
"description": "The nullary constructor.",
|
||||
"anyOf": [
|
||||
{
|
||||
"dataType": "constructor",
|
||||
"index": 0,
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"compiledCode": "5902d80100003232323232323232323232222533300632323232323001003300100122533301000114a226464a66601a0042660080080022940c050008cdc3a4004601c6ea8c048004c8c8c8cc044ccc02cc8c94ccc034cdc3800a40042a6601e9211c616c6963652773207769746864726177616c206e6f7420666f756e640016132323370e002902a1bad30150013007002300f3754002660026eaccc010c014cc010c01401920004803130126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff004c0103d87a80004c0103d87980003301133300b3232533300d3370e00290010a99807a491a626f622773207769746864726177616c206e6f7420666f756e640016132323370e002900e1bad30150013007002300f3754002660026eaccc010c014cc010c01401920004803130126d8799fd87a9f581c5e1e8fa84f2b557ddc362329413caa3fd89a1be26bfd24be05ce0a02ffff004c0103d87a80004c0103d87980003301133300b3375e6e9cc8c8c8c008004dd599803180399803180380424000900618008009129998090008a5eb804c8c8c8c8cc05c004cc01801800cc04c00cdd69809801180b001180a0009ba7330114c0126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff00330114c126d8799fd87a9f581c5e1e8fa84f2b557ddc362329413caa3fd89a1be26bfd24be05ce0a02ffff004bd7026103d87a80004c0103d87980004bd70111980180100098008009112999808001099ba5480092f5c0264646464a66601e66ebc0140044cdd2a40006602a6ea00092f5c0266600e00e00600a60220066eb4c044008c05000cc04800888c8ccc0040052000003222333300c3370e008004026466600800866e0000d200230150010012300b37540022930b180080091129998048010a4c26600a600260160046660060066018004002ae695cdab9c5573aaae7955cfaba05742ae89",
|
||||
"hash": "26dca991cde0d8e0554e3019488f4576e6f4b91c46dd14bd91053281"
|
||||
},
|
||||
{
|
||||
"title": "basic",
|
||||
"purpose": "spend",
|
||||
"datum": {
|
||||
"title": "Unit",
|
||||
"description": "The nullary constructor.",
|
||||
"anyOf": [
|
||||
{
|
||||
"dataType": "constructor",
|
||||
"index": 0,
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"redeemer": {
|
||||
"title": "Unit",
|
||||
"description": "The nullary constructor.",
|
||||
"anyOf": [
|
||||
{
|
||||
"dataType": "constructor",
|
||||
"index": 0,
|
||||
"fields": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"compiledCode": "59042a010000323232323232323232323222253330063232323232300200132323232323233016333010323253330123370e002900109919299980a19baf3300d300e0014800130126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4cc034c038005200248000528180d00098060010a9980a2491c73637269707420707572706f73652069736e277420275370656e6427001630143754002660126014016900126103d87a80004c0103d87980003301633301032325333017001153301449011c756e6578706563746564206e756d626572206f66206f7574707574730016132533301800113232300c0013301a3330143375e6e98dd5998069807000a40046e98c0152080a8d6b9074c103d87a80004c0103d87980003301a3330143375e6601a601c6601a601c002900024000980122d8799f581c11111111111111111111111111111111111111111111111111111111ff004c0103d87a80004c0103d87980003301a333014323253330163370e0029000099250301000214a260306ea8004cc034c038cc034c038005200048009300103d87a80004c0103d87980004bd70180d0010a9980aa491c756e6578706563746564206e756d626572206f66206f7574707574730016301a00137586601460160029002198049805005a4000980103d87a80004c0103d879800033016333010323375e6e98dd5998051805800a400c6e98c009205433009300a00b4800130103d87a80004c0103d87980004bd7011999111919000999991111999805002001801000a5eb7bdb180010004020cccc8888cccc03001000c0080052f5bded8c000400200e9101004881000013001001222225333017004133018337606ea400cdd300125eb7bdb1804c8c8c8c94ccc058cdd79980280380099ba5480012f5c026603866ec0dd48039ba6006008153330163371e00e00226603866ec0dd48039ba600600313301c337606ea4004dd3001199998048048018038030029bae301800337566030004603600a603200844a66601c66e400080044cdd2a400097ae01533300e3371e004002266e9520024bd70099ba5480112f5c0600200244444a66602800826602a66ec0dd48019ba80024bd6f7b630099191919299980999baf330050070013374a900025eb804cc064cdd81ba9007375000c0102a66602666e3c01c0044cc064cdd81ba9007375000c00626603266ec0dd48009ba800233333009009003007006005375c602a0066eb4c054008c060014c058010c004004894ccc03c0045288991929998060010998020020008a5030130023370e900118069baa301100122323330010014800000c888cccc030cdc3802001009919980200219b8000348008c0540040048c02cdd50008a4c2c6002002444a666012004293099802980098058011998018019806001000ab9a5736ae7155ceaab9e5573eae815d0aba201",
|
||||
"hash": "1afe9a73274c140722127c27511395d861b5ed8e0bee1e7e9171c47a"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#!/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
|
||||
|
||||
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
|
||||
|
||||
cargo run --quiet -- build
|
||||
if [ $? -ne 0 ]; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
BLUEPRINT=$(jq ".validators[] | select(.title == \"$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 > ctx/$TITLE/tx.cbor
|
||||
|
||||
cargo run --quiet -- tx simulate ctx/$TITLE/tx.cbor ctx/$TITLE/inputs.cbor ctx/$TITLE/outputs.cbor
|
|
@ -0,0 +1,43 @@
|
|||
use aiken/list
|
||||
use aiken/option
|
||||
use aiken/transaction.{ScriptContext, Spend, TransactionId}
|
||||
use aiken/transaction/credential.{VerificationKeyCredential}
|
||||
use aiken/transaction/value
|
||||
|
||||
fn spend(_datum: Void, _redeemer: Void, ctx: ScriptContext) {
|
||||
[
|
||||
assert_purpose(ctx.purpose),
|
||||
assert_outputs(ctx.transaction),
|
||||
assert_fee(ctx.transaction),
|
||||
]
|
||||
|> list.and
|
||||
}
|
||||
|
||||
fn assert_purpose(purpose) {
|
||||
when purpose is {
|
||||
Spend(ref) ->
|
||||
ref.transaction_id == TransactionId(
|
||||
#"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
) && ref.output_index == 0
|
||||
_ -> error("script purpose isn't 'Spend'")
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_fee(transaction) {
|
||||
transaction.fee == value.from_lovelace(42)
|
||||
}
|
||||
|
||||
fn assert_outputs(transaction) {
|
||||
when transaction.outputs is {
|
||||
[output] ->
|
||||
[
|
||||
output.value == value.from_lovelace(1000000000),
|
||||
output.address.payment_credential == VerificationKeyCredential(
|
||||
#"11111111111111111111111111111111111111111111111111111111",
|
||||
),
|
||||
option.is_none(output.address.stake_credential),
|
||||
]
|
||||
|> list.and
|
||||
_ -> error("unexpected number of outputs")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
use aiken/dict
|
||||
use aiken/list
|
||||
use aiken/transaction.{ScriptContext}
|
||||
use aiken/transaction/credential.{
|
||||
Inline, ScriptCredential, VerificationKeyCredential,
|
||||
}
|
||||
|
||||
fn spend(_datum: Void, _redeemer: Void, ctx: ScriptContext) {
|
||||
let alice =
|
||||
Inline(
|
||||
VerificationKeyCredential(
|
||||
#"22222222222222222222222222222222222222222222222222222222",
|
||||
))
|
||||
|
||||
|
||||
let bob =
|
||||
Inline(
|
||||
ScriptCredential(
|
||||
#"5e1e8fa84f2b557ddc362329413caa3fd89a1be26bfd24be05ce0a02",
|
||||
))
|
||||
|
||||
|
||||
[
|
||||
when dict.get(ctx.transaction.withdrawals, alice) is {
|
||||
None -> error("alice's withdrawal not found")
|
||||
Some(value) -> value == 42
|
||||
},
|
||||
when dict.get(ctx.transaction.withdrawals, bob) is {
|
||||
None -> error("bob's withdrawal not found")
|
||||
Some(value) -> value == 14
|
||||
},
|
||||
dict.keys(ctx.transaction.withdrawals) == [alice, bob],
|
||||
]
|
||||
|> list.and
|
||||
}
|
|
@ -20,14 +20,15 @@ const lucid = await Lucid.new(
|
|||
|
||||
lucid.selectWalletFromPrivateKey(await Deno.readTextFile("./key.sk"));
|
||||
|
||||
const validator = await readValidator("./assets/hello_world/spend/script.cbor");
|
||||
const validator = await readValidator();
|
||||
|
||||
// --- Supporting functions
|
||||
|
||||
async function readValidator(filepath: String): Promise<SpendingValidator> {
|
||||
async function readValidator(): Promise<SpendingValidator> {
|
||||
const validator = JSON.parse(await Deno.readTextFile("plutus.json")).validators[0];
|
||||
return {
|
||||
type: "PlutusV2",
|
||||
script: toHex(cbor.encode(fromHex(await Deno.readTextFile(filepath)))),
|
||||
script: toHex(cbor.encode(fromHex(validator.compiledCode))),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ const lucid = await Lucid.new(
|
|||
|
||||
lucid.selectWalletFromPrivateKey(await Deno.readTextFile("./key.sk"));
|
||||
|
||||
const validator = await readValidator("./assets/hello_world/spend/script.cbor");
|
||||
const validator = await readValidator();
|
||||
|
||||
const utxo = { txHash: Deno.args[0], outputIndex: 0 };
|
||||
|
||||
|
@ -55,9 +55,10 @@ async function unlock(ref, { from, using }): Promise<TxHash> {
|
|||
return signedTx.submit();
|
||||
}
|
||||
|
||||
async function readValidator(filepath: String): Promise<SpendingValidator> {
|
||||
async function readValidator(): Promise<SpendingValidator> {
|
||||
const validator = JSON.parse(await Deno.readTextFile("plutus.json")).validators[0];
|
||||
return {
|
||||
type: "PlutusV2",
|
||||
script: toHex(cbor.encode(fromHex(await Deno.readTextFile(filepath)))),
|
||||
type: "PlutusV2",
|
||||
script: toHex(cbor.encode(fromHex(validator.compiledCode))),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"compiledCode": "58ad0100003232322225333004323253330063372e646e64004dd7198009801002240009210d48656c6c6f2c20576f726c64210013233300100137586600460066600460060089000240206eb8cc008c00c019200022253335573e004294054ccc024cdc79bae300a00200114a226660060066016004002294088c8ccc0040052000003222333300a3370e008004016466600800866e0000d2002300d001001235573c6ea8004526165734ae855d11",
|
||||
"hash": "5e1e8fa84f2b557ddc362329413caa3fd89a1be26bfd24be05ce0a02"
|
||||
"compiledCode": "58e10100003232323232323232222533300632323232533300a002100114a06464660026eb0cc010c014cc010c014019200048040dd7198021802804240006002002444a66601e00429404c8c94ccc038cdc78010018a5113330050050010033012003375c602000466e5cc8dcc8009bae330013002004480012410d48656c6c6f2c20576f726c64210022323330010014800000c888cccc030cdc3802001008119980200219b8000348008c0480040048c024dd50008a4c2c6002002444a66600e004293099802980098040011998018019804801000ab9a5736aae7955cfaba15745",
|
||||
"hash": "287233442cf812fafd74ab135d665f110de89ac12775204ad741f220"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue