fix: it compiles again

This commit is contained in:
rvcas 2022-09-15 11:27:33 -04:00
parent 348ed3b719
commit 26deb6df10
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
2 changed files with 129 additions and 282 deletions

View File

@ -36,46 +36,10 @@ fn main() -> anyhow::Result<()> {
hex::decode(cbor_hex.trim())?
};
let tx = MultiEraTx::decode(Era::Alonzo, &tx_bytes)
.or_else(|_| MultiEraTx::decode(Era::Byron, &tx_bytes))?;
let tx = MultiEraTx::decode(Era::Babbage, &tx_bytes)
.or_else(|_| MultiEraTx::decode(Era::Alonzo, &tx_bytes))?;
println!("Simulating: {}", tx.hash());
let witnesses = tx.witnesses();
if let Some(((datums, redeemers), scripts)) = witnesses
.plutus_data()
.zip(witnesses.redeemer())
.zip(witnesses.plutus_v1_script())
{
for ((datum, redeemer), script) in
datums.iter().zip(redeemers.iter()).zip(scripts.iter())
{
let program: Program<NamedDeBruijn> = {
let mut buffer = Vec::new();
let prog =
Program::<FakeNamedDeBruijn>::from_cbor(&script.0, &mut buffer)?;
prog.into()
};
program
.apply_data(datum.clone())
.apply_data(redeemer.data.clone());
let file = File::open(&resolved_inputs)?;
let reader = BufReader::new(file);
let resolved_inputs: Vec<ResolvedInputOld> =
serde_json::from_reader(reader)?;
let tx_in_info = utils::get_tx_in_info_old(&resolved_inputs)?;
}
}
println!("\nPlutus V2 Script:");
println!("{:#?}", tx.witnesses().plutus_v2_script());
}
},
Args::Uplc(uplc_cmd) => match uplc_cmd {

View File

@ -1,102 +1,21 @@
use pallas_addresses::{
Address, ScriptHash, ShelleyDelegationPart, ShelleyPaymentPart, StakePayload,
};
use pallas_codec::{
minicbor::{bytes::ByteVec},
utils::{AnyUInt, KeyValuePairs, MaybeIndefArray, Bytes, Int},
};
use pallas_crypto::hash::{Hash, Hasher};
use pallas_primitives::{
babbage::{
AddrKeyhash, AssetName, BigInt, Certificate, Coin, Constr, CostModel, DatumHash,
DatumOption, ExUnits, Language, Mint, MintedTx, PlutusV1Script, PlutusV2Script, PolicyId,
Redeemer, RedeemerTag, RewardAccount, Script, ScriptRef, StakeCredential, TransactionInput,
TransactionOutput, Tx, Value, Withdrawals,
},
Fragment,
};
use pallas_traverse::{Era, MultiEraTx, OriginalHash, ComputeHash};
use std::{
collections::HashMap,
convert::{TryFrom, TryInto},
ops::Deref,
str::FromStr,
vec,
use pallas_codec::utils::{AnyUInt, Bytes, Int, KeyValuePairs, MaybeIndefArray};
use pallas_crypto::hash::Hash;
use pallas_primitives::babbage::{
AddrKeyhash, AssetName, BigInt, Certificate, Coin, Constr, DatumHash, DatumOption, ExUnits,
Mint, MintedTx, PlutusV1Script, PlutusV2Script, PolicyId, Redeemer, RedeemerTag, RewardAccount,
Script, ScriptRef, StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
};
use pallas_traverse::{ComputeHash, OriginalHash};
use std::{collections::HashMap, convert::TryInto, ops::Deref, vec};
use uplc::{
ast::{FakeNamedDeBruijn, NamedDeBruijn, Program},
machine::cost_model::ExBudget,
PlutusData,
};
use crate::args::ResolvedInputOld;
pub fn get_tx_in_info_old(resolved_inputs: &[ResolvedInputOld]) -> anyhow::Result<Vec<PlutusData>> {
let mut tx_in_info = Vec::new();
for resolved_input in resolved_inputs {
let tx_out_ref = TransactionInput {
transaction_id: Hash::from_str(resolved_input.input.tx_hash.as_str())?,
index: resolved_input.input.index,
}
.to_plutus_data();
let address = Address::from_bech32(&resolved_input.output.address)?;
let lovelace = resolved_input.output.value.0;
let mut assets = resolved_input.output.value.1.clone();
assets.insert(
"".to_string(),
vec![("".to_string(), lovelace)].into_iter().collect(),
);
let tx_out = PlutusData::Constr(Constr {
tag: 0,
any_constructor: None,
fields: vec![
// txOutAddress
address.to_plutus_data(),
// txOutValue
PlutusData::Map(KeyValuePairs::Def(
assets
.iter()
.map(|val| {
let currency_symbol =
PlutusData::BoundedBytes(hex::decode(val.0).unwrap().into());
let token_map = PlutusData::Map(KeyValuePairs::Def(
val.1
.iter()
.map(|token| {
(
PlutusData::BoundedBytes(
token.0.as_bytes().to_vec().into(),
),
PlutusData::BigInt(BigInt::Int((*token.1 as i64).into())),
)
})
.collect(),
));
(currency_symbol, token_map)
})
.collect(),
)),
],
});
tx_in_info.push(PlutusData::Constr(Constr {
tag: 0,
any_constructor: None,
fields: vec![tx_out_ref, tx_out],
}));
}
Ok(tx_in_info)
}
// ---------------
fn wrap_with_constr(index: u64, data: PlutusData) -> PlutusData {
PlutusData::Constr(Constr {
tag: constr_index(index),
@ -148,10 +67,10 @@ impl ToPlutusData for Address {
let stake_part_plutus_data = match stake_part {
ShelleyDelegationPart::Key(stake_keyhash) => {
Some(StakeCredential::AddrKeyhash(stake_keyhash.clone())).to_plutus_data()
Some(StakeCredential::AddrKeyhash(*stake_keyhash)).to_plutus_data()
}
ShelleyDelegationPart::Script(script_hash) => {
Some(StakeCredential::Scripthash(script_hash.clone())).to_plutus_data()
Some(StakeCredential::Scripthash(*script_hash)).to_plutus_data()
}
ShelleyDelegationPart::Pointer(pointer) => Some(wrap_multiple_with_constr(
1,
@ -202,15 +121,20 @@ impl<K: ToPlutusData, V: ToPlutusData> ToPlutusData for (K, V) {
}
}
impl<A> ToPlutusData for Vec<A> where A: ToPlutusData {
impl<A> ToPlutusData for Vec<A>
where
A: ToPlutusData,
{
fn to_plutus_data(&self) -> PlutusData {
PlutusData::Array(
self.iter().map(|p| p.to_plutus_data()).collect(),
)
PlutusData::Array(self.iter().map(|p| p.to_plutus_data()).collect())
}
}
impl<K, V> ToPlutusData for KeyValuePairs<K, V> where K: ToPlutusData + Clone, V: ToPlutusData + Clone {
impl<K, V> ToPlutusData for KeyValuePairs<K, V>
where
K: ToPlutusData + Clone,
V: ToPlutusData + Clone,
{
fn to_plutus_data(&self) -> PlutusData {
let mut data_vec: Vec<(PlutusData, PlutusData)> = vec![];
for (key, value) in self.iter() {
@ -257,7 +181,7 @@ impl ToPlutusData for AnyUInt {
impl ToPlutusData for Int {
fn to_plutus_data(&self) -> PlutusData {
PlutusData::BigInt(BigInt::Int(self.clone()))
PlutusData::BigInt(BigInt::Int(*self))
}
}
@ -679,7 +603,7 @@ pub enum TxOut {
V2(TransactionOutput),
}
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ScriptPurpose {
Minting(PolicyId),
Spending(TransactionInput),
@ -748,14 +672,12 @@ fn slot_to_begin_posix_time(slot: u64, sc: &SlotConfig) -> u64 {
fn slot_range_to_posix_time_range(slot_range: TimeRange, sc: &SlotConfig) -> TimeRange {
TimeRange {
lower_bound: match slot_range.lower_bound {
Some(lower_bound) => Some(slot_to_begin_posix_time(lower_bound, sc)),
None => None,
},
upper_bound: match slot_range.upper_bound {
Some(upper_bound) => Some(slot_to_begin_posix_time(upper_bound, sc)),
None => None,
},
lower_bound: slot_range
.lower_bound
.map(|lower_bound| slot_to_begin_posix_time(lower_bound, sc)),
upper_bound: slot_range
.upper_bound
.map(|upper_bound| slot_to_begin_posix_time(upper_bound, sc)),
}
}
@ -771,12 +693,12 @@ enum ExecutionPurpose {
NoDatum(ScriptVersion), // Minting, Wdrl, DCert
}
struct DataLookupTable {
pub struct DataLookupTable {
datum: HashMap<DatumHash, PlutusData>,
scripts: HashMap<ScriptHash, ScriptVersion>,
}
fn get_tx_in_info_v1(
pub fn get_tx_in_info_v1(
inputs: &[TransactionInput],
utxos: &[ResolvedInput],
) -> anyhow::Result<Vec<TxInInfo>> {
@ -804,12 +726,10 @@ fn get_tx_in_info_v1(
match &utxo.output {
TransactionOutput::Legacy(_) => {}
TransactionOutput::PostAlonzo(output) => {
match output.datum_option {
Some(DatumOption::Data(_)) => {
unreachable!("Inline datum not allowed in PlutusV1.")
}
_ => {}
};
if let Some(DatumOption::Data(_)) = output.datum_option {
unreachable!("Inline datum not allowed in PlutusV1.")
}
if output.script_ref.is_some() {
unreachable!("Reference scripts not allowed in PlutusV1.")
}
@ -876,20 +796,17 @@ fn get_script_purpose(
.as_ref()
.unwrap_or(&KeyValuePairs::Indef(vec![]))
.iter()
.map(|(policy_id, _)| policy_id.clone())
.map(|(policy_id, _)| *policy_id)
.collect::<Vec<PolicyId>>();
policy_ids.sort();
match policy_ids.get(index as usize) {
Some(policy_id) => Ok(ScriptPurpose::Minting(policy_id.clone())),
Some(policy_id) => Ok(ScriptPurpose::Minting(*policy_id)),
None => unreachable!("Script purpose not found for redeemer."),
}
}
RedeemerTag::Spend => {
// sort lexical by tx_hash and index
let mut inputs = inputs
.iter()
.map(|input| input.clone())
.collect::<Vec<TransactionInput>>();
let mut inputs = inputs.to_vec();
// is this correct? Does this sort lexical from low to high? maybe get Ordering into pallas for TransactionInput?
inputs.sort_by(
|i_a, i_b| match i_a.transaction_id.cmp(&i_b.transaction_id) {
@ -920,7 +837,7 @@ fn get_script_purpose(
let credential = match addresss {
Address::Stake(stake_address) => match stake_address.payload() {
StakePayload::Script(script_hash) => {
StakeCredential::Scripthash(script_hash.clone())
StakeCredential::Scripthash(*script_hash)
}
StakePayload::Stake(_) => {
unreachable!(
@ -950,7 +867,7 @@ fn get_script_purpose(
fn get_tx_info_v1(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
utxos: &[ResolvedInput],
slot_config: &SlotConfig,
) -> anyhow::Result<TxInfo> {
let body = tx.transaction_body.clone();
@ -961,45 +878,39 @@ fn get_tx_info_v1(
let inputs = get_tx_in_info_v1(&body.inputs, &utxos)?;
let outputs =
body.outputs
.iter()
.map(|output| TxOut::V1(output.clone()))
.collect();
let outputs = body
.outputs
.iter()
.map(|output| TxOut::V1(output.clone()))
.collect();
let fee = Value::Coin(body.fee);
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let dcert = body
.certificates
let dcert = body.certificates.clone().unwrap_or_default();
let wdrl = body
.withdrawals
.clone()
.unwrap_or(vec![]);
let wdrl =
body.withdrawals
.clone()
.unwrap_or(KeyValuePairs::Indef(vec![]))
.deref()
.clone();
.unwrap_or(KeyValuePairs::Indef(vec![]))
.deref()
.clone();
let valid_range = slot_range_to_posix_time_range(
TimeRange {
lower_bound: body.validity_interval_start,
upper_bound: body.ttl,
},
&slot_config,
slot_config,
);
let signatories = body
.required_signers
.clone()
.unwrap_or(vec![]);
let signatories = body.required_signers.clone().unwrap_or_default();
let data =
tx.transaction_witness_set
.plutus_data
.as_ref()
.unwrap_or(&vec![])
.iter()
.map(|d| (d.original_hash(), d.unwrap()))
.collect();
let data = tx
.transaction_witness_set
.plutus_data
.as_ref()
.unwrap_or(&vec![])
.iter()
.map(|d| (d.original_hash(), d.clone().unwrap()))
.collect();
let id = tx.transaction_body.compute_hash();
@ -1019,30 +930,22 @@ fn get_tx_info_v1(
fn get_tx_info_v2(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
utxos: &[ResolvedInput],
slot_config: &SlotConfig,
) -> anyhow::Result<TxInfo> {
let body = tx.transaction_body.clone();
let inputs = get_tx_in_info_v2(&body.inputs, &utxos)?;
let reference_inputs = get_tx_in_info_v2(
&body
.reference_inputs
.clone()
.unwrap_or(vec![]),
&utxos,
)?;
let outputs =
body.outputs
.iter()
.map(|output| TxOut::V2(output.clone()))
.collect();
let inputs = get_tx_in_info_v2(&body.inputs, utxos)?;
let reference_inputs =
get_tx_in_info_v2(&body.reference_inputs.clone().unwrap_or_default(), utxos)?;
let outputs = body
.outputs
.iter()
.map(|output| TxOut::V2(output.clone()))
.collect();
let fee = Value::Coin(body.fee);
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let dcert = body
.certificates
.clone()
.unwrap_or(vec![]);
let dcert = body.certificates.clone().unwrap_or_default();
let wdrl = body
.withdrawals
.clone()
@ -1052,12 +955,9 @@ fn get_tx_info_v2(
lower_bound: body.validity_interval_start,
upper_bound: body.ttl,
},
&slot_config,
slot_config,
);
let signatories = body
.required_signers
.clone()
.unwrap_or(vec![]);
let signatories = body.required_signers.clone().unwrap_or_default();
let redeemers = KeyValuePairs::Indef(
tx.transaction_witness_set
.redeemer
@ -1067,7 +967,7 @@ fn get_tx_info_v2(
.map(|r| {
(
get_script_purpose(
&r,
r,
&tx.transaction_body.inputs,
&tx.transaction_body.mint,
&tx.transaction_body.certificates,
@ -1085,7 +985,7 @@ fn get_tx_info_v2(
.as_ref()
.unwrap_or(&vec![])
.iter()
.map(|d| (d.original_hash(), d.unwrap()))
.map(|d| (d.original_hash(), d.clone().unwrap()))
.collect(),
);
let id = tx.transaction_body.compute_hash();
@ -1107,7 +1007,7 @@ fn get_tx_info_v2(
}
fn get_execution_purpose(
utxos: &MaybeIndefArray<ResolvedInput>,
utxos: &[ResolvedInput],
script_purpose: &ScriptPurpose,
lookup_table: &DataLookupTable,
) -> ExecutionPurpose {
@ -1120,7 +1020,7 @@ fn get_execution_purpose(
Some(s) => s.clone(),
None => unreachable!("Missing required scripts.")
};
ExecutionPurpose::NoDatum(script.clone())
ExecutionPurpose::NoDatum(script)
}
ScriptPurpose::Spending(out_ref) => {
let utxo = utxos.iter().find(|utxo| utxo.input == *out_ref).unwrap();
@ -1129,22 +1029,19 @@ fn get_execution_purpose(
let address = Address::from_bytes(&output.address).unwrap();
match address {
Address::Shelley(shelley_address) => {
let script = match lookup_table
.scripts
.get(&shelley_address.payment().as_hash()) {
.get(shelley_address.payment().as_hash()) {
Some(s) => s.clone(),
None => unreachable!("Missing required scripts.")
};
let datum = match lookup_table.datum.get(&output.datum_hash.unwrap_or_else(|| unreachable!("Missing datum hash in input."))) {
Some(d) => d.clone(),
None => unreachable!("Missing datum in witness set.")
};
ExecutionPurpose::WithDatum(script.clone(), datum.clone())
ExecutionPurpose::WithDatum(script, datum)
}
_ => unreachable!(
"This is impossible. Only shelley addresses can contain a script hash."
@ -1158,7 +1055,7 @@ fn get_execution_purpose(
let script = match lookup_table
.scripts
.get(&shelley_address.payment().as_hash()) {
.get(shelley_address.payment().as_hash()) {
Some(s) => s.clone(),
None => unreachable!("Missing required scripts.")
};
@ -1166,13 +1063,13 @@ fn get_execution_purpose(
let datum = match &output.datum_option {
Some(DatumOption::Hash(hash)) => {
lookup_table.datum.get(&hash).unwrap().clone()
lookup_table.datum.get(hash).unwrap().clone()
}
Some(DatumOption::Data(data)) => data.0.clone(),
_ => unreachable!( "Missing datum hash or inline datum in input."),
};
ExecutionPurpose::WithDatum(script.clone(), datum)
ExecutionPurpose::WithDatum(script, datum)
}
_ => unreachable!(
"This is impossible. Only shelley addresses can contain a script hash."
@ -1183,7 +1080,7 @@ fn get_execution_purpose(
}
ScriptPurpose::Rewarding(stake_credential) => {
let script_hash = match stake_credential {
StakeCredential::Scripthash(hash) => hash.clone(),
StakeCredential::Scripthash(hash) => *hash,
_ => unreachable!("This is impossible. A key hash cannot be the hash of a script."),
};
@ -1198,7 +1095,7 @@ fn get_execution_purpose(
// StakeRegistration doesn't require a witness from a stake key/script. So I assume it doesn't need to be handled in Plutus either?
Certificate::StakeDeregistration(stake_credential) => {
let script_hash = match stake_credential {
StakeCredential::Scripthash(hash) => hash.clone(),
StakeCredential::Scripthash(hash) => *hash,
_ => unreachable!(
"This is impossible. A key hash cannot be the hash of a script."
),
@ -1213,7 +1110,7 @@ fn get_execution_purpose(
}
Certificate::StakeDelegation(stake_credential, _) => {
let script_hash = match stake_credential {
StakeCredential::Scripthash(hash) => hash.clone(),
StakeCredential::Scripthash(hash) => *hash,
_ => unreachable!(
"This is impossible. A key hash cannot be the hash of a script."
),
@ -1231,10 +1128,7 @@ fn get_execution_purpose(
}
}
fn get_script_and_datum_lookup_table(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
) -> DataLookupTable {
fn get_script_and_datum_lookup_table(tx: &MintedTx, utxos: &[ResolvedInput]) -> DataLookupTable {
let mut datum = HashMap::new();
let mut scripts = HashMap::new();
@ -1244,30 +1138,32 @@ fn get_script_and_datum_lookup_table(
.transaction_witness_set
.plutus_data
.clone()
.unwrap_or(vec![]);
.unwrap_or_default();
let scripts_v1_witnesses = tx
.transaction_witness_set
.plutus_v1_script
.clone()
.unwrap_or(vec![]);
.unwrap_or_default();
let scripts_v2_witnesses = tx
.transaction_witness_set
.plutus_v2_script
.clone()
.unwrap_or(vec![]);
.unwrap_or_default();
for plutus_data in plutus_data_witnesses.iter() {
datum.insert(plutus_data.original_hash(), plutus_data.clone());
datum.insert(plutus_data.original_hash(), plutus_data.clone().unwrap());
}
for script in scripts_v1_witnesses.iter() {
scripts.insert(script.compute_hash(), ScriptVersion::V1(script.clone())); // TODO: fix hashing bug in pallas
scripts.insert(script.compute_hash(), ScriptVersion::V1(script.clone()));
// TODO: fix hashing bug in pallas
}
for script in scripts_v2_witnesses.iter() {
scripts.insert(script.compute_hash(), ScriptVersion::V2(script.clone())); // TODO: fix hashing bug in pallas
scripts.insert(script.compute_hash(), ScriptVersion::V2(script.clone()));
// TODO: fix hashing bug in pallas
}
// discovery in utxos (script ref)
@ -1275,38 +1171,28 @@ fn get_script_and_datum_lookup_table(
for utxo in utxos.iter() {
match &utxo.output {
TransactionOutput::Legacy(_) => {}
TransactionOutput::PostAlonzo(output) => match &output.script_ref {
Some(script) => match &script.0 {
Script::PlutusV1Script(v1) => {
// scripts.insert(v1.to_hash(), ScriptVersion::PlutusV1(v1.clone())); // TODO: fix hashing bug in pallas
let mut prefixed_script: Vec<u8> = vec![0x01];
prefixed_script.extend(v1.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::V1(v1.clone()));
TransactionOutput::PostAlonzo(output) => {
if let Some(script) = &output.script_ref {
match &script.0 {
Script::PlutusV1Script(v1) => {
scripts.insert(v1.compute_hash(), ScriptVersion::V1(v1.clone()));
}
Script::PlutusV2Script(v2) => {
scripts.insert(v2.compute_hash(), ScriptVersion::V2(v2.clone()));
}
_ => {}
}
Script::PlutusV2Script(v2) => {
// scripts.insert(v2.to_hash(), ScriptVersion::PlutusV2(v2.clone())); // TODO: fix hashing bug in pallas
let mut prefixed_script: Vec<u8> = vec![0x02];
prefixed_script.extend(v2.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::V2(v2.clone()));
}
_ => {}
},
_ => {}
},
}
}
}
}
DataLookupTable { datum, scripts }
}
fn eval_redeemer(
pub fn eval_redeemer(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
utxos: &[ResolvedInput],
slot_config: &SlotConfig,
redeemer: &Redeemer,
lookup_table: &DataLookupTable,
@ -1336,7 +1222,7 @@ fn eval_redeemer(
};
let result = program
.apply_data(datum.clone())
.apply_data(datum)
.apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data())
.eval();
@ -1371,7 +1257,7 @@ fn eval_redeemer(
};
let result = program
.apply_data(datum.clone())
.apply_data(datum)
.apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data())
.eval();
@ -1467,12 +1353,12 @@ fn eval_redeemer(
}
}
fn eval_tx(
pub fn eval_tx(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
utxos: &[ResolvedInput],
//TODO: costMdls
slot_config: &SlotConfig,
) -> anyhow::Result<MaybeIndefArray<Redeemer>> {
) -> anyhow::Result<Vec<Redeemer>> {
let redeemers = tx.transaction_witness_set.redeemer.as_ref();
let lookup_table = get_script_and_datum_lookup_table(tx, utxos);
@ -1489,9 +1375,9 @@ fn eval_tx(
&lookup_table,
)?)
}
Ok(MaybeIndefArray::Indef(collected_redeemers))
Ok(collected_redeemers)
}
None => Ok(MaybeIndefArray::Indef(vec![])),
None => Ok(vec![]),
}
}
@ -1500,12 +1386,11 @@ mod tests {
use pallas_codec::utils::MaybeIndefArray;
use pallas_primitives::{
babbage::{TransactionInput, TransactionOutput},
Fragment, ToHash,
Fragment,
};
use pallas_traverse::{Era, MultiEraTx};
use uplc::PlutusData;
use super::{eval_tx, ResolvedInput, SlotConfig, TxInInfo};
use super::{eval_tx, ResolvedInput, SlotConfig};
#[test]
fn test_eval() {
@ -1526,19 +1411,17 @@ mod tests {
let raw_inputs = hex::decode("84825820b16778c9cf065d9efeefe37ec269b4fc5107ecdbd0dd6bf3274b224165c2edd9008258206c732139de33e916342707de2aebef2252c781640326ff37b86ec99d97f1ba8d01825820975c17a4fed0051be622328efa548e206657d2b65a19224bf6ff8132571e6a500282582018f86700660fc88d0370a8f95ea58f75507e6b27a18a17925ad3b1777eb0d77600").unwrap();
let raw_outputs = hex::decode("8482581d60b6c8794e9a7a26599440a4d0fd79cd07644d15917ff13694f1f67235821a000f8548a1581c15be994a64bdb79dde7fe080d8e7ff81b33a9e4860e9ee0d857a8e85a144576177610182581d60b6c8794e9a7a26599440a4d0fd79cd07644d15917ff13694f1f672351b00000001af14b8b482581d60b6c8794e9a7a26599440a4d0fd79cd07644d15917ff13694f1f672351a0098968082581d60b6c8794e9a7a26599440a4d0fd79cd07644d15917ff13694f1f672351a00acd8c6").unwrap();
let inputs = MaybeIndefArray::<TransactionInput>::decode_fragment(&raw_inputs).unwrap();
let outputs = MaybeIndefArray::<TransactionOutput>::decode_fragment(&raw_outputs).unwrap();
let inputs = Vec::<TransactionInput>::decode_fragment(&raw_inputs).unwrap();
let outputs = Vec::<TransactionOutput>::decode_fragment(&raw_outputs).unwrap();
let utxos: MaybeIndefArray<ResolvedInput> = MaybeIndefArray::Indef(
inputs
.iter()
.zip(outputs.iter())
.map(|(input, output)| ResolvedInput {
input: input.clone(),
output: output.clone(),
})
.collect(),
);
let utxos: Vec<ResolvedInput> = inputs
.iter()
.zip(outputs.iter())
.map(|(input, output)| ResolvedInput {
input: input.clone(),
output: output.clone(),
})
.collect();
let slot_config = SlotConfig {
zero_time: 1660003200000, // Preview network
@ -1552,7 +1435,7 @@ mod tests {
MultiEraTx::Babbage(tx) => {
let redeemers = eval_tx(&tx, &utxos, &slot_config).unwrap();
println!("{:?}", redeemers.len());
assert_eq!(redeemers.len(), 1)
}
_ => unreachable!(),
};