From 2b7d884a918eefbed3e6355b2ad825477ec881a6 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Wed, 28 Aug 2024 11:10:39 +0200 Subject: [PATCH 01/38] Implement extra golden tests for external use --- plutus-ledger-api/src/goldens/v1.rs | 34 ++++++++++++++++++++--------- plutus-ledger-api/src/goldens/v2.rs | 8 +++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/plutus-ledger-api/src/goldens/v1.rs b/plutus-ledger-api/src/goldens/v1.rs index 09b24b0..fa7b472 100644 --- a/plutus-ledger-api/src/goldens/v1.rs +++ b/plutus-ledger-api/src/goldens/v1.rs @@ -14,13 +14,16 @@ use crate::{ }, value::{AssetClass, CurrencySymbol, TokenName, Value}, }, + v2::address::{CertificateIndex, ChainPointer, Slot, TransactionIndex}, }; use num_bigint::BigInt; +pub fn sample_script_hash() -> ScriptHash { + ScriptHash(LedgerBytes([1].repeat(28).to_vec())) +} + pub fn sample_currency_symbol() -> CurrencySymbol { - CurrencySymbol::NativeToken(MintingPolicyHash(ScriptHash(LedgerBytes( - [0].repeat(28).to_vec(), - )))) + CurrencySymbol::NativeToken(MintingPolicyHash(sample_script_hash())) } pub fn sample_token_name() -> TokenName { @@ -50,10 +53,20 @@ pub fn sample_ed25519_pub_key_hash() -> Ed25519PubKeyHash { Ed25519PubKeyHash(LedgerBytes([0].repeat(28).to_vec())) } +pub fn sample_credential() -> Credential { + Credential::Script(ValidatorHash(sample_script_hash())) +} + pub fn sample_staking_credential() -> StakingCredential { - StakingCredential::Hash(Credential::Script(ValidatorHash(ScriptHash(LedgerBytes( - [1].repeat(28).to_vec(), - ))))) + StakingCredential::Hash(sample_credential()) +} + +pub fn sample_chain_pointer() -> ChainPointer { + ChainPointer { + slot_number: Slot(134561.into()), + transaction_index: TransactionIndex(4.into()), + certificate_index: CertificateIndex(10.into()), + } } pub fn sample_address() -> Address { @@ -78,11 +91,12 @@ pub fn sample_datum_hash() -> DatumHash { DatumHash(LedgerBytes([0].repeat(32).to_vec())) } +pub fn sample_plutus_data() -> PlutusData { + PlutusData::constr(1, vec![PlutusData::bytes("Something".as_bytes().to_vec())]) +} + pub fn sample_datum() -> Datum { - Datum(PlutusData::constr( - 1, - vec![PlutusData::bytes("Something".as_bytes().to_vec())], - )) + Datum(sample_plutus_data()) } pub fn sample_redeemer_hash() -> RedeemerHash { diff --git a/plutus-ledger-api/src/goldens/v2.rs b/plutus-ledger-api/src/goldens/v2.rs index e879296..5542f7c 100644 --- a/plutus-ledger-api/src/goldens/v2.rs +++ b/plutus-ledger-api/src/goldens/v2.rs @@ -1,4 +1,12 @@ //! Golden test data or Plutus V2 types +pub use super::v1::{ + sample_address, sample_asset_class, sample_chain_pointer, sample_credential, + sample_currency_symbol, sample_datum, sample_datum_hash, sample_dcert, + sample_ed25519_pub_key_hash, sample_payment_pub_key_hash, sample_plutus_data, + sample_plutus_interval, sample_redeemer, sample_redeemer_hash, sample_script_hash, + sample_script_purpose, sample_staking_credential, sample_token_name, sample_transaction_hash, + sample_transaction_input, sample_value, +}; use crate::v2::{ assoc_map::AssocMap, crypto::LedgerBytes, From fb8cc8e9c6c3ae279162aef481636ff381f1e8c4 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 24 Sep 2024 11:14:06 +0200 Subject: [PATCH 02/38] Update golden tests --- .../tests/testdata/v1_asset_class.golden | 56 +-- .../tests/testdata/v1_script_context.golden | 280 ++++++------- .../tests/testdata/v1_script_purpose.golden | 56 +-- .../tests/testdata/v1_transaction_info.golden | 224 +++++----- .../testdata/v1_transaction_output.golden | 56 +-- .../tests/testdata/v1_tx_in_info.golden | 56 +-- .../tests/testdata/v1_value.golden | 56 +-- .../tests/testdata/v2_script_context.golden | 392 +++++++++--------- .../tests/testdata/v2_transaction_info.golden | 336 +++++++-------- .../testdata/v2_transaction_output.golden | 56 +-- .../tests/testdata/v2_tx_in_info.golden | 56 +-- 11 files changed, 812 insertions(+), 812 deletions(-) diff --git a/plutus-ledger-api/tests/testdata/v1_asset_class.golden b/plutus-ledger-api/tests/testdata/v1_asset_class.golden index 2fe461a..9e193eb 100644 --- a/plutus-ledger-api/tests/testdata/v1_asset_class.golden +++ b/plutus-ledger-api/tests/testdata/v1_asset_class.golden @@ -3,34 +3,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Bytes( diff --git a/plutus-ledger-api/tests/testdata/v1_script_context.golden b/plutus-ledger-api/tests/testdata/v1_script_context.golden index b3be0f2..d9fd145 100644 --- a/plutus-ledger-api/tests/testdata/v1_script_context.golden +++ b/plutus-ledger-api/tests/testdata/v1_script_context.golden @@ -155,34 +155,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -356,34 +356,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -461,34 +461,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -521,34 +521,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -895,34 +895,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), ], diff --git a/plutus-ledger-api/tests/testdata/v1_script_purpose.golden b/plutus-ledger-api/tests/testdata/v1_script_purpose.golden index af1c3c3..e396f0e 100644 --- a/plutus-ledger-api/tests/testdata/v1_script_purpose.golden +++ b/plutus-ledger-api/tests/testdata/v1_script_purpose.golden @@ -3,34 +3,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), ], diff --git a/plutus-ledger-api/tests/testdata/v1_transaction_info.golden b/plutus-ledger-api/tests/testdata/v1_transaction_info.golden index 4d6d21b..5b750f0 100644 --- a/plutus-ledger-api/tests/testdata/v1_transaction_info.golden +++ b/plutus-ledger-api/tests/testdata/v1_transaction_info.golden @@ -152,34 +152,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -353,34 +353,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -458,34 +458,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -518,34 +518,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( diff --git a/plutus-ledger-api/tests/testdata/v1_transaction_output.golden b/plutus-ledger-api/tests/testdata/v1_transaction_output.golden index 0a98a9d..ca371d7 100644 --- a/plutus-ledger-api/tests/testdata/v1_transaction_output.golden +++ b/plutus-ledger-api/tests/testdata/v1_transaction_output.golden @@ -95,34 +95,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( diff --git a/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden b/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden index a394d41..2c2e0c5 100644 --- a/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden +++ b/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden @@ -147,34 +147,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( diff --git a/plutus-ledger-api/tests/testdata/v1_value.golden b/plutus-ledger-api/tests/testdata/v1_value.golden index ac756e7..3e6b527 100644 --- a/plutus-ledger-api/tests/testdata/v1_value.golden +++ b/plutus-ledger-api/tests/testdata/v1_value.golden @@ -3,34 +3,34 @@ Map( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( diff --git a/plutus-ledger-api/tests/testdata/v2_script_context.golden b/plutus-ledger-api/tests/testdata/v2_script_context.golden index f44208a..7357b59 100644 --- a/plutus-ledger-api/tests/testdata/v2_script_context.golden +++ b/plutus-ledger-api/tests/testdata/v2_script_context.golden @@ -155,34 +155,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -427,34 +427,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -647,34 +647,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -771,34 +771,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -831,34 +831,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -1099,34 +1099,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), ], @@ -1245,34 +1245,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), ], diff --git a/plutus-ledger-api/tests/testdata/v2_transaction_info.golden b/plutus-ledger-api/tests/testdata/v2_transaction_info.golden index 9ac751d..4829d60 100644 --- a/plutus-ledger-api/tests/testdata/v2_transaction_info.golden +++ b/plutus-ledger-api/tests/testdata/v2_transaction_info.golden @@ -152,34 +152,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -424,34 +424,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -644,34 +644,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -768,34 +768,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -828,34 +828,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( @@ -1096,34 +1096,34 @@ Constr( [ Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), ], diff --git a/plutus-ledger-api/tests/testdata/v2_transaction_output.golden b/plutus-ledger-api/tests/testdata/v2_transaction_output.golden index e7110a7..8f6dad8 100644 --- a/plutus-ledger-api/tests/testdata/v2_transaction_output.golden +++ b/plutus-ledger-api/tests/testdata/v2_transaction_output.golden @@ -95,34 +95,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( diff --git a/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden b/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden index d07191e..65c6342 100644 --- a/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden +++ b/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden @@ -147,34 +147,34 @@ Constr( ( Bytes( [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ], ), Map( From e9adfe878b2c055f2a5fe10112ea13e0dc8a4ce4 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 3 Oct 2024 14:00:51 +0200 Subject: [PATCH 03/38] Custom serde serialization for Value --- plutus-ledger-api/Cargo.lock | 5 +- plutus-ledger-api/Cargo.toml | 6 +- plutus-ledger-api/src/v1/value.rs | 99 +++++++++-- plutus-ledger-api/tests/{json.rs => lbf.rs} | 2 +- .../tests/serde.proptest-regressions | 15 ++ plutus-ledger-api/tests/serde.rs | 161 ++++++++++++++++++ 6 files changed, 266 insertions(+), 22 deletions(-) rename plutus-ledger-api/tests/{json.rs => lbf.rs} (99%) create mode 100644 plutus-ledger-api/tests/serde.proptest-regressions create mode 100644 plutus-ledger-api/tests/serde.rs diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index dbc4968..06d8f7f 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -508,11 +508,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index db2417d..c77964c 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -11,9 +11,7 @@ repository = "https://github.com/mlabs-haskell/plutus-ledger-api-rust" [dependencies] proptest = "^1.3.1" lbr-prelude = { version = "0.1.1", optional = true } -serde_json = { version = "^1.0.107", features = [ - "arbitrary_precision", -], optional = true } +serde_json = { version = "1.0.128", optional = true } num-bigint = "~0.4" serde = { version = "^1.0.189", features = ["derive"], optional = true } true = { version = "~0.1.0", optional = true } @@ -26,7 +24,7 @@ chrono = { version = "0.4.34", optional = true } [features] default = [] -serde = ["dep:serde", "num-bigint/serde"] +serde = ["dep:serde", "num-bigint/serde", "dep:serde_json"] lbf = ["dep:lbr-prelude", "dep:serde_json"] chrono = ["dep:chrono"] diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index f3a3045..249e6ff 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -39,13 +39,11 @@ impl IsPlutusData for CurrencySymbol { } fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).and_then(|bytes: LedgerBytes| { + IsPlutusData::from_plutus_data(data).map(|bytes: LedgerBytes| { if bytes.0.is_empty() { - Ok(CurrencySymbol::Ada) + CurrencySymbol::Ada } else { - Ok(CurrencySymbol::NativeToken(MintingPolicyHash(ScriptHash( - bytes, - )))) + CurrencySymbol::NativeToken(MintingPolicyHash(ScriptHash(bytes))) } }) } @@ -79,11 +77,68 @@ impl Json for CurrencySymbol { } /// A value that can contain multiple asset classes -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Value(pub BTreeMap>); +#[cfg(feature = "serde")] +mod value_serde { + use std::collections::BTreeMap; + + use num_bigint::BigInt; + use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize}; + + use super::{CurrencySymbol, TokenName, Value}; + + struct Assets(BTreeMap); + + impl Serialize for Value { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq( + self.0 + .iter() + .map(|(cur_sym, assets)| (cur_sym, Assets(assets.to_owned()))), + ) + } + } + + impl<'de> Deserialize<'de> for Value { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let vec: Vec<(CurrencySymbol, Assets)> = Vec::deserialize(deserializer)?; + + Ok(Value( + vec.into_iter().map(|(cs, assets)| (cs, assets.0)).collect(), + )) + } + } + + impl Serialize for Assets { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq(self.0.iter()) + } + } + + impl<'de, 'a> Deserialize<'de> for Assets { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let vec: Vec<(TokenName, BigInt)> = Vec::deserialize(deserializer)?; + + Ok(Assets(vec.into_iter().collect())) + } + } +} + impl Value { pub fn new() -> Self { Value(BTreeMap::new()) @@ -105,7 +160,7 @@ impl Value { pub fn get_token_amount(&self, cs: &CurrencySymbol, tn: &TokenName) -> BigInt { self.0 .get(cs) - .and_then(|tn_map| tn_map.get(&tn)) + .and_then(|tn_map| tn_map.get(tn)) .map_or(BigInt::zero(), Clone::clone) } @@ -124,7 +179,7 @@ impl Value { tn_map .entry(tn.clone()) .and_modify(|old_a| { - *old_a = a.clone(); + old_a.clone_from(a); }) .or_insert_with(|| a.clone()); }) @@ -143,6 +198,26 @@ impl Value { self.filter(|_, _, a| a.is_zero().not()) } + pub fn is_subset(&self, b: &Value) -> bool { + (b - self) + .clone() + .normalize() + // Has negative entries? + .filter(|_, _, amount| amount < &BigInt::from(0u32)) + .is_empty() + } + + pub fn is_pure_ada(self) -> bool { + let inner = self.normalize().0; + let inner: Vec<_> = inner.into_iter().collect(); + + match inner.as_slice() { + [] => true, + [(cs, _)] => cs == &CurrencySymbol::Ada, + _ => false, + } + } + /// Apply a function to each token of the value, and use its result as the new amount. pub fn map_amount(self, mut f: F) -> Self where @@ -188,12 +263,6 @@ impl Value { } } -impl Default for Value { - fn default() -> Self { - Self(BTreeMap::new()) - } -} - impl Zero for Value { fn zero() -> Self { Default::default() diff --git a/plutus-ledger-api/tests/json.rs b/plutus-ledger-api/tests/lbf.rs similarity index 99% rename from plutus-ledger-api/tests/json.rs rename to plutus-ledger-api/tests/lbf.rs index c918724..a71ac3e 100644 --- a/plutus-ledger-api/tests/json.rs +++ b/plutus-ledger-api/tests/lbf.rs @@ -1,6 +1,6 @@ #[cfg(test)] #[cfg(feature = "lbf")] -mod json_roundtrip_tests { +mod lb_json_roundtrip_tests { use lbr_prelude::json::{Error, Json}; fn from_to_json(val: &T) -> Result where diff --git a/plutus-ledger-api/tests/serde.proptest-regressions b/plutus-ledger-api/tests/serde.proptest-regressions new file mode 100644 index 0000000..ef0ed42 --- /dev/null +++ b/plutus-ledger-api/tests/serde.proptest-regressions @@ -0,0 +1,15 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc b1c17d89cb2c4087ca1f95b15b7f1312a37c33526bd37afc13254e8030ede155 # shrinks to val = TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(000000000000000000000001b3ac92cbb5c5386f63579aab8d275075)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1323a50422e1cefc776900417e9a2c65b7d62c3c69d773990eb55eed))): {TokenName(24e4a63b3550f034484bc3cdb4acd4e0f2ecaf9d92f804e6c35bf13d3cd06712): 4052692294, TokenName(62b4c5e42779e5f33f34884c0f747c6c8218016de3d3bc16aa53212fb57dca64): 806378676, TokenName(877f2c64113927b43e3174544dc03a14f318a0b341347e497bc599c54ab329d1): 1330682733, TokenName(e1665048fc1253c116fbdbd5274cd5831cd42c4a1e7866b3b347845303ce0a35): 3833112553, TokenName(fc96020ec9705256c2dd221c98f151b5bab9c6267e4815a04a5ced7cd0bc15a5): 2966980009}, NativeToken(MintingPolicyHash(ScriptHash(1a578eb605337e7975d3bfb7a499b7bf6c5dce67f5369bdd0c1b0204))): {TokenName(4fa6ea25c720b41ce50852f4c0f45714716f33761d34d0102d86912d1e31c448): 3970296511, TokenName(90d6b22e6dddec599e14280f3ca3ffce0d5e5e39125e2e71ad44d907f4c1a657): 3950474072, TokenName(94ed7a0cb19ec9e8e273b4ca593e96c58fd2ea426d85ec8f0fd10b4a34e0c3c4): 2568538332, TokenName(9b28aaca088d92bdadae12eea29f38f5a68b7b5394dc3f66d39eeaca18cba8ab): 1520145484, TokenName(a06be355b020fde56946bda558c5269a6b58e791ffc49616969ad6dbff2d449a): 1987977824}, NativeToken(MintingPolicyHash(ScriptHash(6bdd2b58833f83b83b63d4614fc519662d8d099351570f4397603307))): {TokenName(1dd469853e7868eb330d75bb018cca1a07c9da4d6add9eb250b84e6a5628c96d): 2144987589, TokenName(3a03221f8ef5c831853c598c6f025af529fd4fb3be46075c114be9512e0b5b1f): 3787481019, TokenName(793b8ea5d945b96f9223a2c2fc13f7fedeb68928aeee9724c240564351c7675c): 2478716803, TokenName(b743679afcc2fce2ba105f4d7029d4c9808a79fb95a7364ced89aa02288a76d7): 3505601434, TokenName(e77d85645a2a19dcdfe0201b33e77cec2785d8f93e70843fc5651f54a4024db1): 1813187621}, NativeToken(MintingPolicyHash(ScriptHash(770ecf6a777ee674b01d2fee75e086f381ec7ac3cf8fb372b3335614))): {TokenName(113f0b5ea9b6f4b886fe37e50cf7e9c1140dab723b444909fcdbe26481c9d6ee): 2174643095, TokenName(18ddc1bd38875cef3e85c309eeb6d3c542f5a08a59e2566b899e8a195021367a): 2966220028, TokenName(47545e0285fe6eb7b36e7d8bc9e10b28251056ae45898033d2c4904e9ee77e55): 2126438577, TokenName(5fd1ae3e2e71d5bc2ca6b63a91a3249bbc20bc1d02eace02187330dd37b62ca2): 585634295, TokenName(805294b21b804c232a573b26f4a68b025dffccf8a389bcbfccc9a1133fa949bb): 2574511089}, NativeToken(MintingPolicyHash(ScriptHash(aa5e20202d7ebcef3722640132058784312adbe1462de47de6476420))): {TokenName(83659f7546f8475b53ac412167261b41aa8fe39a840c0bb6640fb895e376405d): 1333949599, TokenName(d50096f8f220094cdc6bfcc09d4027b2c8d9aa76bc832135e3f759a79c1c8c21): 1139917772, TokenName(da48eb636c0f71f69265516ff18818a0abca6097d2b36d1941b96edd6fbd8f6b): 1795366150, TokenName(dea5d26f08da84f4d41c7bbdc80ebcd0ebda8529be91c633947707ada74d936e): 1440752344, TokenName(e81efb96588cfc9a3f39d05f2c5104be830832ba7ebcbfd7b8c360c84d74f534): 1487908621}}), datum: None, reference_script: None } } +cc 13e6892c12a0adb0a78d1574f42bda31a80466e9f11374a9dafa15c86cab2302 # shrinks to val = TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 3351355059690873586}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000c4a412e95f656d23a96328922a900d2ee5fc53f): 4007578882, TokenName(11a4f0f03e60e63d6d117f49ea2e9ad9da2c3035418335886be7219f9a3475cc): 3734091249, TokenName(14059d2a785e91a4de0fa379f6b692bb7ccec27f37fa7a94cbb52680be837267): 211916204, TokenName(16ec936c15c6efac15dc0a52edf49207429d581c5e81eb3c3c90715978771747): 813082854}, NativeToken(MintingPolicyHash(ScriptHash(1807c470904538fca75a8bef3c58477b6dc55e942d18ba7a77f7bbd9))): {TokenName(2ae27047fac788c1b510a203a57d9bdd18d990025f292e8cb1cd92376593b9a2): 3589724762, TokenName(2dfcc2f461b0fdaf1cf4d648674fda4882f84d87b013f3db8fb52863b40643a3): 2466834830, TokenName(59859fd60af5ea72e0ef60e81b6926ff3adf3ecddf7e70d864feaf81598e66b6): 3768615940, TokenName(91fae3ce742d4d6e474cbb5908718d07480938d5c4bf299fe3519f20fe5bdcf0): 3457482975, TokenName(a28cc6ec581dabaa93a22bcfff7e093b280dc03cb5d2c2d1f5abd93f4104c8de): 1750809165}, NativeToken(MintingPolicyHash(ScriptHash(6bac92a2a3351e841fd7ffc1f3b4198f1f47fe4e33ef96d2903569c4))): {TokenName(03edaff3b48cde1872af44ee6c92922cedc4411ee0338af1b171a21b21084d26): 991468614, TokenName(14b56c27a338c8b6b70ad4237c54ea412ff431593f43369eb8b494560c336572): 2996247931, TokenName(41d6bebf8662e7bab8f746e3bae279b7864ef7e0101454514a4962b7adf5957c): 2956570886, TokenName(51b4bf33fb1559d603262face6c4428d0d87945fdd682652bc8d7dd030ebab50): 2254790562, TokenName(624d2e1fb8df51befe3bf161ecc4cef0f77f706dc4e16aef853dc268904559ea): 1710855054}, NativeToken(MintingPolicyHash(ScriptHash(79a516785f9797629f9c2c32afec01bf422d2fb103e1f84aaa99326e))): {TokenName(127cc8a57b489b8aaaa254d27524c5ffdb98244864fdc99e10041e0c70b9e7bb): 2911123850, TokenName(26c7a7d0e6a64c4d28d5297f9d10bbc2c61f28482a4fa2c3125ffdf41075981e): 1533600818, TokenName(5e938908c855f0d5631501da422f9f6b24b79482cd3e4d7ad8c7d35717404ca9): 1158808136, TokenName(6bc88da6b280231b3648fe273be94f29bdb9cd8de23b2f3b5a93d8a7bce0ed32): 4220629354, TokenName(d912b414d54a571ef3d97d7818572f281a889160f906eac0159055c31d6ea72b): 2055194512}, NativeToken(MintingPolicyHash(ScriptHash(d7562bd106cc7fa0e674604afa71e913d2e801157f61e2a2c99cf4a3))): {TokenName(2b6fac61611a8c905e9b2c26862a67c4d07938692a627023a66e4adb0031bf83): 2124892851, TokenName(77b22426fd6e190fbcbc666f0412d896eff5b701b583f1b013c3fc7faf41b8c0): 2827264884, TokenName(d85fa013fcb417b5334c54dee99cefe8bf7ca8322f9bde074db675a6b939f701): 2233309242, TokenName(dd584dcedc92ae2baf2feb81349e5f696b6b9aa9e9f1fb58afae45a45b7335cf): 2360756438, TokenName(de403ae8065c27720e1f26fc9fe6b723a6268c5b092f23273c649795be99bd52): 1094933406}}), datum_hash: None } } +cc efb15ee8f6ff1c2694b1ad1eb4cf367aff3c071647f3e71ce13189757ece5224 # shrinks to val = TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 1943354996870588357}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000004): 474051645, TokenName(421f978c4ae0a4d161dc60fa8d7cd877511c57cdc806c1b5986deb4da430dfa7): 2488334975, TokenName(59a4c85bb911454672bcebe7310d375adf018772548276da34b975fedb2d0f8b): 4248903206, TokenName(e0df732440159f9ff19b6e9c8e77e1386e4a9aee48382e97fb6994e9e2056562): 741409653}, NativeToken(MintingPolicyHash(ScriptHash(46be1b75a4ce4ef920f10727da674b0204aacc63206d17949be033db))): {TokenName(1eac4f3046bb7931ae0b0c081a82fb1b8da200e975b82a168d17aff0fd83fc1f): 2085167816, TokenName(2b011d497091730c3b2d071a6eedafd5718bdb5bfb68f38020077ccba58eb0a8): 2371561513, TokenName(92907875642cc284c5ab15539232419c66924efc6d771e0a670dccaf18e3c781): 642398574, TokenName(a207c7f26b68b64fdd3e689635e804ebb83a81c8a702662a2263d55ee74935dd): 2426539045, TokenName(c9d904185fee6bfb95adb0c7a2830ecb11686817ecec7ec73d0c2dfb20a67eba): 2871074309}, NativeToken(MintingPolicyHash(ScriptHash(9815c5ed4fe164bd67cef3a2c3c1e205631eff1e1129a113a66b861a))): {TokenName(108397c797da52b1527f985bc4b2bfab81b8ac0d642dc85c359db03eaf918d9d): 298995140, TokenName(4fdf093700645828bf414ae34c5965832eaa415f24ff2ae94b960db3c21e9450): 397599212, TokenName(51723e9be351097934bcba1454bbe5fb56e93eb8c6a9974ee8534a04d319735c): 3375646872, TokenName(bb9c8cd43399152337b43c68923555a011ebf13772ad5db39e0f58bfa43bd118): 3516553824, TokenName(e074c7540f1cbf4424684374d6ff2eca7373201c384bffc055abe5ed95b3c340): 4233369511}, NativeToken(MintingPolicyHash(ScriptHash(bcc202ae2e4a8a7c8bac99cfdc7a95fe0cecb89abd6c58f8b5fa19fc))): {TokenName(36df927af2c2e9a241ca88303c3a3a8230f442229c263dc7a7a578d4a92a7902): 136786585, TokenName(3f464eeb4a907e94c68a5fd7c8ecfb94aa8aac39efb4717d7b473c88e31ecbad): 3425350380, TokenName(51b3a012475fe96a0eb494fd25b3956b6b6a6b22820dbeeae2812ef5b9e70ad5): 827307920, TokenName(5ab8ed6811129a7596182c90a0a655ce4ebc484dc46f6efc73412c6198672274): 901225683, TokenName(91433841d02999c7f0213617f82bb3876884bce04c8c784defc3634f0cfa6626): 3044386477}, NativeToken(MintingPolicyHash(ScriptHash(f825436d4f6be16c7323cf984f4aa271e77c4bc1fa677e8c3bcce61b))): {TokenName(311bed49fd59f549915fbd7d5dc084bcc18320157e680b76fc154d0bc4a548c6): 2380644840, TokenName(664ca0142210f54f7a7a717e0ee1024eed3f3e79831b52214206349811a4ffbb): 3567838447, TokenName(925bd975df9f7e47d6baa7dbb82dcc5a4c0be3e351334103503a51fbc69914f2): 974361472, TokenName(ab83002f92dad8b86c304e7f5b4ca546a82271c68fc8598ff913d3c7121aecc4): 2435923687, TokenName(c8c34606302581726ffef12ff4f51381796834d38292428ac7d55ecca2385ae1): 2493215310}}), datum: DatumHash(DatumHash(16ccc094024c712b49cf1c19730d8822604721ffc09dab0423f3cfe539c7a4f8)), reference_script: Some(ScriptHash(f8eaa89d7fb3767c920fc463cabc2be5409cd34f3d9ddea38e022da1)) } +cc 23e9ea394bb0feb9f097fcbe50e1c617ab693e281348967adecf030c32bf9d96 # shrinks to val = TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 11307790846066098720}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(00000000000000000000000000000164922cdcd23b8e8ba4570a33f8d41c321b): 1572532578, TokenName(98dcc17b144163371f67593dbd99919f8af1e4eeea262ee8ca22ffd48312a811): 4051480068, TokenName(b34394f9dbe0ef4c71502776a2cd2757937967d0a43fd687d0646ee0df046fbb): 1336019099}, NativeToken(MintingPolicyHash(ScriptHash(256b9ee71ab62a5faf06f4062012cdc740ef1395d0c433dcd7be01c7))): {TokenName(2a169c8050297a1c30551ec2772ef8d1e8b9d771d9523dceff7d7ade4e9b7012): 1796313873, TokenName(50de778b5c82dc5113d84c97bac82c2348e6e4a4a9510a91b979ef075e116ddd): 722992515, TokenName(a030f7592af2fbe6992a90ed642de3cb8c4ef0697ef3c2720360c2db66e851ea): 3391589749, TokenName(b89611b5951937e1d3de3bd9d012b6e193a5204cd2decd314703d737c5bd1573): 3746419003, TokenName(feef6c66a1a5ad207418108dfe9fc19136d977de6710bf4e154ca6970a5ffa10): 1788244832}, NativeToken(MintingPolicyHash(ScriptHash(779d9fe9e83cbb2909567f530a2ac9d3a2d6499d15b016121f0988c8))): {TokenName(1c65160f41a60a9039bc1c690e462a73a09953c926c0ae96a99e7934ec16eefb): 4206602492, TokenName(34760a4de83d356878951d56466b9ad69515a32c593ed87e79786254f8008de0): 3681013152, TokenName(473fa050cb5d36e2387958289294b250984e96b4775ab135ea7da523099eeaf0): 2635040445, TokenName(6e58bb62b49bedc75e29aaa03f0d0bbd7ff93bef7ffe65fc1f5d27532f68b0dd): 2245578388, TokenName(d218432f5a8c7d2a3dd12346bfa490e7fbe436c85445b2f01346a8d5542e731e): 963588298}, NativeToken(MintingPolicyHash(ScriptHash(aceaf9912f63b6ca6eaea4b4826189d2de6cc8bea808b3bb6d291527))): {TokenName(1fd79d7b69811162e4aa0986cb5327419b9470b2b5f72ef694e53d964838e458): 2111302467, TokenName(3e953c061fa00a1227226c11eee35f64f28b7dcd27c3737c8384984d47dd5fe6): 971503309, TokenName(54ddf4c6b1ef026116fc31c4d7a0566be4c2343997148e31031c316b8d10f153): 1492445650, TokenName(aa81e77e5415f608e37df77666506b8003a832b5b315ebcdf467f4ebd0afae67): 4271805958, TokenName(f84deba5e443ab5ba20e79c104061b7ed957b06a74025e901552c34f621ec60b): 770820613}, NativeToken(MintingPolicyHash(ScriptHash(d8df147ed8b9d38c064f9861203205505399a9111e96fcc9e7050a26))): {TokenName(6d39b06ee9fb5ac4d5069d2931c481396b5a1a1ac97d4e35148fc9b34252517e): 2549362015, TokenName(70858ce665aa73bceaa8c3f0880015f3d8f420b09164918aef4c6fd8e29bb462): 1916783923, TokenName(7413c1696410281fad993156d7df79ae2deb14e4aa61a4debf461fb1b5efad06): 2856706283, TokenName(7560669a950f1b8a24cf8dbd7ec0b9631f48a16c062740df3be00f1f12e578ac): 3487241612, TokenName(dcd392c34baf0b7e97cd35b4075162cb2530b8ff9fedcdf26cc47e4680e7314d): 253797432}}), datum_hash: Some(DatumHash(3156abae7adb8f67ea12ac36bf969dafe6ac5846329ff2163e35c65f6cd31ef4)) } +cc 543e956766923f668ce342e8ce383f28dd9e72231b64d13e4ceb7a71bb98a0d3 # shrinks to val = Value({Ada: {TokenName(): 14424837469395343527}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000002): 0, TokenName(0000000000010967b27594d209d7070e5a0249e42a094d95f948ee043439c25c): 1788463841, TokenName(30888ee8d51a9ed949b594f7a1f1a40e78da76bc7444504f1d911647ce8f9e63): 650020242}, NativeToken(MintingPolicyHash(ScriptHash(0ea196d3b8a562932397da7fb2c94f8082bd9e64283bab714e094ebd))): {TokenName(4d20c3abfb8f4b1bfdb8d242359a0d7957a19922db440ebad25d3c12a87e6e8f): 3304779373, TokenName(5a20e1e8dd1d4a7cf812f102cbb0de08581584861d8f629b67deb9de7f216026): 1842503113, TokenName(92d26c1737334d7e4fde203bf7c98b5b64834dd678e1150e5be0369b4e728e4d): 3651598782, TokenName(c29ce34659540f2c15969e476e3aea9bf24796afde8a7c0cc5005a029eedfffe): 1907117525, TokenName(e73f3f478aedb38b2f78527e3d56e1b1693f15e0e062f6e873b38bffaf0da284): 273641939}, NativeToken(MintingPolicyHash(ScriptHash(394528ab0076d0245ede5d7aa6ccf8b89e32a27b8055e2e54f6aacb2))): {TokenName(0ea975b7110055681aed9d579fb115ba5c716c6f2dcebf69320511e41b8ffc64): 1656666742, TokenName(68ceb85082724dd89fe00b2148ae1982d767eacbf6c468466030d7da3da5136d): 2137852647, TokenName(a44b0079b391a5c725e8972a9ca3e05e3631f9a2d7f754fe9c5e52e8ac0dbc2e): 4183214932, TokenName(ad8bad35c15d89c074b1aa70f6bc62ac10b489710e1dfe1a3df52cc503f3b7ff): 361263401, TokenName(f9ba51f47615c86af84e4a5c9e798244dbe28230498a2b9ef4b7a55630ae004f): 2929477375}, NativeToken(MintingPolicyHash(ScriptHash(97f25ec089dceedb7e4e47eba212a79d153e74e24446f48359a01c13))): {TokenName(66a14a5165c74437340c0161f9cbd3dc10b7d89992e1c96cbd0d0f0254b04545): 1726978085, TokenName(6c31dd856fafdabdc5250bc1d8f6c44615cd0429213748caa3ef6b93df3357fb): 192819734, TokenName(b34d6468a5043a1e1fe3691e1f345f25968c87d39b5cd6142bf526d9127c1309): 3572494951, TokenName(d7f1ae6f89bdb1c17c498e75cb3158c40e288171783c9cb032775edabe8a1bc7): 3350017561, TokenName(ec5ed545b36adaf6c1df0fa6acbefda2ad62221ba9cc38e37e3425a6415c0311): 2179161864}, NativeToken(MintingPolicyHash(ScriptHash(ff386873341b1bcaae8ab05ad80533ab4c4c4b6b884db97f59f968c3))): {TokenName(369f2ba9131db399e3b61838992581f68a4dbd4fb3aa06aa0e15041079447d4f): 1900606450, TokenName(6a76151ce50cf711d63c29c51b8f307b904bd1e412b90963f37ef83716de39dc): 4233782127, TokenName(8ee60f629af8e9fdb7f88009f5019bd14cfaf6230123d41a594a314c6cf0d91e): 3597316093, TokenName(cc4ef63ad384995a2416781166808ca8d51cdeb1ace960da440769edc7d29e12): 2153679071, TokenName(f503b52b34c5b9e621d3360038f55dc5242c1626821606aa11d19625875c3e21): 2091888762}}) +cc 52590d67b91538cc3fcd06d3e709aca62126f18b7363189db12383c4362fead2 # shrinks to val = TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(00000000000000000000000000000407edf8adb91cf89541e545e72496f07a20): 374039361, TokenName(1d0b453824ce557bf6fca45a77965a26f495bc7db5e70aa4bf403fe9c5e16303): 3558846317, TokenName(86bacc62b41afdea27a3ad67e2347e10655ce679e764a922394381ac19943919): 828865406, TokenName(a350897df7bac32ce8796e269191595ec98863b02b3537317d75681e84a8e429): 1731759626}, NativeToken(MintingPolicyHash(ScriptHash(110676327075ab343912349bb85ccb77019b8ae5b396e4cd416a3c0d))): {TokenName(32bc97530e7a592b2f8630e2a480118421275e58c196b5c3aa2889dfaef39e54): 4100972697, TokenName(49a899b2e5173fcf358ecf74bd9610b117d6bb75eaa6a002b431faa2c734665c): 1009551356, TokenName(91221cf10db922a1a209f75dda756b2e7df8a16318000456e4cb7c277bcf8f14): 2148844087, TokenName(cceab4a5173762e2c01973e1f5f1aec24418692a4797e0d01734877231b9258c): 1591908534, TokenName(e90f5d97fa42a95d2f7f69376fa00340245cd698a90cf200bfbc98f3e2dfc3fc): 1860292516}, NativeToken(MintingPolicyHash(ScriptHash(4bdcd1523ed412e4ab67035eb368ad1b759062c7a410ba1d209fdec8))): {TokenName(188fde12d24aaf8a7dc15aae14d3fffa150b888cbf14c8e182b21c092fcc4d59): 1244087303, TokenName(4edd8bfd264c0569408a288f86522ecf82c6515e487e62e3bddc7eb5916db2e8): 537602506, TokenName(55fb644db0c596e92bbc3c217e9a1394c3d007474209e2079baa1b5dca2eea0c): 673098567, TokenName(7652799c4712d9a009f7c5846f35efc8fcea5a45817428d6e4241c9fce120535): 2409979608, TokenName(c2d8d50e8b1319019b0deeeb9fa49c83b8322c23c82fa18b87f0f533706bc856): 1259902524}, NativeToken(MintingPolicyHash(ScriptHash(cc79a057808e4c804cd8304253deb5e21f0f58335d108a22d014d0d0))): {TokenName(5b87217cb1ff8ed33f592726e9be4256cded3f725aad00c2f8bae54de1aaea60): 1662572243, TokenName(624bbc52eca808726e6e76d4631e857472200e724363a77690c783bc9fdcfe17): 1857662724, TokenName(a390b7761fdd484ff1123e88ce732c064fc79eaa7de470b31fb5a6c3be75f12f): 630637122, TokenName(e295f370af39b67a23986955a776696000bd8e4e8604aa8a5530f238e82cc482): 3765641512, TokenName(ffcd7aa906d79906871384ac2b7b7147d0812417f30511793a4b88aa5c40788a): 4156446257}, NativeToken(MintingPolicyHash(ScriptHash(edf779b2d3812f0c4d84c6dd0c4ad7b8dc3438a93bb6081221b92024))): {TokenName(26d2c9596bcb2a6c2d75ea90a3049bb569d247286526a9b8251a2a6c011c5d73): 3986757752, TokenName(273a66461623a3e686eda206bcbba9df540c2cad7b4a4bd5bd7bbda79d4e9787): 422699215, TokenName(9ddab29f7066cc2261ab86de5a5dd75be3dd6fd25314f2232f2576bdd5bafa2d): 2898291720, TokenName(f7ff19017f0773b48a8ed759706a2dcb81c0a92f643a9e42c3ec6ead8271408e): 1872832045, TokenName(f89c670ba8b564019eb56d5625db89092f30d65c52b69d86b59235b6f84f6c24): 1227840929}}), datum_hash: Some(DatumHash(2b30dddbf7e4d84702f001d4cb2e44f1fdd265d349b62dd40db52545de220a29)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(3608caa8c9a441bdeb618bbc888410c67429df878a186df9c8d4667577437171), index: 2505034753 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(93ffdf43517f1d5fc59790532451ac5c5df8e740b939d3ada063ccc6))), staking_credential: Some(Hash(Script(ValidatorHash(ScriptHash(3e7260a6c88929d0a414fa09ddce0a82a85dd6250947b98d4fa4f16c))))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0a230b516f31a9b7e773c59b1df65b53d6f28fe040ee4f4ebff14c90))): {TokenName(3d167921ef314f97fd811237208dea5796376e54d2fca024f5931f4cba4beb70): 1706344604, TokenName(93d5d7d5137a2188f63b632b1324426bcc18783b229b90f40ae6e57a9c872d25): 3878789206, TokenName(a16898c99e4d0d3355b7929794c485b59c33c4167c2e700a70fa54e03c6bb381): 1316155636, TokenName(d3f5d06afa3a7a686636fbda3a995c4695ce993674dd9b91f2e8814edf8ee8d5): 98210038, TokenName(e44c49b9dcbe4061398269076cf0577bd1060bc6a5c41d9961e21c3c421fb536): 110055982}, NativeToken(MintingPolicyHash(ScriptHash(769b33031842dddae11463eb167e1cbd4b97a7cf6d9306d298d3af27))): {TokenName(43a6ce056b96ffab54133ef9a5ae732d40ecf89e56eb64137f326604634bdd84): 1169283178, TokenName(4b2b68721b75f00c82af508cc844d778718153f0bfa2f38d04897dd3d684109f): 2296085414, TokenName(d0d45e806140bd49ed236ebba7b5836e1dceb49bd7bfd87c66d0fa2e65cc7059): 4242343236, TokenName(d2bb9bbb0726ad1f41ce1d1431e5dcbebf033938a53ed147c81df0a96d75386c): 1548897659, TokenName(ff382d5bdef55129479c3e9a1829bfb783a426bc4cbb0c7d2c860707b3ebdbc8): 816548483}, NativeToken(MintingPolicyHash(ScriptHash(803dc93b340c00d17d3d734f37d15364e305edb314f1bd77e427229c))): {TokenName(80434afd415c5dcc31b26d9b33adc917fd05fc07bd4bac40b8e433cc917e14b8): 4036724512, TokenName(862c26cf7d50ec6b3e2cbfacef5f7003bcb1bc67d3b9667c879634967577c913): 3483301905, TokenName(bc928483ab6ddd4254a8dc0a35743ca403535a2de7b2f5b7db96b91d0f5cf36b): 2789696563, TokenName(c2365d912588993a20a7b7ad04ab12447110c0029871c2f8a9879d0052c1fce2): 3274018622, TokenName(caf7975d5fa73649574fc3dd143ecddac576f008599aa80c3c73cd0da38a4498): 495832125}, NativeToken(MintingPolicyHash(ScriptHash(892d1a24e3527b900968d75baefee5b234d39e26bd798f2987b4b718))): {TokenName(03b45d84ed114acb7f74db5d0b3b683631fe25ae954f96cba5d55cfed2d5eba5): 1637132504, TokenName(4e271d6bd9e3690da6a38f9952ef6111abc0f9cea1a9327f1c3af748abc6f53a): 2401555099, TokenName(a5537dfb34e7f25509c97d600fce489cecbf57d22e72f35f6a3fdf726121e7f3): 3356064449, TokenName(af969adba96fa98725c9c91b709348d18fd9aac47948c8da7293fa9ac2e92396): 4281688255, TokenName(ec94e85bdc9d175489a6cff2285a1f24d8fc378bca3b07cccf0baa7f274e320d): 4256109274}, NativeToken(MintingPolicyHash(ScriptHash(bcd2c9ad98f80a84ab431a5a9c22d40650a8aa2a03e4bdd2c1cd20bf))): {TokenName(0b082058d082a6bd98f66b8411ad9fea78518d9e03e36d28f8aa27dedbfdee70): 78234265, TokenName(0eeae96e6388083152ccec03087524cfcea79e6a875b87af2ccad1e687cd8e27): 216657798, TokenName(778c0c8ce081eb594c3c9ce1db4c605d42445e5ec43885609e4e18010626876f): 3507391797, TokenName(be767ff84f4639851a91f78a2ac29764e03c37921840e10a7cee90e24ee2a816): 701477366, TokenName(dc5c0fc93198fb3feba93c0ba69c0332aab4fd85a1d350febeaab7002a61f3af): 1752261894}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(d1b645658455c3134237115a3ab9400a4a0b1c710bc123bd554d01382c61b12e), index: 3115642705 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(080939e906e3622f3b6f617b0172a9729df1ba466aca07c9d5f210cf))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(77b8331a27e268833e2b7af865d07823696edea7ff672bd2b2bfa8bc)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(058ac06a37eb7510ad1cb9bcbae06d95a7ca57ce31b994cfb7ba0e28))): {TokenName(0982a4e2b9a6e499319e22d3a0fa20813f0c3994d8cf9fab1dfc79ff80612860): 436208616, TokenName(1c5db4a3484d72cadad51957c766273aafc050f970e4b531c2d888406768b90f): 2299825712, TokenName(33d5aac8a293c1791f7df32aa4b2fe1361f034b7d277f4836a7ad4590af5f805): 2609244847, TokenName(9a3f3005afd4dc7580ac8021309ff09846c80c48e9b6117e4bc5a98c0d9dc5ab): 1331037799, TokenName(cf77241468aa2453665300d280b2c94586c75546ab205c634c42b0234d852fbc): 2916744388}, NativeToken(MintingPolicyHash(ScriptHash(3fb8d00144adb2d2f63f61d4012b172c854cb675b43899a9a342f986))): {TokenName(41daa9c61e4d9de30265b4df35f0ecac7fea5b5664ef44649c1e3245132f93f9): 1119356175, TokenName(6fd515c51e30a3a6dae3d4e563a8e14d81208906c93ece49da73abe0559392e9): 3894143546, TokenName(83c0dcc9640b18c255272c421366d651f360c471f340426293132dbabfae5bf2): 1619325732, TokenName(9680687326d471f9335c494cb25eb51c0d2b8dfa143732e0b7cd8c8ecf7e78cf): 2412586278, TokenName(b6ee08e2981a46b92bfc6c2365978f116a2f1677126a38f31c3861f60d8f515d): 2042428623}, NativeToken(MintingPolicyHash(ScriptHash(66d3e927c9db5ac0983e81b47d3a61215e0210095179f739ff39e59d))): {TokenName(118dcbe5303078a367a24ec358e672b0132c3be07e608242f06ce9e0b9cb7fd2): 2650236921, TokenName(320db7f8a3e729bda48d3c044c2006fe59bc1fdee3eb55d5092059e94e0fb2be): 1054482504, TokenName(470f191908a1b3bc0b28a94176a99e2c6c8d2cb155ba9c79b48f1925d1915dad): 365539338, TokenName(b78b4782520720d8e19139ae80269bdb181bdb997567221d102a2aaa37c5e66c): 376692965, TokenName(f392a44b3bbe452ded1ff4f8e3abaa82c6d6a57fcfa89f9a5a22d504a4bbd6af): 2377338980}, NativeToken(MintingPolicyHash(ScriptHash(6c71a1a7c5c43fb2cbcb2e5c1d3fabc97da44d2432bcb2dbc998b6ae))): {TokenName(2f415a59dca91e067ee0e1063d78baa1737856e6e0a6a4db89fa35169efb0ab6): 1444969153, TokenName(bf2ba9c840adfc871b11366de3b98c47117a630bb9e9450f703b3774156e6ca6): 789595036, TokenName(c5917f94f3d44cce3ca2f57b9d96a5a479ee1e303aba0a8cdbe57d5b7b3ea5db): 3567555179, TokenName(dce3232c49a4d3eb10fa3d5805c2caab98d1edbfa01e050c1b4bb6a8baca6136): 636556504, TokenName(e3cb029eb81c9ed25781c011bcd2067a592fbffc5aa286f6e4869f493e61bbb0): 2229180782}, NativeToken(MintingPolicyHash(ScriptHash(8f6fa4dc5f3b3435b5dd5e46aba6a1332dda83d58bc4041e21d159ed))): {TokenName(2f8e26285f838f215da993196558056a72b38c14bc83a5c436452372beedde3b): 2084712920, TokenName(3545998c584076d85b9d3e04aa7dfe4ddee44cae8a9a496e0892d2fa1711074c): 1583163728, TokenName(3a3bbaee789440cc16880f11711c1cdd1840cb9930e4b4834a83dfc7099ca410): 875965494, TokenName(8802f5a073f2a567a9fcc558a5a10deb3ea61c853e6901fc9e0fb591144d214e): 2198651115, TokenName(9558b1aca92f7b6f4645bdba1b84e258f545d4f18b4bb1e34bfb19355ed266b3): 1818984028}}), datum_hash: Some(DatumHash(30e7bc4cecc08267735aa03b6503e91c33ae4218e5bfcd7c1db26dfb426e01c4)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(b788a2ba61e9680498536f8b28daf3ad323a47ed6044b636041e2272715ab17f), index: 2534781838 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(4b8950e75906d624ab2b1bd938a7730033fa710b80575d3cca9216a1))), staking_credential: None }, value: Value({Ada: {TokenName(): 710163555261585332}, NativeToken(MintingPolicyHash(ScriptHash(31f30fc21616a16366ef9aa79038b498c89bfddca46cd4b9898f3ba3))): {TokenName(336c9708249e632b51249a465da394eb4c7755eaa5345d2cb2e18b99a9883d29): 2736465276, TokenName(66de15d9ac8f220385059884c847f1ebe36b71fbcf026d8988c54c9b33ee8164): 1033802914, TokenName(a12988707cd40b76c73e20b1fccbdcd441a60a8b7101fa269780687ef40b3690): 4098961484, TokenName(c16a762291b6ea2ed16cd879edd2351fcb938d8e07e4d347e1845501a34d708a): 1942554846, TokenName(d926a03adcfabde2dc39b451c540d59f4cc01ab04a62cc39e6ea85cf8063b2bf): 2882376297}, NativeToken(MintingPolicyHash(ScriptHash(513997501d96c4e3d87e0d4c5484c73acfeaca8b22116dcfffba8e5b))): {TokenName(234413823848dd5724e87c58870c9916f83bf835cc83a65ae13d280b6b8cdc0e): 3912994292, TokenName(31a73843eaf00472ff4cabdf736351ba096c628c11903646a8fe770fe8d7791a): 1527714607, TokenName(a734cb2591a9751a69e3913d21ebc51449065bf735468c623593654b962f5b02): 2431254021, TokenName(e6af621e3940f1dc0b6005eeae3a410f6876c539aed2fed7a7602ae1da80f0b8): 1458257302, TokenName(f21ca9056cdd1863de155e2cd3facdbfd5372655d0b82710852ef4d51ec1947b): 3043983130}, NativeToken(MintingPolicyHash(ScriptHash(c6aeacfc700f1802b15c94de96facedde6c384eacfc9c3bc33d710e6))): {TokenName(0150f42a12d4ac7ca8193c8286ed0d72c26cd2808dd724973511ae8b9ff27e3f): 3680159812, TokenName(4998b6923dc0350f8f64963bc19d0664b29d448430a67fc42d40e162b35f61c9): 3257935214, TokenName(868b7622c4b934723dcad517c217e2581c6587025fd8948ffa57ef933297a4cb): 3842022460, TokenName(bc776864c4181d25a63bbec854732922a93d88c981c1963e6b1716c3f17792a4): 1580999213, TokenName(ed32637548c1b6dccbcb94f6bf7562221301500e9c028379a5dac8280afc2452): 1635662888}, NativeToken(MintingPolicyHash(ScriptHash(cb2df132bcbba5fe4ef4c37a58faeba72408095b6e5554376441c799))): {TokenName(6c81a116a383a027d608a6a1cce43177b48ab9be9c97568b52126351901a0e58): 980604308, TokenName(776f6232e0b982d48f7ca90a2d8cde32609fe02c38a06146a6f3874d2119d891): 2470546106, TokenName(780870ed9c222cd5897c26f2126b7ae90af045a881a82ab84ca55cabb1aecb1d): 3928169243, TokenName(d7f334bca02f48525e60784dd0d69945319cae5df431e583434cf6cc4e9c647b): 1087682919, TokenName(f6b37b15d15002ce4d6d810a10fd7a9dc213c78b6392639a3f3ca7f5e13e7d2d): 3319137902}, NativeToken(MintingPolicyHash(ScriptHash(fa9ab505768e962dfda560fd76233795b5e68ff6d7bf3230ff1dc237))): {TokenName(5f02262215086aaaafdeef624a81b6fc0b9d72dc839d30369126036d963b047a): 1297264053, TokenName(8e25287a0ab0575eb64dedfeb4b7e94d91bc193486ea1eafbe5152ace98e8eb7): 2436422543, TokenName(9585a430900c1155782abc26ac10a1d4e8da9b3cc12c3d04eb0987e7f42a62ad): 24027131, TokenName(a8a3dd1f763b8ceefe4f828b6acb69833127cd49f1945c25e907999aa4d5f5f0): 4078987097, TokenName(e9000da8709aa255c9119a1b913a04d6fc90d149936eb938988abe3bba6dbaa3): 1463922281}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(4a58917cb81a66bd673b31f0725985620676f7342dc40c57621f5dd5ddef0cdb), index: 2237120378 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(dc6adc7152a569a1e6dfc6ea8f7de5663acb00b9a916ee26773fde5e)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(07f3ada2f3cbaed53e74da54502d785beece52f456887289c36b01c5)))) }, value: Value({Ada: {TokenName(): 2187420690785327395}, NativeToken(MintingPolicyHash(ScriptHash(0f1f0bfe953adca264f10d0f36b98bc7c0e3549da5f3355b2ebb1f90))): {TokenName(2f5c5e1da40a7c4f5911f3b87fe5b534b5e9442caa4750362e26d3a940cd7ad9): 1749869049, TokenName(4e34cff6cc2c1e294990ee06385aa2d87feef581c4c0d18b5441d958af529857): 3386749994, TokenName(6dfa637c9edf7f237a7531d3eb097083c95655aa2bc74136dc863669f1dc7f8e): 3424902970, TokenName(96ea480d56abf56c4dda47713b1c90d1225b4d00cecc104e4dd8db51a5121699): 120786680, TokenName(eeaaffcc1c1113116cffd9c89b1c839cdd6dadb83660046b1f58bc5aeae42c13): 1935378831}, NativeToken(MintingPolicyHash(ScriptHash(416961201c75acdf68f31c44af7b0554b5472a90f512282e09d8d952))): {TokenName(43c11832e5f18a7844b82d95b5b050df3d38b41fd74a5f0f1947e479d1dbfd5e): 2308196071, TokenName(5a790a21d4b34e56a031c7bf91dd3347dd9e8f0e7142c21385bcf176617ba1e0): 2762092532, TokenName(5e1428a96f901496627a35371821057f6b1197bacc6968500788f1ca667f7de5): 1786463607, TokenName(9b8297349851f9282f4fcd613be37d77188d19a2c8e9573df52910030761dc67): 2644675782, TokenName(f4c7bd912e86616df00638c4e8bec5da29a9e30c7d2beec1b93fe2470cc536a6): 4029499366}, NativeToken(MintingPolicyHash(ScriptHash(42a4921232c02536a092966b7e1f7e844cfb8d2d6d6d109c74efb801))): {TokenName(084b6abede319fe531033d514a51211dd13f3b1fd2bd2c1ac463a314979babe4): 1031801373, TokenName(3caad7cc2a7ae5831de551a8b5df1ef5375a4505c0563c3e81fa69d11ea08ba1): 1340469765, TokenName(7cd76fbb5e86aff6f3bca788b308b7fcbbda7e6b6975f6dce8857c4f0ae574a2): 813064888, TokenName(c195267200a0ddd3d157df366b68a38d8bbce29e26a420d2a3731bf8115c5748): 665272959, TokenName(dc0e6c374d47a156f53b4be95d50935db6912557d7bdd05037eae16581f8bbea): 1921030566}, NativeToken(MintingPolicyHash(ScriptHash(8b7aebc7fe45bb6fb781710a83d38187da62ade2ad3f53ee909ffff6))): {TokenName(2d84c91747ddb380cdafd7eebe9d46d221dc7c94d2afb620a5a66bf9d575fea4): 49037436, TokenName(6fa872799f3408ff0d4d42cd62c9ea6554a09521517bcf33f0b8be988f2a3253): 3271104944, TokenName(97adba75d68e15a7407644beeaedcd8f63b5884c962e8b0eb34a819ce83ae154): 233593306, TokenName(bbe31681e67fe34142121e601f5e2b9644bf8f728a6f6a7026290f2dd82952db): 1750148926, TokenName(cbae3a183bc5ae195ecc652ddcd3b188f284bbdec219c031be824beb656d40fc): 3238415812}, NativeToken(MintingPolicyHash(ScriptHash(c9e14350262805ec43aff9e7d55b32ca41846b0ce0ab2300c5c675ba))): {TokenName(5c9b3e8e3e2b1a4ea0525101e9767947129ef90fbddc6a05622d05badf2738fb): 2427201629, TokenName(739c8bc0c52f2bfbda95110b524168863218f3835692bcac78c11400dbb93214): 3091824608, TokenName(bc573f5d85e3e0c1feaa6d806361d1ec7c45075c9c29d6f1523a1b265c070a80): 2339288559, TokenName(f094e25d97a677fb29e5da08a8c406a26bb84a82f6623e159fa08f6ff20cd5e0): 3772179716, TokenName(fcde86156ebb0a156c28b144aecc6a78222550a751ac7ae7e0539496db4ea770): 2816272552}}), datum_hash: None } }], outputs: [TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(14ce7cefdb3ffd53fb230b760dbce0ebe19bb48097de17dc3369e402))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(e64a7a19755505e403bf9ba623f3004d156daded23758e5e6597df76)))) }, value: Value({Ada: {TokenName(): 3204140381163145128}, NativeToken(MintingPolicyHash(ScriptHash(be06e679e27b762534f97a4a615fa6af8881833e159ae0cdc701d3aa))): {TokenName(5577d1cf8ce79d631922e020751334ae728616cde48563583e167916b8fe6ba6): 80422922, TokenName(a8e7f8c425a21fdaf9762b631438719d492020586337853be7f14636b0715d85): 1994695392, TokenName(b25ac4f1492b0642dfd5cacf0c424e54210e5a7f50307c7e56641b563d5b8e65): 4132953472, TokenName(c79c9bb99b410689217b7b03cb6c0c852c6532d494a417977a850cec1a5de666): 2925597833, TokenName(f7832185435abd19f1a39742376c292f4011ce0f90ea5edcc6cf52fc3a70d859): 1708481710}, NativeToken(MintingPolicyHash(ScriptHash(c1aeacdb9717886401d576c5db4ed7e39934a348d0fd34c9505774da))): {TokenName(47ea055512efb5a13c235e8eab36996f4cee8c26eb451162f721a2a82b161843): 3072137652, TokenName(5d162452b4d41ad2847d8140fdb3bbac45bbeddbad03cca2ef5b5accd75dd90c): 3139757021, TokenName(ae90d22adf87f70dc7f4f2f7e5a1c390355a0051886965358b9a5ebd0f732f80): 3717552077, TokenName(bf00a996eb8799484b37a699aaa4f17eaee0a6c31b42c4c72aae2bc6e39260e9): 781313480, TokenName(cf4ec8aa9e5374b7f69dbecde5c1086fa74200bc62672daf62022d33990209a3): 3278215950}, NativeToken(MintingPolicyHash(ScriptHash(c3b726543b9a3c64b9f1424f92cae3347b2b619063eb445f526352dd))): {TokenName(196942fc8fb02984afd653fbc389b5099e739915ebdc45ad5e77367dd425c550): 1852062128, TokenName(38d4203a5324de3b8c320b42e577a59563f469f510a92d953fa81e58abd3cc5d): 2566486165, TokenName(39e389a962dcd308d67cde5a32cea16385980336ca851be16c44fdf0b7e928a7): 413787175, TokenName(4bcb5b53b8a530bcd77776e97fe622b5f78db97c90ab801e4002ba237213a923): 1445582470, TokenName(fbf9db6e9878215925c303119aef35221db420ac43835ba17c539f9c538ac870): 2854834655}, NativeToken(MintingPolicyHash(ScriptHash(c8f52c2542aeb46959372de09adeaa83910059fdf6aa79791787e4be))): {TokenName(1362e2cb1b42cf5f247144df06dc7935c60fa91c451bcce69c512b981846cb23): 1234526972, TokenName(2fca898a35a43a85a9c9378c6c7a33e6e097b2eaedea11004f3c777a10d2ac62): 904175189, TokenName(7f1f9be4d46fd601b8a051ce503f2c19f5ce1ee0ed04eb1c724cbc399572a428): 3707513607, TokenName(877ad2da29efd6086b62ca5487c50147940cf9b44b5c35d7f505b39c0c8e48c8): 4102078761, TokenName(95d3031a95dfc9dba9027f6f9fcd6d8d2dad16a4b2a4d66702a123d38586c288): 254174447}, NativeToken(MintingPolicyHash(ScriptHash(cff14a45d976e85a1a8383ec5c945aa01ac47c8bbb22938539fcc306))): {TokenName(152ac3c0b6f871fcb493b84b9c200de7a0e4cbbf63c9c2ff471ff1b8d2dce339): 2115577256, TokenName(35dd497aec2fd036b1a94622d7d991ac6cffd492521424d9746bb985c65ebba1): 245872665, TokenName(6c32d1dada638009f2cc44102c43f9a02011e9ed5660692f3bd0908908d0d3d4): 2101072084, TokenName(89952bde248e770a36c839ed08bbe60011d502778037ddf12ebf662ebd896284): 2334605192, TokenName(9a3e9cc8a4c5f2931d23f0bb7ff2157912f85c47de221a1301288ec79450b84a): 892292307}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(1bd6451ac3423f9199ba899886fa2858b37127935c66173140b38b4b)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2127fa9639ee45983358cb96beda3695bf98d62937793363d6c87b7b))): {TokenName(0440bc1fceafed5cb7fe218fda89311fc5f776b22886ba601758ffa155cdecd7): 2977875133, TokenName(864d6359fb3e30a135fafaa3a9f382ce4ae3353daf0d6fb8eef2aff9b06fcf93): 1987814508, TokenName(9df46bb33bc4e64dc49d68f967bcb7cdc24049fc543eaecd5f6c72d72ece35e9): 698488157, TokenName(c6b83b83d7da52833579eb92b302a92d4bf9f797fc7c73ce0c8451609f800ffe): 776047550, TokenName(feb81145f36a5db83955f1a0d9cd948ba194eeff2eb788dbe35db6b563db65ba): 2185584919}, NativeToken(MintingPolicyHash(ScriptHash(5d7f0f90bfc04135763bd67cc5d095aa485cc6ba5e28c1536c7f1f23))): {TokenName(4164556b03af8ce62b77dff178fabf79c5872d307eb7ae3b21e5b8318c47ccc4): 2436169930, TokenName(822fda798db60d45f9b1e8a2f1883a26396b1a3f789478f3cc874b05e092cefc): 1815487654, TokenName(8743900397f1434ff96f72f2c0149647707fa7a9de4ae1e97a21d4be8bc56efe): 405332397, TokenName(aefa2f3b87dafe90952ba15769b170196286124ca5a545e2d02713cf61033d3b): 373101445, TokenName(d69e8a200a8f1c3eb3f4d1c2d5df008614c57da2c5e4be42c1370df66b119dbb): 3675765993}, NativeToken(MintingPolicyHash(ScriptHash(73614882564e717e8a410b3f450f4a867cf392e38874e85a3c0cc11b))): {TokenName(15f27bf0e9ccd4380f7d04a2b41cb4ea9620ee6cd1832e4287c3c2865504aefe): 2990546610, TokenName(778d5f9f2038e5317303a339632c964485aa01a8f049281cdd395012d895b3e7): 2828286019, TokenName(a480b6b257de7d65544689429bd3685c94e4b3d4f02d4e6c2af8a30c7a9d96a3): 2960566335, TokenName(b5e5ef445306a87c68ad16b13db2cb11a43c9cbead8fa6d273a4db6bf21979ad): 2003513283, TokenName(cb0837dee220176f304d6c27fc2132b47d5051bd7de5135a4a1a668f0f72d1d5): 728382953}, NativeToken(MintingPolicyHash(ScriptHash(ed5ec393f4eb319aca49968d0252c036ffd2756c0a1cd6193bc55c8f))): {TokenName(05ed240a69d035eba26e6ec044f1e8c8ebbe7dc53946c1e653e92aa287c6ec2d): 855436172, TokenName(7d9b08efebc14a5b6b53b61b7d95ef5ac2ef93f8c011309b60ab82a3a3135b79): 2841148457, TokenName(91723f81c7fa60a343bf75316864e2e96b92b7cbb780d5418a266e3ae4926df1): 1751292367, TokenName(edeb6b562a1db406bb6c5061a8fe33db9788a81603f98358a55ccb7d85ee5407): 1261153895, TokenName(fb066e91e81ee821a9b65147971e9a5e0fdbe232ace09bf2589eb407051dd90c): 1058727688}, NativeToken(MintingPolicyHash(ScriptHash(f0e52737544c0b422de1f403f69af968ee9eed4246a5b14c282d8fb5))): {TokenName(203e46596645d1a7a4141708d351e374a10d9a7e43af147b6ed63600989cf304): 1552260197, TokenName(7859a7e9c2abcc99c35b556204ca58d5b0667d7dca41f52116685f137e4d2992): 3661700872, TokenName(9cd8a5d5c1ea8d06f0d0e668bfdaf9d0314d4e6e0f166a3c9a987989febd2e9c): 3261841714, TokenName(aba4d7563c0c020759bb0d6cc64ab5895aae74940c13e8b43d3709e8f8fe2e52): 168222759, TokenName(f38f7d8a057a07f22878680c79fea54fb49cddb18ace4903e11d2b0eff10c61f): 1154769142}}), datum_hash: Some(DatumHash(f7daced41605156921f79b3f24626dcd73a44e055f1e211413101fc1df5617e9)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a81191d7bb7ac16c9debe0843fc64bc9e25c5bc8cce600025d8628af))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3511d437e44f5356364f24ffe1f8e9a3aa730317cb025d17bbf295fe))): {TokenName(34947371e5e098ec2030200a6b28c2a98720f0a9f3909ddad928f746c2e3b854): 4279030183, TokenName(4f59be7434a1bde2bdfaa5c99a3508f4ed60be02a112bcf7abf242aa85535f68): 2924357960, TokenName(9ac2fb572ee7673e9ec2cec0aae9ce3cd48bdde86662f9d8fefdea63fcb8bfbc): 1959595321, TokenName(c0af18379d7fd92561c7d60bca085bfbc3b5d942977c5b558d7105dcd834fef2): 3426883453, TokenName(f1858ee761571c36310108e946be719819b1827c30ebb1d482efaba8c25d7d75): 1657981309}, NativeToken(MintingPolicyHash(ScriptHash(52970355790060b77a1cc3fd46d7ecbaa2c91f10e5ba540b04ac4033))): {TokenName(0f28b2cd94631e1fc01f160c5fe7a728b689eed4516947e67452bce812dac2d9): 2912791554, TokenName(6c49c40da0821b8eab4a04262b389c1e8264819019e47b55ba10ba5eab12f788): 2004867540, TokenName(9648245b6d266c4484be7428a2ddedf31858af9e87f20eb3b11124afee8beacb): 497951342, TokenName(98fd3d501999a99b13c18a348e985516e71a437f19b6e6a52b435aa41c252655): 2647984422, TokenName(ee1f8ec07346c0c7abc29fe40160b76f43087e533fb65239f80016aee530a804): 2109310571}, NativeToken(MintingPolicyHash(ScriptHash(5936fe5cbf098e413db3d568db0c06665bab351a81058289376ef3fb))): {TokenName(00e4dfee874175678ff80fad99fb214753b3da0e0db7786df2c37253f2b6ae79): 3236125097, TokenName(2f2f522fa03885411cb23fd253f35c6834093afade46738da410fa2395771bce): 4246110326, TokenName(47b94183753e7eb7fd1bd09e28e2f12a8b3243067dbe15c8c8f7347050a27d97): 1554141356, TokenName(add3e8fb43d9d2ab4c7c9715bb86a680bebe22ff74ef3dfb0b293d3506c9ae37): 3188851922, TokenName(ef4cf276a25bc90a45e2c9126749f903d1cbb7f5f29e997eeb9c33c8c25425f6): 2831608162}, NativeToken(MintingPolicyHash(ScriptHash(d0f5da3e947b351534e1f62b7badaccfa9f564bf3becd4d600ec6d96))): {TokenName(29c0b978d88ea88f66ae632307f106121713eac900ff1c47f297e71058428201): 687422574, TokenName(7354bf72a2bc0b8eff89329d09cec4cdfc94db652068ad1ba8cd4ad3c1ecdece): 1889761630, TokenName(9306f02f943900c6a8af5858dda798204d637deb94f01c10b8d04e041c768c95): 1894987416, TokenName(aa3dccbd0029e01e72c9e8e0c074285e687548823c11c8173a940a3d097bf781): 1383955432, TokenName(b5818124ad743b4c585e07e835c353272ec009c322be1f92481ff88ac197035b): 1848236160}, NativeToken(MintingPolicyHash(ScriptHash(ef9c81fb293691f601959f875c274e7d991524c7084b65162ad8cc0e))): {TokenName(2e8d7363b28abb48b2aa1148b1d53baf69ff88d57edb957bd216ebe9dd476143): 3675083634, TokenName(5ee27d43d0a024728484d479467e2ac7da2365740d750fef37ab9474bb3eed86): 3545813450, TokenName(7c7607597ac9b0a863e6fe7d14c28882291f4c36886ddc5947069cd5f997b1b5): 4171611603, TokenName(80a12802a489ffc9c9961e3669ea18baf650369b26cb81727a05348673381859): 3351283778, TokenName(cfab13d81c0262e698530e522a69a979f8f7afad97c4e272743fe120201e3151): 3574590105}}), datum_hash: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(1366944a0dc97d42df4b5ef692da0b50d364b157596854224549310b))), staking_credential: None }, value: Value({Ada: {TokenName(): 13351802756234715509}, NativeToken(MintingPolicyHash(ScriptHash(3333493a6a0157506c83e5cbc9eb143af73e261ebc1da2e7b6ca4658))): {TokenName(04b52fc497106ff6332109b2695f6ca120d322475d948f150a5cdfa27ca4fd74): 3492284099, TokenName(1236a2f81af40e3459ef7519ced218c599fd4b0ea10e5763cc2f75ce3347cbb3): 4047643179, TokenName(1bf54142556d10216306606dd0017a42e32bcb5d8a0de7fa9852b36f6dacb0cd): 1683687412, TokenName(57eb0883f6678dbfbb4cbeea135f459ff288f7318c8e42c36fa62b0bd9c30d47): 4289493069, TokenName(a1f86dea69bfdee6bc21ba3b7c2c09e9fc60c9fdcd8c42365b51cd4540f42019): 2995685947}, NativeToken(MintingPolicyHash(ScriptHash(9ac99cf97e2cde774e506eddd63986fdcd865e0c9de39b1e3c9e5a4c))): {TokenName(37bb89ba393b3e5bb675deb498fc172e4d1648b44b7ef506e63a808fe753772d): 3129145689, TokenName(3c4568114829f9b232f1f9d956170107f29b8b0c5e8019330bfae84cadb7c193): 1156157674, TokenName(cfe957c3c20d32c87b45c9f88aa7d30e92b1dcf7d41b4db1fe2f40525b4ebd25): 1223547497, TokenName(d41ea6e7d657fa623551aacb2f8efafd9afc4dcc37e8081428bdef7691a9611e): 2198119818, TokenName(d5384a89b0e366d4c400de9d0e5b12e2393b8caf118a0c2b459d83e280ca4f59): 805613717}, NativeToken(MintingPolicyHash(ScriptHash(a26a00aa6e9f2117f9138c2a9ff5f76ee2656163b7118db1786ae38c))): {TokenName(4afed342390256dee5d3d9b5c47155873dbe02075749ddbedc599343b2fc34ab): 2929375856, TokenName(50d6046903bce5a7fbff220459139702f1ec2c8a57aeeb4e76b67379b6743efd): 2409147650, TokenName(70d35321ce9dd1b41711ae1b326241da331a35a6ccc464c727922068a67fbd4c): 1766121644, TokenName(808217e1ac34641897a824d1f6769fe55a1ee4fda6a59bd3f1f255edf1448f80): 1248412111, TokenName(a6dd643fbeb6d5a9cc8c318115ef704de77b11fbc6acaa06030937b216096f9c): 582545510}, NativeToken(MintingPolicyHash(ScriptHash(dda30ea82e162802f2c91c65ed47afaab607af9c4a8a5a1219400604))): {TokenName(5b41ac71275861ff2ec5dfa1de2990c19b417511ae4478d9e89ff7b483067172): 3449412633, TokenName(a3da564c457a2435006659f191f8b2c21b767fa8ada7f44fcea28708151aebc4): 3439364834, TokenName(b52601702a31b72c6fa6184f97e1618e6edc802096c30ec7a43273f82e83546e): 1845099946, TokenName(b81594580ed31cca2d5d2983743c2ef3cd467feb798cf9125bde3a1e54c9ffbb): 2233546504, TokenName(de7a95404a66c0064191243f052add40850b9d41b362a9a67209467d6cce1af0): 1194625508}, NativeToken(MintingPolicyHash(ScriptHash(f6af65a78fbbdae33ffa1dc33a7d00fc9d55fc9c31a57b595ac21f73))): {TokenName(199ae885b98c11ce28a6aa0abc2fc4301438ef1e5e2adf9a9dd2c65eae8bc25b): 1672237215, TokenName(28b5c3af3d1956aebeca97354c6c5f1fea5bc4cdb96306cfe42cd8b8a3834e02): 2522397673, TokenName(840c246ee8e65971214b2ce1842a83fdfe9dfccc2f6ebbaee6382afd0d548d7f): 3508342103, TokenName(a7e5d3b09cfa389972fcf38cf5c9b4669bf3d8ac8ebedc8f93188cf8bb102202): 1316451132, TokenName(e11fdedccb9d317851c500be87e44ccd447d335a8587413b372cd27e5c9f7511): 2841616680}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(247ec5924a2e8d049a1ed1a7c030b7b945f77481fb4b4e905017d562)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2450805533), transaction_index: TransactionIndex(3725415279), certificate_index: CertificateIndex(992538979) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3097ab6b9f11ac41b2b62a2b187376bdb749894df054363cf85091fe))): {TokenName(00652e47ade1743699fd5b1653446d5f1a1feba494061001f85f78d66b6461d1): 1911922049, TokenName(4ee8a0136cacff3b1b911ef1ffef30296fc068829bf2baa77467f15c03164e16): 1242398632, TokenName(5b9ad3b1912c0bab37be2e540abcbf3f2ccc0b03ed815db3afbe66d1f646f631): 4054076827, TokenName(cd32139a69d6b6325de16431451cca2b91e574e7c8178d0e09d5fd99031eb492): 4287503836, TokenName(e1c9456c964d607e97926955eaaba6c741212527e1aef265f723a485cac705ca): 1886959299}, NativeToken(MintingPolicyHash(ScriptHash(5ee25ce0cac04974b19bb292e6125bacb4745f01cade2a38f2fcddcd))): {TokenName(40106f4e64081437699085ab258ad8cb7caab53c0bdbf1d3c4d26b626ed1cabf): 1982887309, TokenName(84f985f8d580c7e5fb8ebfcf846596871490e5d7cfbcd7e3ccc2120d305b76ad): 2169968749, TokenName(8dba0028dd4d76f77fda3ab995c10060320015a5d60e783f2a08bc46b6dc0413): 4127905617, TokenName(99c65e7a82bd3d31b90bc08417bbf1dd5d9792ca23665cc19956d7d20e05efd4): 770108781, TokenName(9b0c9da4b82f393883b6a1acaec32469c887a16f9c53cbae086c6ed5cc18d30e): 3974021517}, NativeToken(MintingPolicyHash(ScriptHash(6e24ebf6513091773ebd4294fda9bd6b83e64c2a0353376dec8127d7))): {TokenName(0e695a2befebae2598cc133574f4c82e9f90e9e3aa78a3ecc97bc7e36a18ed71): 3082909143, TokenName(770727d6f3e76fb630db24f10305e3bb455f6c8375f5f6c39002b9bb9cf502d7): 2029396459, TokenName(88010c000289f7dbbe362b895b698f3a0b61cf43a3f01d681c122797e30d7fc4): 525582582, TokenName(88d3306e41a945c166df7a4e76593f614fd48eb034f2cd4ba8355220b223e264): 354710608, TokenName(c9bd4cbe78d3c0a251480c0449029b3dc6de569e9df872fb3829953abba97485): 4143978965}, NativeToken(MintingPolicyHash(ScriptHash(87689a7b197a246ff4933f38181eb1a772a051356fc9f16c21fcf4dd))): {TokenName(99861eecd1fb25e288bbc4eea32469478d11707fabe67998a28f969fafe6145f): 4004005865, TokenName(9a7c48fc20693b162e4f3f2e274567b2ccb4e538f4a88b3fb88d9b5635253e8c): 1034688184, TokenName(cd916da66c003e332443a3c64cd79aa142abea71d8bfe2e2de4993ed41a77f0a): 3233870665, TokenName(f69d57f73c6f35b14fcfeb0d75183db23e64ceae817984509b83537554673aed): 3999837128, TokenName(f844611c343db68f6d9bc7e8d927de6af6837fc6bb1c94d9502a4b8b72537644): 2503352227}, NativeToken(MintingPolicyHash(ScriptHash(d317388e192a34f51df8eec430e2d53aca7d04ad315e0e3074af3fe1))): {TokenName(10666a619d5c83a471e786f9b81c9ed1a7a573334c4667169f01211e1ca0b58b): 314137795, TokenName(11851deaaee3721c83ed53b211e63356dc7afa3f9f1dc9ebfe75e98f9eead160): 3135406278, TokenName(8d2a1bfc081a54fcdf59523de72bee9512b4392c07d61377fb984204e1ad82f8): 1963530350, TokenName(a00d6bbc3b0fe894277ffa8d0e23d9a23d5463e8d8c426a8ff45b29a3528a5b0): 1440594174, TokenName(eb7daf04a6aaf9b17ae0e21436c3c694b2531f31d176f8fb0878f115757352ec): 1860614444}}), datum_hash: None }], fee: Value({NativeToken(MintingPolicyHash(ScriptHash(4f4ed647979104581198f38cc33bf18dc9d39eccc4c7847ea67be5f2))): {TokenName(b277a337e0f7c277dbb940662f774374d0cd4fc412e1c82f75da3111527ff50e): 2712245377, TokenName(b73f41ff0bf0fd19f4b91687b0146b48074634cbf18429d8104f0f0e806c47cf): 2724470942, TokenName(d6d0537b727c896b09eec212320aa1326488a794c446bb4218145803866cc1ca): 204951555, TokenName(e5fdba2517c9236f6727ea47f6269686e7159ef08c1376f18145331d7272b16f): 2946639197, TokenName(ea8f9bd188f63366fd4b36751fd19400e1c57b78a43ce9795b57b64b7c13b9b6): 1514162206}, NativeToken(MintingPolicyHash(ScriptHash(5c7fd335b0394b5b2fbf0894beda0a21f0db530ee5df4825222da8b6))): {TokenName(1d2eecaee62e606b2b409f07344c89249aa96f2f5648df7fc1bd1a2f7e1f0abe): 3149830167, TokenName(4640b5aa19c9467a8e2b882cbfd05568a123ea28523cd49071baa3e0aa240234): 1114408917, TokenName(5c29ed6d0c1270e719022fa598a198daf6cf61443d0fbf381949426102a0acca): 418466267, TokenName(bf86fad3ceacf34cbac8250997970e1eddf0c80c37447f41a0d81559026e6da3): 3114176567, TokenName(d487d6d1f2f03e7d5088ce48f660c92a1eb9b233b7a5f583229691e5037a9636): 371392486}, NativeToken(MintingPolicyHash(ScriptHash(96e7a3aacfcc19415ac2dd90d7ce6d66427ba594379d42f3b5b4e375))): {TokenName(17216189aca3503be5fb66d78f3b73839cb2bbc6fd9d9b281c9b9c7901bf102b): 2512001971, TokenName(18bd046901ab530e298d0ba093abd80e227e7b1fbc466c95d35d7030eea9a286): 3202447959, TokenName(2f02812f7bb3eaecdbc92fad8258f5d6b3db66d3080427517a8554050347a9e9): 2603671614, TokenName(66301a2107d40924082226d0f22e7b795009900f7a3a0328899435d439da6286): 403207560, TokenName(85fd2679f45d1d6b50cb36f5d64b85b65dee962d5be1bff4f57b377a8f35e7ec): 397536103}, NativeToken(MintingPolicyHash(ScriptHash(a978ad1fbfa0f0754fe1e3264ad0e7c92d4d23aac03f2ae51ce83057))): {TokenName(8ab36cea5ef850b0ce53f382c68c621ea705d5495f86db0cf55078f656b3ac23): 3764521872, TokenName(c98797bb1838a97368c48e0c601f437ab8ae4822c38f93403be750a123c5a1a3): 2621956, TokenName(e178df31fde9c97f1228734be022968f16f7fe4d78c9a92f966b50e679c9a72c): 235299451, TokenName(e74032fb845768d55c40a00ab97900a863d7e406f5baf84a349ac4e84beb38f9): 2784055924, TokenName(fdd46af0d5d1310646186a959be3b1b317b92922110841501c8c18420babc19d): 108793125}, NativeToken(MintingPolicyHash(ScriptHash(c7d0db00c2d19e9eba8c3b9f619fcfe0e43046cd8117eefad382e389))): {TokenName(30df48f1d8bb627bb182a2da47677c29674baaecc70d1e80db35f3bb7a40aafc): 3190993488, TokenName(9421c103289b7f6c602ef2ec25d041cc7015dd05d741997aeb30238043f7a424): 767833255, TokenName(ad475eb7e695eaddf149b7bf2ee885456b046dfa6838b446d888c9ef8782df8e): 2424177239, TokenName(f55ea0beddfd731499ae4dc3018046918aeeb3d461cb2a1309ebf87903d31c4b): 827024207, TokenName(fea6a093d67c81f8161c51bcc0d9e137cd97042bb4f35629fe7c96558b085a7e): 3082106472}}), mint: Value({Ada: {TokenName(): 4484255954812903887}, NativeToken(MintingPolicyHash(ScriptHash(16c6230f2f56186845dc2008bfa823db71539a5ed563f176250edc06))): {TokenName(35a0d926f60cbec1e088955fbbeb5aeec5203e3612dee4a880bfa997e17a684f): 2465735697, TokenName(6267b28a797103321be91df5a3b7c199e16d279dce457f8a856f4b2517313ba2): 251472862, TokenName(7caeb6eb3b2e9b7c902821836e4c101d49747799c9b79d8d5cc582afbaf6ea34): 2418753347, TokenName(9cd555aafc3e8fd7b91ba539f952cf1624b746af7216b7ec661dcbce62b3f284): 1685614024, TokenName(f831a804a92fe5bc468aef8db7482d967763d1c0ebe41b1ced5f4aa5f69e5692): 2725077761}, NativeToken(MintingPolicyHash(ScriptHash(4af71503e23015e31ff35994b1cd2c820b484baeb21fec7360392b1c))): {TokenName(26a82b25adc3982dfb2e1b9e9ecd78db0a428768ffa6304b6bdee9ca7809c947): 2509698740, TokenName(544b3d47be42de0880c70db985bccdf4368e7875d2f655f20d721363307b63d6): 4111962369, TokenName(54c885afb2f13b7aec9ed0effbbc81662ae2a0053f56f8807aa62e09d537ff24): 4044612435, TokenName(87dbe312baf0d7feac7548f9a155a55569ba7aa6c13d78b84eb09032ed60ffe7): 1674068454, TokenName(bfb1a81ac798b327de792926e337cb4899c4668a8031ec408d0cb98af0134564): 2932569205}, NativeToken(MintingPolicyHash(ScriptHash(506554a77c0bc35df1947eb3250fbd9e292f4432a4a2ff74128a397f))): {TokenName(439d05f17c19d161244fa33839aee5a99bd0d1d96ef3ab76df7030e52c45c774): 267031124, TokenName(b78a7e2d0b8f0f0c2d681890b1993e4d07475ece09b8299b338a59d5e34ef741): 26262469, TokenName(be5d2c2298065f139f51271c2152185f1439918931e2a01fad8ca4679903bdba): 3444892365, TokenName(dba75da7e05379972a38b0bcc662964b2c54c90d64c4827248ff7401f23faab9): 1821064483, TokenName(dbe5b65491100fa42fe74d95699d52141d711578ceb72e76e80b3ee6126ba736): 938105178}, NativeToken(MintingPolicyHash(ScriptHash(c52708db8b7bf379da28b854585b9e41e1ef4ddf280637242234c7c3))): {TokenName(39304d824080db9a5f92393396fadb520caf77b59005cdab0e7577fa3302175e): 1358842347, TokenName(9625a14dec1bdd9c5213a0bdfa94b1f2c1a0b7df4ecb242793c14a3b31372a31): 1058507408, TokenName(b0138894459709be46c58cb72296528b733914a9180fa065276c9b0d6e3903ae): 357692970, TokenName(c8758a70c8f7c460a6b8ae7abfdfd1ca71ee6b3ba1ad0715ff4e73ee185c2fb8): 1430671755, TokenName(d1c16ca432c4c1cc92ab405a97187a95004a3fd080124fde773bad74ace36b5c): 1799919870}, NativeToken(MintingPolicyHash(ScriptHash(d5094112526dc3c02d9b13f9b413d6cff40fd5c49b7d527ed6c77f41))): {TokenName(16ea7c5ba3b66835508e420048d0dd8d41dc2738491eca2c3abb90e44288e86e): 99281503, TokenName(1f993c4e33549663b914e109b07febe0a75720cd4960868b2cdf0a5d5843f22f): 1347731095, TokenName(2139f3b6f0f5a9e72ae394625f74e1a12ef8532cbc0ac071d67fbb3b95ff9698): 3585489705, TokenName(6afa274e6ffb96915d6db3194efecd2dde12f27aa9c5c34df9696bb502175d17): 3202351991, TokenName(a84e820c2e895166915d731acf01b890a13e90cfe15270276c6a3768fe0d1544): 3632298943}}), d_cert: [DelegRegKey(Hash(PubKey(Ed25519PubKeyHash(79a0ba43c4dc29215aaa34288b7b224ae89601f3fc5389d20766f02f)))), PoolRegister(PaymentPubKeyHash(Ed25519PubKeyHash(b95b9f24ec9eefc8844d44457aaef71f3e8423fa97bc73fdd8eaf96f)), PaymentPubKeyHash(Ed25519PubKeyHash(f54ab714fa6c5a7cae872c8cdb41c775bda9884f584a167ece55bfad))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(3263202212), transaction_index: TransactionIndex(1615444231), certificate_index: CertificateIndex(3527070464) })), DelegDeRegKey(Hash(PubKey(Ed25519PubKeyHash(8615ab504d3c130a55f6a0df284c7567b4a364d7f3cf84f7a198b4a1)))), PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(f8230b5a2e33017dc500b50a4d6ca2e972684a1a4ea702f02847fa35)), 233332572)], wdrl: [(Pointer(ChainPointer { slot_number: Slot(1937832358), transaction_index: TransactionIndex(1604387045), certificate_index: CertificateIndex(2991349637) }), 3602438527), (Hash(Script(ValidatorHash(ScriptHash(f80da816a225e3d053edb7c0a4359ff32b912a281520270d46198cd2)))), 2565874968), (Hash(Script(ValidatorHash(ScriptHash(648918be182456922c4fb9b12bc741aa21d65671a89bae866e4a9b22)))), 537790796), (Hash(Script(ValidatorHash(ScriptHash(78068cdbff32a36b7e5cba9020908329833f1f4429b661fb50aa4b32)))), 1854272316), (Pointer(ChainPointer { slot_number: Slot(60968441), transaction_index: TransactionIndex(139981048), certificate_index: CertificateIndex(3245224625) }), 3908710790)], valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(27131238)), closed: false }, to: UpperBound { bound: Finite(POSIXTime(706034310)), closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(ad36d045a57bf97ee7bf174af25891d8353250891086da213b593038)), PaymentPubKeyHash(Ed25519PubKeyHash(963567c0e649c14a9a382c29c9dce945685d117d6d1925e142b23585)), PaymentPubKeyHash(Ed25519PubKeyHash(ecbdcd8fcaaf29f36fd1bcd6bd10adc07058e101096d7ceee5679218)), PaymentPubKeyHash(Ed25519PubKeyHash(62c7695cafb6cedaa6d472ea0a940c61be92e94fe9c16ac2120746f2)), PaymentPubKeyHash(Ed25519PubKeyHash(b48e241660b29965fbe69fe7715ba77da52b44b7718193d6e62c8876))], datums: [(DatumHash(07c4afac8aa4febb64542fbcacd4302ffa63b4e839c2afd30e1f67fdfa6573de), Datum(Bytes([155, 31, 63, 241, 225, 191, 146, 49, 122, 27, 155, 59, 207, 177, 102, 7, 227, 113, 176, 183, 38, 44, 146, 16, 184, 183, 224, 244, 49, 179, 141, 252, 227, 31, 107, 159, 204, 75, 37, 33, 230, 81, 148, 155, 105, 192, 129, 255, 178, 64, 48, 55, 214, 70, 87, 226, 70, 79, 147, 223, 60, 247, 33, 212, 193, 70, 115]))), (DatumHash(5721a5f6c687c22b7c570d6aed4fffb594152802ea233d3d40f7e2165e6a1e64), Datum(Integer(-12882160068102115190))), (DatumHash(edf391db47922f85345ad6d6a2b4b6b3127e3cf3b7dc3606a0e7c906536af5f3), Datum(List([Integer(3907966504468315242), Bytes([39, 242, 75, 167, 202, 196, 13, 129, 184, 13, 32]), Integer(6525451893793250397), Integer(16764816957189074843), Bytes([245, 208, 254, 72, 135, 209, 189, 179, 20, 1, 43, 244, 216, 38, 21, 7, 126, 228, 245, 110, 165, 170, 198, 223, 176, 165, 229, 12, 38, 174, 117, 217, 27, 24, 203, 254, 189, 198, 33, 102, 154, 74, 72, 183, 186, 228, 67, 225, 143, 174, 63, 161, 81, 221, 188, 139, 227, 111, 43, 6, 80, 79, 73, 28, 203, 137, 46, 118, 37, 139, 249, 32, 89, 129, 50, 112, 39, 212, 208, 182, 211])]))), (DatumHash(c480643d03944212c448a34b299112f4c5a413ac456d2187d7085aea1fd7540c), Datum(Constr(3887588070, [Bytes([15, 124, 53, 171, 89, 35, 14, 221, 6, 253, 13, 15, 211, 61, 118, 42, 152, 184, 133, 131, 153, 99, 214, 173, 163, 85, 5, 92, 129, 247, 170, 69, 3, 248, 43, 108, 139, 24, 176, 6, 112, 115, 220, 6, 136, 103, 184, 64, 35, 72, 163, 232, 42, 166, 150, 140, 69, 230, 152, 230, 175, 178, 187, 154, 42, 135, 179, 103, 159, 67, 177, 52, 243, 20, 216, 235, 235, 215, 209, 60, 197, 44, 103, 10, 210, 91, 97, 24, 184, 73]), Integer(4317692085593261322), Bytes([24, 52, 41, 140, 0, 221, 148, 139, 145, 76, 209, 48, 197, 219, 62, 18, 128, 191, 62, 48, 19, 212, 113, 181, 225, 186, 0, 153, 64, 136, 32, 142, 234, 231, 156, 97, 220, 124, 133, 7, 18, 28, 144, 194, 60, 34, 42, 155, 151, 65, 34, 15, 54, 121, 97, 60, 95, 127, 169, 73, 247, 202, 125, 59, 120, 164, 36, 86, 149, 191, 216, 61, 237, 100, 155, 130, 195, 42, 86, 114, 207, 124, 131, 153, 4, 201, 152, 11, 47]), Bytes([188, 95, 116, 198, 186, 117, 13, 98, 227, 200, 223, 87, 163, 7, 168, 229, 216, 128, 12, 168, 243, 170, 57, 78, 108, 124, 24, 229, 141, 222, 120, 34, 65, 225, 73, 22, 58, 84, 155, 153, 13, 219, 47, 183, 55, 37, 53, 20, 113, 215, 239, 175, 148, 237, 27, 137, 111, 213, 124, 182, 18, 42, 145, 221, 124, 82, 24, 193, 62, 156, 159, 136, 187, 183, 56, 36, 19, 91, 250, 53, 186, 67, 182, 152]), Integer(2739006915478014080)]))), (DatumHash(5ecfd3be33d50f1700eaf26bc89b5321440da25da6a6b3cd28239dc2ee862c14), Datum(Integer(-5478635978075832525)))], id: TransactionHash(10070c59ae8c54e6a55f5fd485be722f2188813a2d4ee85b967c1dabb8844024) } +cc 5b67775395d00084146293e9c736691f6b9d7e7c02bd598321e92dbe73e96092 # shrinks to val = ScriptContext { tx_info: TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(000000000000000000000000000191474a76853450311e459ea0bcbf))): {TokenName(02b8261c1a919c2a4edc1336f3f800f7d3ce205b855b663715ee419987f88bd9): 3741398057, TokenName(122e280b426bc6440c4914bbab64f6716c473cd7a834e69121531a5fafb8601f): 654288552, TokenName(1ef9add2aa5b5e0398f77271c961698672d4d5fa325e6d013ff5c56bdfcf7cd3): 3559370096, TokenName(5fb8fd82d40a6718a99e9dfbec998930d8bbcae694172c5fda599c34109186a4): 2326038209, TokenName(f29f9fb017cf64c52e99aa6f929a69a338ce851fefecbec0de399dc7c17eca2f): 420951512}, NativeToken(MintingPolicyHash(ScriptHash(09ad47fb5d427c06ead6c080704c5b54db22f8839e5d3dd3d9f3be7b))): {TokenName(0cbb0b58cc8fe06f68f1a051bd9b01139e29f9df94c41af7e9e613ca3f24d167): 3210002966, TokenName(1bfe601a6acbcb51b1ddb78f72c513d2bf675f083f2a9cb11b6271c23ef88303): 2878634423, TokenName(68c65ad36070cb103054fe517afc32f834795cfb7b396e1f81294f3c8ce0a7fd): 3424265698, TokenName(77cdaac6df8e71fbdfabdf10c59a8ab916d164f6f47962e1fcdf4a4fdb08fe57): 186575199, TokenName(89c7383b9b247ff0dc033db43bfa07e41643607d4ef1f723a9042aa20f97628f): 3027129771}, NativeToken(MintingPolicyHash(ScriptHash(5c6028075971111bb7d5a311620a9f9598a55012b17fcc9bf34d8e51))): {TokenName(0a4881d8358303a6783dff3d3a73e595e5f8c01fab43cab26b5cc9a5a2adae59): 2460376216, TokenName(2345badbe25dc64f27c6d95aba4765b2c8f296f5e289ecdb90682206f6cc9359): 406994353, TokenName(a49de8d5803e9b560ce09a8af3f35eb350bbe87c8fd05e5ab07d1346bbd1059d): 3808232177, TokenName(c01e87fef3a79fd3341efbd3f18ee3d7823871582944fb9f21554a2ae9c2dc03): 3723094029, TokenName(e1757f18a06e8f4d074b922cb8df6a2be2efcb009808683347a8556521f07065): 820504965}, NativeToken(MintingPolicyHash(ScriptHash(7c6669cdc6f244e73658891d9b1e325f86d93d90a9e7502c797f2365))): {TokenName(155b07443913def1ffc7519d09512b79cccfe7ddf41f88f03b40e75a018b4a50): 638751769, TokenName(1e70a74aabf7e7ffc1971ca0729f393f0ed1c62350688e19d6c3a0315bf5a1a2): 3770825174, TokenName(a0465ffbd5acce57dc044b1268690c8fda0b913138145471e5d6e0fb3f15adf0): 1179534545, TokenName(be97d351b0dafe427bccf0f681c003c0bc89b06df02f9f3189195da954b7de01): 1552631648, TokenName(c0dfc617ed50ddb1e558474e6279c9e04ddb7a7c86067263b2aca5723a24687b): 1913074831}, NativeToken(MintingPolicyHash(ScriptHash(a3d435f2e7c8994929ba4e35d582110837cfca86e09ad3fa3a211bcc))): {TokenName(00a5d2f993fb2f2b9e81bade8ab3bf17401ace6d37620dbad95b34dfb864fad4): 964051070, TokenName(0259879921cf5b941f55f2c39a89ebd0588fd001e5eda5850c64f9389e1ec74e): 4066364501, TokenName(12121d337fbc5df3c61ff51a6eda2b32a635a141767f37ecb598711960a74398): 200844655, TokenName(421e4dec5dcd04567fb0722a1e22f09be6347d842c0549f5764629c9e20d6214): 1508702313, TokenName(661d5e817282516b0bf2de71b7da3bf3f31eb02b25e973e147cbdd9659f7a3aa): 3223840276}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(90968a9f232f9a4040c212665057fe487e28ce184d4306d903f0e34f7c224096), index: 3641377350 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(6553dc7078f97704252e42ea40751c8722fc88941100d5565d696f84))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(35443bf673c7b6e9a4d9bdc516d651a5d70c9c5e5c57cb9b7140baf5))): {TokenName(0d6c266b803c69c8cf7abcf12f009f3317f141e4e0e8640bc3f63bccbfbad126): 3220666971, TokenName(0e3ade09e2a305d4404ff0e66dd8d8e12afa6a7d31ec6a71636d9efcd45896f1): 3258366934, TokenName(456627e2f2ee9feb907f47d18c372fb02a305af3793eb53db91fe832e41e4444): 310994589, TokenName(68104a07401575ef47973cb5fa1e99c202b0da1734a34a0e59c7b9f093a59575): 1709980727, TokenName(df4a24784f4580939d8572d82996fd0c4c7ca5e8c266feddbf7b45f960075a1b): 1789775407}, NativeToken(MintingPolicyHash(ScriptHash(58596adbd52059eb96a87b60716545d064e07958131652dabd266ec5))): {TokenName(20867789de37754aee286df02b2d990ba7f6269fa9000ce35f8b4cf0fb5dea34): 3812777250, TokenName(6412c6875897a645fe2897e359e636334a2e9e1371292c09a132c64f7cd4f0ff): 1539272861, TokenName(662cc9ab8cf6df0f65069b86911e3ee924ba3cdd9e39e422d61c77032da139e5): 799707873, TokenName(b7f3fb70a4cd95836612de6334d68bd4316f357aff00d39b28e380b9f26cb2fd): 1299895896, TokenName(fd4d076e65e99ed503be37ba9c4601c11ed4b4bc8d04e6db25af4d5e4b7a3f81): 2058427791}, NativeToken(MintingPolicyHash(ScriptHash(6cfbfda004d5bf6c151a42c5346a964593497dead12cd96af9eb3eea))): {TokenName(2caf6a41e297f15c679cc92b87889c248fc443e86c9ebf4984dbb2760305fb99): 2039368744, TokenName(4699c6cf992949d42e66b83ef85ea3e97013954367e81bb0f312e7ad8c5effec): 822612872, TokenName(b803b6de56c16a077dbcfffddd6244a272e3e145e92d3764f59eb3dea01629c2): 4243055907, TokenName(bb1d53625c876b46bcd5318e00a74fff66a73baeb5f76a22ad7e72751f67d97d): 1460137028, TokenName(e5d3b3e8d61b256b5bacab98b24d63adc043260a48c90e57b5cf42c28e6d85f3): 624435344}, NativeToken(MintingPolicyHash(ScriptHash(7563f3d45817170b9d62bf297011c8e97673742663f717501c8c2d65))): {TokenName(4189bbf0935681c636c80b1d7174fa72fea56b8134b37700f5ffd281a17ca51e): 842749751, TokenName(7bae52f99dbf9370e82919e2559076784048ebccfab2666969b6d14c6c8a9fc0): 3797446519, TokenName(bdf8a0ba95bb1a9163b899eb36885da0fbab28fec4bfa33f0c7f8220d2f08b23): 34063203, TokenName(bf1471aee72a680fc44a61c367d54329011f96518e3f9f9499c2544d0ff9cc73): 1140296512, TokenName(efdde985c6e67c42b2dbb265ac37de2367f534c5c41d092ce6ccebd27f602416): 3103884496}, NativeToken(MintingPolicyHash(ScriptHash(bfae0e5f766ada3d5f465826372272f0bc04ceb787a72dfaa2a0b7af))): {TokenName(0804e35e6de2c11f269a8fdbb1a140a6202d1572f6694f9d31343250ba6262b5): 1800349224, TokenName(1bfb03fca76bbe5649070c25c428cd471d630a1034368b9666657d241d25427a): 2875064961, TokenName(4350135b9fb0839afad76923a1619f7625b799f8d6b930f22a6144c28e61f3ec): 2290497488, TokenName(6ef334575535fe2171fe3c73b0924c3819221f1755a15f118ec7c8a41fb2ea46): 900110570, TokenName(b0dc8a3f410328a6594cfcf03fb41dea7da07242865d5613123c88387423f7e7): 2605534417}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(6a17f19622e54a4aa37b064ee4e24a20dfdcb07b3de6f47fb3c371b6f8613749), index: 100036086 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(f9760bab71336319d2f2bb914f6b6d330a23d1506a487669766aa7d4)), staking_credential: Some(Hash(Script(ValidatorHash(ScriptHash(f3a9529dcaf233c0fd0adab1b69e37fe644c6d4abb992d6392b34777))))) }, value: Value({Ada: {TokenName(): 11066297076483743775}, NativeToken(MintingPolicyHash(ScriptHash(031d9bb3d1411830b73ba1fc049615e9f45fa540eacde49571f7c301))): {TokenName(3f1d1b0282cd4fba8702f11fa55b09d992e71e91105dc8921361be00b1e8cec9): 1574137814, TokenName(a3d6f82f057ecfe85e84598adf4f65f45785e2f9be068eb50723dd6c0db7888d): 1938268472, TokenName(b5cc2ecf75a2c0b216fb3d8205646ea0b0e927b64610b3bd55a570d1f005f0e3): 676331517, TokenName(c5e3402a575a7c6ae3e212cf095049be55803c89dd9dc3d91b22bc555e33234f): 2841681065, TokenName(e046b40f7eee648cffe0626d3e2a8f7ac604fce6d45e60ef5f1c269d4ae6973d): 1431309354}, NativeToken(MintingPolicyHash(ScriptHash(1967a4a232cc3759fe999a7dd98ae362e4a40fc39a8aae762b6fe684))): {TokenName(3605b2c90af1caae18eb81ffbb2b368b175a884531fd3dc9bae80e362395351b): 4060630825, TokenName(417870f35c6e30e5f3a4d851627b6130ddf0499ad40efc555fb831000c7af841): 4124959856, TokenName(484975a0f681a225d3385a10f2d65e6284049c73dc40db5f6f2779f3d2e4252c): 3927739254, TokenName(4c3e7b6caaa12a52a6ba46b497f3179c2ad56964f2157112156f73284ae06be8): 2891551242, TokenName(664d4d2357681f8194918bba9065deba4c259dbbc5a884df79decc6865d2334f): 4068940355}, NativeToken(MintingPolicyHash(ScriptHash(5d44c88feb6fd0af06f7771634c378184f55ae4bec36d1514757c70e))): {TokenName(0141ef48409c65b88ee9e4915072dc70fb0807c1d5a2edf872594db7efa5d451): 1863090885, TokenName(28ec4004b285b5ea031ab117b7ba8c861c4c0e87224e25a3779013862dd1a54e): 2618154546, TokenName(3d78cb6af48805c0629ed76522b460fce1c67a029653e5ae0d28a6f35a1675ee): 3906139411, TokenName(df643c48efe37d66bdf259d3e089600094e1eb74a0627a51adc0001b13c4b2d0): 915052555, TokenName(e7175a657466a47834e5d7588c9299afde82db686fab8e1d9eb8c5c5c2cf99cd): 3407814322}, NativeToken(MintingPolicyHash(ScriptHash(cc8714a53e1f4dcba661b80fad7070c3fc90b76986a89e51752cf98b))): {TokenName(a7f41f959a06fe70f6220f5b97522d48053a72e7917c1553ed915ef84f66704f): 1973847202, TokenName(a8ae516b2cf4e515ffb674529e6f2258a36829b19fd3fd92ae71e2cf783bc156): 896623724, TokenName(c6568a357f6df7853a1e06ad5bd141cb0de9776e7b0094fefe9241dd53777878): 268506596, TokenName(cab7c2316939386ce4b949ccb600a2bf42c5245b03fe48384e5b4b887881a95c): 123529537, TokenName(dce1f1f8bef90320a2e5cbae9229febf8ee19430bcb0b588aa98c3cd626eecd2): 3870790961}, NativeToken(MintingPolicyHash(ScriptHash(d94a89403fa59a90d30e24d4fa2d3016d11c7d54225b6d15a6dfa362))): {TokenName(50bf6d1415b195fda1639e70a69ae25bb8afc4a76fcedd55e2a9aa6813736f97): 1884504357, TokenName(58214e0e88dd2b118a788fe10bf71420cda84bf0e45d3e6e20e109a5fd1ba53c): 1968034309, TokenName(5f0764733b323a02bb0c92cce9fb830c068d689d30da5813b36ce733cdc14b84): 3976413660, TokenName(9744f243b0e341e18a308a1df8b476ebe076f1f30e7201b918ea9052ad17d400): 1491965510, TokenName(b0fcf171cb061ff37d359d337d3a8926edf3a051e00fc2c647b00d18a6208d49): 1195040897}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(f4c9da0c2f11149a84b29d8b029dc6845e4404626cf09c9f19840b831f6e1fd3), index: 3471291294 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(6a5536fd7cbcd6d15e3f36f291cead975171e36a9382d2cd5651d268)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1892659501f0b262889f4333e1b06f3e29c093822f1b62946bae97d1))): {TokenName(221f39f94ca6e001b5067384db616b6a7acfad993652d5841a08e3c4d30ff024): 2435908946, TokenName(28874851aae59945689b4f67424cbefe463a083bc974077d7697db2f25a4c8d1): 983369265, TokenName(70fc9dbdf7cd3c5c91c23266f33d7074c2bc7a8f1da436241fc0b633f5ff855c): 3942208370, TokenName(7fab7dd506ae6b9b4206545d41f2f78d851acc80a9087f8e53959d185ed5900a): 2836654077, TokenName(dd5d410d8e0ad8189f1b6538559a214a04fe38d987157de9c50e40f7046192a6): 2545022988}, NativeToken(MintingPolicyHash(ScriptHash(2f47f0226f42521492880e6e943cf101db929cd2c3df834177504300))): {TokenName(361ddc1bded66001064ee3ca623b2e456a93a572897eceddb1c7b4bc7e346c58): 785013788, TokenName(6bded178d1d759bebadbd549155540a5afbf88807434ce4e6b50086ed011440d): 2613671219, TokenName(772b8c64b3ab50676580a9ecb60d3545307e4d5a6ba97c667e67e1c10dfeec5d): 1809722074, TokenName(7bee84902cacce82806302cab231771d0d545876782500aab5639e1eaf443900): 2950267549, TokenName(cf9a694d089c3d25fc23ebb4aee9cb0f49629fe92d4aea823aac3ca22696060b): 2670860841}, NativeToken(MintingPolicyHash(ScriptHash(b3388ed819850cdf2e2d912502ac2abb28e5d70a9eff6bd82b74361d))): {TokenName(2e9c3e991caa2158f2737271414d1cc721a797c793b47bce36e9eada8fa58ce9): 263107722, TokenName(8c8e5656a2f9d4a3ef583ad9cbb1782b93b87a879222613b37a0409fcb95d7fd): 3215128855, TokenName(c724c4ae0635fbd270064643ccf1a8cf9f6ae91e66cfeff0d7be3281ceabe5e8): 4168052425, TokenName(ce9d4a1748fcfc074f0685cdbf4e319ded7b5bcdad0ebd52189bcf9b16a588cb): 2351570092, TokenName(d4efe360d4d1d6741c8efd2b69905a389cd0207b14c8185290318bfe63ca3ad5): 3724700142}, NativeToken(MintingPolicyHash(ScriptHash(cba1beb2925fa51eb87b6b65056021353dd5b7449db7c7b944facbfc))): {TokenName(466fb1ee99b1bc4588a62ff02f1d1cfc1e87c5f2a5ce323237994983967163e2): 1657790938, TokenName(ac1c04610899fe8bdb6ddf0e50359268c9e70ece93f0989f1574a8f592d40a25): 1032818888, TokenName(b24b23a373a1b04e93dec3da52e8d39ed80a215b724ae9f4deb35191c6427490): 2572413570, TokenName(b5c7725559b6c2056c7f3836d9f318f0ba04a785e2948a683e03e5e479dd9c27): 3435926259, TokenName(ee8ee91703a3653b45403e5f5291ee77e9d1b101ba8c2ff1e0a1548993ca12f1): 1118399916}, NativeToken(MintingPolicyHash(ScriptHash(da17ce0dd9fc880a89e1729304018f458db72abd131036b33573f259))): {TokenName(48a966713ab5b07d7d73fb48c605c3c3be66a51244f10220827c9207d778936b): 1773930055, TokenName(4d3fa0536f5564719d1de1923eac9643870284f1b8d97c6ceee834531d5af347): 1604427068, TokenName(790e51d1aec36d087a862bb9e3cad7ac523f8d151fb5e6d42aeb8408c68fee13): 4257658286, TokenName(dc6639db2c3ffd56ec090984d0ead105d845f25290f6ddb4f443bff69dd31451): 3146067101, TokenName(dd125c092d4c63b702ea569114f15c41ab4981bc1669350299ff0e41d44b5fb6): 271827712}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(5879dd6967db44cedc62952106884e56aecf4e7c4320dabf4b5935b58ba5b180), index: 3485704920 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(16d5ed17d22b43269cf47734eb3b4791779bb8f0fd4ee8228cafd674))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1b64d0eff8511e7e71840c375382108a416a2e1693cc9a8267c57d8c))): {TokenName(276ea1e86fda2273cb40f402d7a2460cb27639da86abb2ef78b0194d1a31a2f4): 1211614096, TokenName(601b8aa8570cd9708e461818c8397225ff3f2bfb567f576bbd75c3dce165a460): 1969511630, TokenName(6175f3679a1cbe4af4cbd9cc838f1e454442b5114a800efdc1cd2dce973930df): 3358248541, TokenName(bfcf5347dc6dc55145329b53d20c6b021025998ade52cd93788c1cf9036d12b1): 3446740241, TokenName(f1929d7ff3c4a1125f0aa39a6ff07cd5c441e5be96f2dbf26c9850f8255e61ae): 101120211}, NativeToken(MintingPolicyHash(ScriptHash(33320ba5d954cec458cedeb51f379d8f1a03c63bf2c766575aa290bf))): {TokenName(659fd962a912782749f64099d5ef62c7bdd76df0e47e801dd52355ec2df96772): 3681355845, TokenName(9555fbee47bcc0e066c2b057dd0b58a7afcf00f683375a5300215044a2e703b0): 718630574, TokenName(992f3a2b9d1bd964fde0f28702f127a5eb6dad458cc9ad0975c8bd2c6dacd281): 3143767483, TokenName(a6d3dc33838e4dd7d5854840cf7266ba2de7a9f2cc645e0bba2a83158d518d51): 4001142531, TokenName(f86ae4385152adaa40bb91d1e324d5b9108142315fef1d745b3383c7bdd5e818): 1669088936}, NativeToken(MintingPolicyHash(ScriptHash(4ec368489e7c56d7f33c05f0f13e0d01c262aea9e9b7b9b1cc4ee5d6))): {TokenName(1da397e76c46dfd80a6ba27cd499780fb3010015fe1eeb414e57609f5b3b33c5): 1021749616, TokenName(4e8e2c6617ed3c8ce96534e7bddb53acbc5466c8b94add08cac996cc83dc3518): 2046357757, TokenName(5debc1e877eeaa22c8f297fdf2ce594d796d96cc321b2b1615c88a26630e8b7d): 2281547075, TokenName(63f44d9e7015d3a4fed840475fc6f044dc05ede4aa87275423d06df5df19d2f2): 989038786, TokenName(9ca72b88afafb80d5cf76f4ac650448a67b22a89cdfd4af40f12c322e2cd4efe): 1137235049}, NativeToken(MintingPolicyHash(ScriptHash(6eb6f16596b164edaeda09d0668c970246766bfb483c8d1b5b626dba))): {TokenName(2fb5aa9f090019f81e67e7e18dbddd538112e7be1c05c7071887f00a425d9b2d): 1239704588, TokenName(4d8ed293429a0b79a2f49b6647a018642cca2d18bae093d15437d0076d82e8de): 1776598507, TokenName(7b07018feac1207c443cf68d29249e633a362922c4d748fb7f4cbd943afc6b4b): 3822481022, TokenName(874d2a492dd2b6c282b09816503cea74a3374cd8913a38cb5297ef0bff5af29e): 437540623, TokenName(a1e6f7a9b2592d8a74933b6018143fce50f2cdcfe22fe7753c0e3c59a7e66d62): 395590863}, NativeToken(MintingPolicyHash(ScriptHash(999ca846b08dda1099ecc43c7b5e110174d0d25866181f1236ffa98d))): {TokenName(019eb9984fe708f75e2617a90ca8f330b68ca0ea30a43324e62cb2f29792a941): 238253765, TokenName(24ffed416278eca29e73cf12ea2308500a71f889f765690d51b6bb1b1f22a0a7): 753468915, TokenName(5dbb7cc66a29e0a44163d6223794ec202c880557907574e8e0af58b82dc974b4): 3722048720, TokenName(e2304c5ca3f88be964f9b2bc6ade3e3e267cfdae3732df80cbc97d4fc98dbce3): 1151645541, TokenName(e779ad879e44b0dc7a8e40c39908c27fd05993c111ef255f422b6c8e13a98e63): 4157772306}}), datum_hash: Some(DatumHash(657287e635f99601d25672040b09ac56ea18a55960088dd59b70ad7d04fe7116)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(5410f27c1072cfb57633a166cb06dc7f63d197f57b280dae1c92e373)), staking_credential: None }, value: Value({Ada: {TokenName(): 2236402502608423157}, NativeToken(MintingPolicyHash(ScriptHash(37f5493926c37b8fd2fa750e7c5ac4453500925fed31390d16d187a7))): {TokenName(8abef3b5a2e98a58775628e7d02411c91c9210efb788695245aa1ef9b58aba3e): 1120796524, TokenName(8fe2c5a30b736ae7dc3490502fc0ef84064753d439034097ef9ee379473c7dc3): 3576353478, TokenName(b27b491ef2b05836aaca9ef9b2e611dad4e0ede978758d071aeba684972426af): 83661867, TokenName(be70ed4d37a8ff547c1e575c5573170d1401bb3c003ce291c94685a1fe6b1b02): 3643189005, TokenName(c16f5aa74fb45b833aa6168fa7a2ce1231d5314e62264dc8ebea2194cac41c84): 1032182263}, NativeToken(MintingPolicyHash(ScriptHash(4a4c1e843bf65ecc5ca696ab9cab914183a997e16f4f3fa6265cb750))): {TokenName(1f115bc73e8f1c04d5c3a9edf3b9e83c09b5fe1e3104d8d7cd2bc99df23ff186): 3531971084, TokenName(297ff50147d03a27d09a2de562db7ed2292ccaec76c8700bedc2d135c7944ab7): 1219519124, TokenName(308d8ff13de1001b0848be9e9d13b9697d0417368d989571683c1bba36a1363c): 3605905568, TokenName(bec2f9b28b8a267f3fe5d5d5c711ae27ddf76b3ee505938d06fd51927ee037e8): 3060620575, TokenName(f026bcc21051e5ad2a321ab61c4b14a871dd1d45d61e4f98d8992b59ad983420): 3862631933}, NativeToken(MintingPolicyHash(ScriptHash(4d5f93ccd2c9b5bc0bc51df9555f9a5b3823139c67d859e538204dfb))): {TokenName(08deae698d8c725836a144e4721bf546222c04f47df98acf4e0c4f86534085e7): 2338878597, TokenName(229cc3aba89c317e4e04094c9fea0001c7346be0d0c303803a51896ce607294d): 979340440, TokenName(72eddb58606fb5bf6a259fb145f21ca13150d2830bd8001c47d7d2921cb53177): 1633054632, TokenName(79133b5053a3cbb622df9e3f314e8e6139e98434bf8f48585b07eefcfebc860a): 3762308518, TokenName(97b726bcd8eab247a4811dd05af608abea0db5b9941aee61efbbf6afb1565a1d): 1480211334}, NativeToken(MintingPolicyHash(ScriptHash(6be3949f84d857200364320e1a260682af5892931a7f5e66a1e6b22b))): {TokenName(0e36e47218f60e0e59e2bf44d460ebf7cc8a30b93f86ebea8fa58f6beec1ca77): 3590196303, TokenName(2bc0d6562ad16687f5a8eb2cf42fefda4cbd1cbafd663c8dbe478f89d2744795): 105976987, TokenName(5e5c56d42e5315b2a5a7003427e4e02070a2f222e689c60310a93b6890841368): 4109335879, TokenName(5fccfd2181d9544e2795a4521d2c397ac1f0d7c4a191656c3b604eac4b568583): 1270584497, TokenName(86918a5b0a3342877df524fe304b2e6b4d3c2f11873e14ec3f2ab3e4cb892e41): 3009525002}, NativeToken(MintingPolicyHash(ScriptHash(9fc9a94a4a5090b71f2a27860023b053298e49960420009eeb40e622))): {TokenName(01585c6fbabd257130a002f4c3a91fcc0139de3fff030a9959d0e2018018e963): 171502532, TokenName(56c81ccbad02d0f567ab9299134088a0882b4026bbee5a7d6c5708587f15b5a8): 3059613463, TokenName(6cd1ee5901d7547d5673dc72e07d20a10aa27d226dbe6fbe350185b70b48cc2a): 1483144782, TokenName(88e27c6a9fa0a32499dba4068bf904d8dbbbe7953fbb61f8863d726f2365a92d): 3942060868, TokenName(916ada24b31ac4a91b574e136c2a1c20cb911f14e88a513586f9fb871fdb443e): 1287286334}}), datum_hash: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a8030bfa36be16a64f8ac42b15c32243403ef169c43f61f82ee34f60))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2526288468), transaction_index: TransactionIndex(1423893661), certificate_index: CertificateIndex(1434755680) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(16b697ef79174cbff09178e9913caba27e7fc6388e93e9921a6c7535))): {TokenName(4cf873940e6b18c637aec69c9fd1aafd8e6928bec40e36afa91ba88892a087ec): 65884883, TokenName(5cf79433ddb13b2170a6401ffa528a969f5a4b98aae9cbbdf34276dbe4a10369): 1245109372, TokenName(9aef3dbd3f7fbbcf12acfebcf3c0b15cdbc3538d5b3d981932ba85c9ed7f2320): 3480773757, TokenName(cc20daadb793f37dd582e6cfb6656b0bea4c0b7807b695b5f8a49ea9b2f792de): 3171074411, TokenName(d90371478085e9f9fff95c83025ae4113ac2baf817f810dd466518b20f723505): 2368810595}, NativeToken(MintingPolicyHash(ScriptHash(35f1c74fb4c5ea9c12effb4102533fa0b170e35bce4a8e53369f81e1))): {TokenName(29d086ee45857772eb6be342451c74a5722bcce88df144fc285661d827fef1c9): 1392013783, TokenName(4c3d2ca9248357a385a6105906aa9700c861ef741ff21f09493b844124ab9b75): 725500744, TokenName(8f83c910e5ad53ec564a4c882b36293fc163a535730f37eb706f569e6e696812): 1744470819, TokenName(94917f4b89958bfba62d02bdabdc00a28d0491293a2d0a6770a5629152e605bd): 1150828174, TokenName(f632ac7774b14cf5ae8071a87bcb371ad0d0747157abd598a04d6b1643cde18c): 388479184}, NativeToken(MintingPolicyHash(ScriptHash(67849ecd96a82888f73345d0667f792be240c89d2a0dd4f962fb06aa))): {TokenName(5dc223b452bd882745a3c0f28acee5188a28063806f07af312e29f4ac906779e): 1574752114, TokenName(bf65de834423af4259aa29415d2705532c9bc5553bdb3fae9d88a79bd43a8f70): 736416511, TokenName(c6a2166230b639294ba5b794a809f495ba80e3c136b3f10d4efedbf0473c901b): 287728001, TokenName(cbf25d0dbc7172a5f932660210bafce1223d3420facd2a991d8510fa07ba6b8f): 4271054289, TokenName(eac70ec87a809b8cda02430b90e8041cfce0e9cc09f4e8972cead8ab1cd35204): 3829911799}, NativeToken(MintingPolicyHash(ScriptHash(c87e6ad4a77c08a9cd62704ac664b4847b8d3955343cc764e6799a76))): {TokenName(0ebf4dc6be026d31b6d3e89616a9b854274eaa6b27586684004732ef06ecc7cb): 3331548695, TokenName(714224a04712f420831f663035b5d31e676e11f76070d083912d5cdc9312f0b3): 3198236104, TokenName(8ca93cf893162b4eb0dff19d86db7652f949355b0c0ada237b0a3e6996fa03d8): 19227515, TokenName(9e6f2d32150069f192452f45da2fbb8ed5184f4ebb312744cc638c42756ad4ea): 2833663308, TokenName(a0e5f4ee93c14d2d0acc9d69451b5c4b7fbd492db0b2bb11979f98fb40afdb88): 3016347740}, NativeToken(MintingPolicyHash(ScriptHash(c94de030926a397f8f2eb5689d191ad62b2e55b0baeed260b1e1eabf))): {TokenName(09509d4b63818755ac0f87929ef885c36c51fc130b2b258b97a5c0392a9f1103): 4248747602, TokenName(78946fa16f926786d4bbde8a66a405d90c4553ffd44234518e3a734873c653b1): 3224251699, TokenName(bbaf846cc30bfe5df9a63d2b16b02cf4471aff42d12a9de48f72d75f4a108a3c): 1539058509, TokenName(ca348017e38d302443b33a3884262415bce7c2f81ec8c755533e31139f3892fe): 3749331943, TokenName(d398fc91851ef1074e08e4b9e4bfa89df3eb80f82473597e91df3e6ebf7768a1): 3885424405}}), datum_hash: Some(DatumHash(b628b6277edfff8d284ebc42ddf97d4a5efc09d629dab71f712398cddd60d820)) }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(bd0a12cd4086632eacadff7a35117757a005e09abd27e17182f82474)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2906389819), transaction_index: TransactionIndex(2498004148), certificate_index: CertificateIndex(2910959286) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0cb2a99edc13cb44382b865663f5f4a65dbc24e7841ba2aec5011028))): {TokenName(2c1184e9ef870aeeb81c9d0b3840e409908a48df2dfe83aed36b55f3167138dc): 1647705484, TokenName(8a774cc8014f0295cc6b50d65f61af46bb85b2cb26644bb9242642dbc2768cdc): 1375149956, TokenName(9e43844045f151ab9a64a727946b9c6d80959ed239109c24c2c814dbea4c09dc): 3736400037, TokenName(eb0e8c7312462a2388c7b76eab0e1fd8388ca9b54380efef95bc2ef4ab130ca5): 2516519196, TokenName(fbd7769644ccaf2a55bdb8af9caa0276101f7cfee2049b20d5a653fc532528c7): 1753111857}, NativeToken(MintingPolicyHash(ScriptHash(1d5428cd7a033b9b904169b213da8402625c298f88dc37a50be43d8c))): {TokenName(0145d030a9b4304b520b1c60a5fb897dd053b310030df6c5131afc4245f874cd): 2946533521, TokenName(03d49d46b9f69298a585bb7759c1d2f4c1bfce7d0187692c1897cbf2490aee00): 1883058736, TokenName(05e6883aadca625019882ba68fa8cdb1fd8267adefbf56ce16ff63e0c5daa9a6): 1828812533, TokenName(3d9cbd49c03af33640e1494a94f250dc97b826bfbaa4473a9544b4c96d062c64): 423948032, TokenName(a9284081504726dd673907aa6f6b0f4b4406e69474a9d8346f47d82319dbad76): 1980557188}, NativeToken(MintingPolicyHash(ScriptHash(a2bb8d90c8ab47d346d975e980a1d43f045dec292535093e0d51c864))): {TokenName(02f4d4e68cbc706e0d0c0837201675f3bdcbad8c0cbe95270f87b7e677e74589): 4059186037, TokenName(0d27ac444015385dc142b7f17854f6a2fd226eed40db00e5471135abd2614910): 893862889, TokenName(4c0ba14a4e81c539b8c1927676051248e1f0470a0bdedbbad99ba757742c37a8): 3677005175, TokenName(9f54572f0d7dbc278f65252ec8a9fdd605514b0eb146b43f7548637b5bdb6d98): 865230738, TokenName(ff85c18aaa31427a17d09dd8b1c92deefa98de67dd95b5134876d69bff07fa1a): 2197769791}, NativeToken(MintingPolicyHash(ScriptHash(cf5353435cb62d2163224104e0dae0078a694a4aaf190fee0ae34a02))): {TokenName(1648c8d0d1b49102baa656497e482412767fd18bb4cdf1cef1b3c358d7a89f71): 1711195694, TokenName(26bb953943de5e600739f97c4ce75a75764a1ab8a067cb3e7c29f3016217adcb): 2877718150, TokenName(815e21da7c69f3e64b810907bf5c44933407c2c5e8ad953abdad6e2b0a799e70): 977946915, TokenName(9353e34d7f9c8621f44f914dac8dde9cfd5000b9dee7ac693708d228ed718076): 283297721, TokenName(a1054626db4e0d335f46d7a7f2c40b742ad6c70b78c9f88254f1f84fc3ea8589): 968690886}, NativeToken(MintingPolicyHash(ScriptHash(dea44770355f847a4eaf18ba83b0d401bdbf98908efb0e8b1f897f83))): {TokenName(4921eb7143be35f9cdfee9b098bfb4e6c76a6fa916ba52f80e222caad6e57f46): 2851452302, TokenName(6a6493bf51f70f648010e4c5d9ab406fdea3f05951b51b917e846d03f01c50d9): 4152676206, TokenName(71d6a6180f26982f144f2cf289c96664eab73ea43b9ee9fee2fca7ea3b9a6468): 1380940925, TokenName(b6ab7566b6ea3fc735c39ba9b1431c3e5d1b0c8cb77325b4696035ab4d2cf546): 1747434410, TokenName(b902a0f2088eecb1f3f7f4f2b88c685a5840b62bb7ecc06416612b4cb9b7efd8): 2641353882}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(b2b038341412cba317cf86df6ef6e935449381af66030af75ff42e51)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(3342422d590ccd428b2f3fcaca1aa9b4d1e8f7366b546b1c6445f894)))) }, value: Value({Ada: {TokenName(): 4948328761542502746}, NativeToken(MintingPolicyHash(ScriptHash(072fdda177af7847e1d87877c624158aa2d98cfd659324f2b373c262))): {TokenName(320c45c154400fc4d8d6b5a8cc4ceb9f51f8ede2daf8baf0d4ba0316d675eda4): 411254330, TokenName(77e69c2eb1e08684727019bfeae04c43687cef2526d2940436d7d7368a816d92): 1855020307, TokenName(8a1cb9930c75f32f95ff8f133ea76ee23e833d3e0450c4a846328b5b9944710b): 250752536, TokenName(c48f515f70d52822afd8ec7f704a53eca595542f7ccfcd37fde27af4dd5c26df): 2374474381, TokenName(e3b15cfb883a25f465bcce8f501af658cf8efbee426829a9531b9763fc37ab11): 2313747249}, NativeToken(MintingPolicyHash(ScriptHash(093ee8ff80c2d0096a9fb455bef075e199fccfc1954bb2986326aba8))): {TokenName(44591cefd9a148f95a280dcde2ab7ef30813cda04c082fe16c2df07ab91283bd): 3029068441, TokenName(69e2c5f840466eab3308985fd9e16d25b366eaf31df06b19ade95aef1f306bef): 3504873071, TokenName(a8da02edfd4e5b1176ac9961ba56da291fe9907565da43a2a79202bdcd5bb4f0): 1138322246, TokenName(bb2f1a91b2ac39def8a7e55d990d4490a66a8c4415aa0399d0bada760b6db917): 1512771149, TokenName(bcfebd930b1735f727da96689b8a672368000e30de9877cb4e4bfa235b336242): 3239823677}, NativeToken(MintingPolicyHash(ScriptHash(5b07738191c965fbf02211ce93a8be82b130af907d547679d6b3c7e1))): {TokenName(130ef730af540f6e578167e20aaed3664978c350f0b29a5401ddc5bba0475fb0): 2033047369, TokenName(6652918dd53130e4cd9e04fc6bc61e86972acb68d642284a63885b162490505c): 733077339, TokenName(7f333a23849fa278b7b4c94f059915205a5f12147eef9ea272491799f73bfd2e): 87433845, TokenName(804070fb43e317d87955b340b5344a8a433e80da64cd36d2ea4ea57fd299179a): 1631450234, TokenName(870f4bc4ce866180c857901e4aa71cf8a1879916e3aacc0bef31651a429aabcc): 1324734331}, NativeToken(MintingPolicyHash(ScriptHash(90cfa5b959bb2669038f943b5bd9324b64f1fd7aa175d1e04bf593f2))): {TokenName(44c2177821ab02387c05145daea415f5ed1e17c9daaf44073db5e4c8f2a09b95): 1125997943, TokenName(5085d9c0c0ec21749772b2dd1d833dc89740983dcd0c23a68e2e6ecac1514153): 2928004275, TokenName(959bbf7dc15d9a6a0fed3f43f5d9b05d974dca9957da7a95e128721cb0b6dfc9): 2886942365, TokenName(cb9169ed8349bbc980d191c3a7f6a5a203b0f8f7b60876b5d2b1393d5f7e0036): 3635081973, TokenName(cd884cbd66ac62ea2aeaa479203c11bbe7ffe99c1e07d32809cf042521f146b3): 1702000497}, NativeToken(MintingPolicyHash(ScriptHash(a0db8a554393782bf4db132fb516da7278dca0ce40c0db3baa142a4a))): {TokenName(00d094c2cea576664164a22fd766a5cabf6ebd344528fb09bba89ab562ef305e): 4192416526, TokenName(0b428b95a12e8c9c5ce6682e5dcc6b1c3fb3899a4b707552afcf5dbd0154baa9): 2331618111, TokenName(0cec1dc6336fa94860d66be7580d78aebac53c1c970395eec552ad9b508b7b4d): 1504969392, TokenName(1d4a8587b38efb2b79414a04342c3d05f252ce3fdadca54a45f207e8f9c29beb): 2777991698, TokenName(53b02a79e80c31c85b84e0493abc93d536043ecd524cfd7d7fea032d05a6e7e2): 4119511346}}), datum_hash: Some(DatumHash(ff527f3d10e8feb4b6b49b4e5878f2048461ba3839a09858ba10b0f46bb5c171)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(e05c6baab226429642a0d4baa4a6dcdf0bc263d3435f5ae166c9a139))), staking_credential: None }, value: Value({Ada: {TokenName(): 4553602872540099082}, NativeToken(MintingPolicyHash(ScriptHash(17cf83ec7b334a11f0b4afeaca399f3f0655df3d47b8ae389b867cb7))): {TokenName(0fdb6a936ef95425fac91e840d467b4af2002c01cf41174166287b25cca7a05f): 2730309942, TokenName(1014fec598837f1f57a0d8932b527162d300dbc38461884018b7056f090bdf5a): 2791151522, TokenName(5576dc44909b08bad91f97cc4ec172a2d84291eeab5c53203668ee5110d58f08): 811998201, TokenName(a35801eb73e0f2cafe000dc265c49190b9edd8aa8846b5d7a4865c0927c4b397): 4122858360, TokenName(eaee31b7ac5fbb6b11665bb43ec0662b4a6e64e2797ccb45b8f0a75e280f1619): 2270382587}, NativeToken(MintingPolicyHash(ScriptHash(1ef6385877ca6778cf88e5ffd054ed90d66da25378cd568565a096ae))): {TokenName(329a62259a89c9ecad955d28201e94bcfe386a67190bb4b051b7166c45b1796f): 1494858695, TokenName(749240046949124728861c7baf181a7b5ad4a8f0c37d884dc79ccb907e6e5af4): 1710360777, TokenName(bd6abd5b26ac8e1a109190b25708d94da4bdc16cf244e79a096c72be24e0a0e4): 2190753389, TokenName(ecde2b1d7c514389b66afd1d24cbaa2723f07caaeee61913a9f9701e8349e36c): 1232171392, TokenName(f121d76461bb94330c69f12b123c279ec26b092f669dbb079ea18cd0a876add6): 4026230494}, NativeToken(MintingPolicyHash(ScriptHash(23b29f5815c42402017db7bd79d21037c19947ed7f2c11f7757ae6e1))): {TokenName(0e289ea4f9af5cfc43e20f747dcb24d12d3c7ce1a40d0ede72b9c0cf579041ca): 1173553796, TokenName(1692c126e0ee9010182a8cb4849aefe076fcb9a1f4bc94c274c311b2ef9e5fca): 284175176, TokenName(28e7a278b4893a6afb4ea92e417549ca644be330f15581a9cf8ce75b441eea1a): 2358327012, TokenName(af490988fae42de1353cea6a530d4b19a0c08ee8fbc39a216d8c83916d8b09cf): 3410120375, TokenName(c14d13fc0b208e9cce0bdab33085ba6c59a8852af0d47bac55a17fccbb1e7f80): 3055786762}, NativeToken(MintingPolicyHash(ScriptHash(7ffee3ce8d283d8aa14745314091ed0458569b8ea9e84c0f3e8fef22))): {TokenName(02ae89ed9dff3b2a587d4a4137dbddebcfacb888ecd2eb24003bc69b3e3208d4): 3054823407, TokenName(184d800153b13706258004f4d896b86d7228c5f0fc9437c5b5b26b7b1eb0fd44): 2454894028, TokenName(662bd5eae7d2166f3ef6d2d1ea8e0273f202caf1bb2cd7e6b54066a6a9d23051): 3022759543, TokenName(b31ff8f7cae312f932cc13677a0eeaeeb77fae01c49117ed7aa8a58960f30674): 3188065398, TokenName(c07142a9e17cb03285e1ae8a17a16bbfed16fef9effbc22857044d4289fa8364): 1465431524}, NativeToken(MintingPolicyHash(ScriptHash(e8e9baf27214acb30ebfbf7c000b8f613cac2e0bdd663626eeb0267a))): {TokenName(13e6135a846bf7bc213d4ae04670c5d5c886419513a99d4997193b552bde6dae): 4084850878, TokenName(37ae5df9337fe81423d7c7a41d217cb66368d85949a899c9312750eb5792c347): 3709611353, TokenName(a92e2356e20f6a58903c882805d1672dcf95e2447e42f22284f466dd8c6db2db): 228959620, TokenName(c589ec27c134fbedbc5ec2c33da74785245808c85c796903164d6a770b90001f): 1239222555, TokenName(e9f13cc81c4cd36d8684f0c049f92324c738137cc36b69546090385a717fa8b7): 3850436574}}), datum_hash: None }], fee: Value({Ada: {TokenName(): 969633109869906273}, NativeToken(MintingPolicyHash(ScriptHash(8d6723525ba3d1f1d6997c0ae46f9d85502e6765dd041161633c3560))): {TokenName(06303428b96cb3f1b1d275527a0b6039afda0c190ed10b559478d9cec0b7da42): 3814140804, TokenName(3467ba2a37839479cfbad1d28281dedf585a6c0109a4fa238371f65e9a4bf60d): 1131929688, TokenName(658e9b6b33c3eda9de19ea577dc497311d2a0b96dc8d6ff27893b035848b9547): 250668046, TokenName(8599f7565c24adcc16f57a3b856c4dce7e7a5efa48d9a0a91df313ab66845f24): 1236629975, TokenName(921f9da770507d599e88df415f5b5fd1ef2dce3388b2abe1cbeb8819eeb2752a): 1375718269}, NativeToken(MintingPolicyHash(ScriptHash(a171c162fa95d08d59c680fbe807508d41460683e736f2964856e2e3))): {TokenName(1aabd16381297021a0281493745863dba32e12553bd1b96556bf2e88506140ac): 3291925497, TokenName(2050da14445b8940d5dcdbdea4d274e6bf7873455431b2e634c72d0c4465c051): 620717311, TokenName(4f19c4aca84ea4a29ffee3440d3d824566e19c06010a04507ff7a5a59e302a99): 379732248, TokenName(a13bb873c9e1de1bb2cdc7f48863712f5e80eb212804c14b1db8ddba6dcdb29f): 2246452864, TokenName(f39ee6358be13089fad7c84120980839632dc2c4704e58df41d490d6690a7a38): 3334683934}, NativeToken(MintingPolicyHash(ScriptHash(ac9446f80204a60030165546ac6714046dead84812f05eadd94551a3))): {TokenName(25a0ee877632392e02cd43d00aa6a7ca261ba4556193e0dc396cf98c2af31c6b): 3444385402, TokenName(3e01f229172eebbc73423db906f42c63cadfb707992eec85eab601aaf5dc1251): 3790718980, TokenName(a58da0fc2411a07ed3e0bc47af2a2b29d6c113a4488a3be79b92aa3323986f60): 1134977431, TokenName(d66116b4056bdd548a4da2780337013fcf1c4a75abc7e94bb6cc446e404a3780): 2609803911, TokenName(e9d67a85cb032f4116e0ac6c323eab6404a56e1148b367a2bc8f8c55fe0825e4): 1014384257}, NativeToken(MintingPolicyHash(ScriptHash(e564398c9d94ef31ba6b710d366cd39a3a790dfd302991d2fa642e32))): {TokenName(0bfa888d52987c26166e90cf2304068253d96258e0c71e74a178604a84e89a5c): 4003280998, TokenName(31d69eab408c70a8c0f0449c9c84f8331a4a2abb1a427e712b3a6f48fe4fd256): 1888595874, TokenName(d624bc70dd5f611aa436de15c3e1e7535bba75e7b42342959e2391d7fe4c5c6a): 1989441865, TokenName(ed5d23f659fecceee3347e90127d2c4c44e161f547a4ae595ff29b6f88ba53ba): 2198525552, TokenName(f603ead8ade9a61b1b88bcb269b1c5f784a65451e29f1e7a0ecb8c48239fdb45): 3645297236}, NativeToken(MintingPolicyHash(ScriptHash(f46ef9af924ab79c91aed4987fd890b61fe27abb8ed9254e96c74cc8))): {TokenName(59094af9093043e8a96b5a6bf5a335b12ededcb9f01878f91495fd2819aa67f0): 1766038848, TokenName(93b8854769f208a0256f9ea596df9e52a3fbb06850c2498488f40c6b93f94da4): 3559068440, TokenName(a8ccaaea3d611fce0be3df7b58a22e351ac9e255c72bbb7d37855b81f910bc9c): 543249717, TokenName(be59a0fc8ce2d78d60882d184c66faffaf77657003d8dc9f70cf920147f8e0a1): 3750383943, TokenName(cb241e54a1f5e0ed7f8be8b6c54c5e128111ec57015afedc6e73913c17e97ce1): 2954796306}}), mint: Value({Ada: {TokenName(): 7631164501003577366}, NativeToken(MintingPolicyHash(ScriptHash(000b638318708d6910d2d4ca2cf92eb08f54aa76ef9288860580bdf3))): {TokenName(118c464ebe2af200f4a14649f8bed0b0ef50ee1bfed814a8de00953f89bb050b): 2442299996, TokenName(1849c62509f9c1f054d41d926038c23b684a646b1968e8cfcc4a3647a28754fa): 2030710250, TokenName(22cd5e8112cc3a3d413eb1d4de1d9c383b7534f45ea2e829b43844c22ad159d0): 471205976, TokenName(a945c6e456cbc77f35eb25e2b936de6282a93b0c0b63183f607da00278b92302): 3274228680, TokenName(ad86d0ad387617c24e81a4343fb745231aab4912a61bbff939f782cbb56d2968): 3179376177}, NativeToken(MintingPolicyHash(ScriptHash(0e0ad372d8a5549a9280d97575060f8d2f292ef7b1e173a60c4fca61))): {TokenName(9005e23d6a7edd5a420284842e7ae4097e9521bd2a4ca4bad7bdecca8b75d9be): 1363897572, TokenName(b7755a335efa50067a4757dab725ca8f41b1a0c751ff53d3dc21d0a05291c7d3): 2898233279, TokenName(ccd71950b2ba7cc3dc8bb1717bba2927ed15142e84934ccfff98d1c6d23c7d91): 1289247048, TokenName(d1312a57e53827c11f1df869b828865c50d17482a205e4edc945582385e08706): 3074462666, TokenName(eecbf9e4f9d0ef421f7a59868225cebf18f7000f6de30e0f8493cbfee4d04194): 4135510026}, NativeToken(MintingPolicyHash(ScriptHash(14c373113770b8e9a72a862f1abf89da699f73f44eb9b74db712a10d))): {TokenName(0fcf4d730e7463311d146a4d32a365364c6520bd22d40a4811ce659c05019cde): 1253206852, TokenName(25830271bae303c2a40cfe96cb91492f9abeb5da45b51facd1399c6c2b3aa76c): 1256411084, TokenName(58067388a86c970eeabf01414993b019d237593fbb4515b40fc7d6e29a52df85): 471578325, TokenName(6b7023af0f471f0bc78c7616ec90ea0f9fe0c8e4e3b0134e227d45736785d676): 183113714, TokenName(c9813c42fb1f38e268cedf35457615fcca99cc094405926ad16aaf4ae82567a8): 1385894198}, NativeToken(MintingPolicyHash(ScriptHash(4fdce36936b4e15aef63e7f608f0414dcba259852aca6893e5d2b9a2))): {TokenName(1a9d777417acc7644ceeb3d52f5586c0bda66302bfe3aeb680b87f06c7c4712c): 2870070021, TokenName(383a08a33046a06148ef0b38605246a0577d7ddfc2a9621ce83165164491167e): 1995923698, TokenName(9170ae6672cfffa3d2bfa40aa08a337aaed400edceace5c518da9f034aa217bc): 3250266866, TokenName(af5319c39aa37eb907271cb377aab921dcfb82cd28985bcd471fae49da966f75): 4015499506, TokenName(ceceac952f631978885d18466f653b68cfd4ce8ef8ac171ecd82a5f92a289d02): 636890669}, NativeToken(MintingPolicyHash(ScriptHash(e05864b623516a63e9f9e515522404b98b02b0b2221c54598fdcb6e9))): {TokenName(11d8fee4e2adaee17e985fccf6c56c114f86c60734853082add8441bf990b63b): 2496407695, TokenName(603ece16dbbb888998f91d1238c4a456ebfdc957834debf70fbb10d91ad7460c): 1108103483, TokenName(627d25c701d7696dcb6834b71612b51d575b931f91a5ef2e58fb5e8efad32ac2): 1195013276, TokenName(c13ae1979f893e33e49acea02651b6ebdc4482195d852ce9191499b39811a4af): 2197115122, TokenName(e891c9a502e6f8bd48e6ec0da44bf42d86e7f38840491f262d2cbba4f2752464): 2321083779}}), d_cert: [Genesis, DelegDelegate(Hash(PubKey(Ed25519PubKeyHash(33a2aeaaa2f2ea80b5090a2b82f487b57ceb931d469b58e01e43b94c))), PaymentPubKeyHash(Ed25519PubKeyHash(6a77b6f28a34ce07ad408232717d4946c493748591b8f35b94d0f25b))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(433742330), transaction_index: TransactionIndex(1845628647), certificate_index: CertificateIndex(2772472914) })), DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(742649179), transaction_index: TransactionIndex(704895891), certificate_index: CertificateIndex(2566189219) })), DelegDelegate(Hash(Script(ValidatorHash(ScriptHash(542497dc23302d140546cd8be6b86b518f704b858edcf808ac2cadbc)))), PaymentPubKeyHash(Ed25519PubKeyHash(7daeb663c2955e1c7bb6afa4005fda2c6ebcbd5bfef080b2e84395e0)))], wdrl: [(Hash(PubKey(Ed25519PubKeyHash(68aee271f2f2ed00343c237a0284243116bac2eb69c5d3800054efac))), 3319729642), (Hash(PubKey(Ed25519PubKeyHash(3a70e62fb80a360afab75373ca182ccd8b12145917e679784d82d799))), 1883636234), (Pointer(ChainPointer { slot_number: Slot(2507536261), transaction_index: TransactionIndex(2809721782), certificate_index: CertificateIndex(3948189935) }), 1091631966), (Hash(PubKey(Ed25519PubKeyHash(675e7d0092f2131828a0a0c1161d1cb2966896b189fb2508f33e3bc3))), 1036524356), (Hash(Script(ValidatorHash(ScriptHash(2a0df4e2705f4f465b7500d0448f5b86ce338f8f3a1ffc81936d613c)))), 2084137754)], valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(509290088)), closed: true }, to: UpperBound { bound: Finite(POSIXTime(1589796949)), closed: false } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(e113607d8a6900dc57999fbf7436a2b258b265c9de34b66adbfabfbe)), PaymentPubKeyHash(Ed25519PubKeyHash(9919208d63b0eab1469561b6160e620514a330a5c9687ea4da91eba5)), PaymentPubKeyHash(Ed25519PubKeyHash(84cd67e498c6e295a7f6d060445cefb3769342c7e6d80e49d9572f16)), PaymentPubKeyHash(Ed25519PubKeyHash(4510294c5ff167ecce09307c0e7754b9810023f91ab4a13c283ded1d)), PaymentPubKeyHash(Ed25519PubKeyHash(07843ba0ac368ac6fa41d8a68df466e6ce43290a792f43c925834220))], datums: [(DatumHash(1dd2ddd0f1687da13c0471227100821e5caafea2a6c0bd1836031a71d959296f), Datum(List([Integer(12111198339882327665), Bytes([148, 36, 223, 226, 122, 56, 252, 144, 89, 156, 32, 217, 100, 206, 105, 13, 220, 245, 56, 220, 245, 97, 79, 5, 11, 193, 163, 60, 49, 107, 143, 205, 45, 119, 143, 111, 0, 52, 158, 154, 35, 166, 69, 162, 159, 87, 136, 252, 138, 16, 197]), Integer(14917055000583713380), Bytes([250, 84, 182, 96, 4, 26, 241, 41, 166, 168, 99, 85, 41, 235, 69, 187, 56, 88, 226, 193, 14, 75, 123, 98, 232, 13, 157, 32, 177, 152, 85, 123, 59, 243, 111, 246, 108, 68, 235, 177, 226, 125, 225, 26, 197, 84, 217, 173, 246, 216, 173, 47, 89, 189, 140, 201, 145, 56, 94, 125, 200, 166, 205, 103, 149]), Bytes([28, 53, 48, 133, 148, 22, 66, 28, 53, 97, 115, 177])]))), (DatumHash(ac4bb31a4b8c0e5dcb712f54b54e403407223cd43f07ec9714d079ae10136e67), Datum(List([Bytes([26, 174, 162, 173, 112, 10, 99, 29, 35, 19, 111, 56, 63, 186, 224, 219, 148, 130, 223, 192, 49, 243, 125, 69, 173, 244, 191, 205, 226, 116, 205, 167, 227, 248, 232, 175, 27, 26, 90, 105, 140, 133, 134, 28, 145, 71, 212, 33, 187, 111, 89, 108, 130, 174, 210, 57, 117, 154, 220, 41, 211, 115, 13, 145, 148, 221]), Integer(10600455703549979744), Bytes([48, 253, 65, 239, 169, 140, 189, 124, 221, 144]), Bytes([122, 155, 53, 41, 41, 192, 134, 181, 116, 240, 45, 233, 57, 218, 36, 241, 20, 139, 199, 77, 235, 23, 233, 152, 217, 187, 184, 240, 64, 231, 25, 250, 160, 21, 228, 126, 204, 131, 219, 58, 41, 185, 223, 80, 221, 176, 79, 161, 85, 199, 223, 80, 194, 18, 180, 222, 49, 41, 202, 222, 137, 255, 29, 22, 213, 10, 144, 58, 238, 42, 6, 35, 243, 58, 15, 217, 40, 111, 25, 2, 25, 212, 229, 253, 136, 26, 133]), Integer(9156334723734449835)]))), (DatumHash(10d026a0084cf4a9945756217eaa5d6ff2451e56467e6c5cd42122f11f628b24), Datum(Constr(1096592962, [Integer(7149187219739976565), Bytes([244, 46, 11, 183, 246, 67, 232, 48, 14, 111, 216, 61, 118, 10, 48, 192, 253, 92, 61, 142, 111, 168, 197, 243, 114, 219, 132, 77, 186, 116, 95, 182, 67, 6, 152, 233, 53, 228, 57, 252, 22, 243, 240, 95, 48, 129, 49, 92, 42, 218, 9, 254, 135, 99, 92, 245, 250, 24, 66, 204, 229, 188, 203, 128, 251, 48, 125, 182, 72]), Map([(Integer(-14934554458418146212), Integer(-8733990149434153712)), (Bytes([157, 49, 60, 178, 244, 196, 156, 140, 229, 102, 124, 77, 45, 73, 113, 181, 20, 32, 240, 195, 67, 122, 70, 157, 85, 189, 198, 104, 227, 153, 108, 116, 243, 239, 13, 21, 141, 175, 93, 15, 145, 104, 60, 190, 223, 107, 49, 78, 85, 161, 59, 133, 31, 163, 136, 68, 172, 105, 155, 248, 15, 46, 121, 150, 56, 53, 216, 85, 226, 230, 68, 8, 144, 93, 67, 132, 57, 30, 123, 165, 83, 105, 12, 42, 157, 139, 220, 146, 70, 9, 114, 199, 169, 84, 160, 175, 176, 177]), Bytes([212, 160, 118, 135, 239, 173, 227, 137, 220, 211, 1, 137, 239, 171, 193, 85, 157, 221, 47, 64, 78, 148, 111, 79, 202, 215, 31, 55, 99, 113, 99, 33, 80, 188, 17, 229, 90, 58, 49, 78, 70, 152, 129, 34, 74, 122, 108, 44, 43, 148, 116, 194, 164, 205, 177, 138, 49, 227, 121, 50, 76, 97, 251, 6, 190, 209, 228, 81, 151, 157, 151, 186, 114, 42, 138, 59, 17, 100, 15, 231, 231, 236, 40])), (Integer(2664178424296852335), Integer(-6867474426338311931)), (Integer(-1806391647205798784), Bytes([244, 53, 57, 234, 143, 202, 109, 129, 44, 201, 203, 12, 149, 133, 165, 145, 226, 111, 34, 114, 123, 80, 137, 14, 222, 219])), (Integer(256972643692214470), Bytes([192, 141, 215, 60, 238, 113, 69, 5, 164, 130, 54, 109, 144, 128, 95]))]), Bytes([59, 154, 183, 176, 156, 136, 223, 146, 60, 72, 113, 242, 46, 117, 33, 119, 142, 142, 84, 82, 222, 26, 148, 174, 241, 32, 226, 186, 212, 118, 88, 182, 17, 227, 241, 15, 57, 187, 211, 236, 129, 190, 84, 150, 110, 40, 44, 147, 190, 148, 159, 89, 4, 115, 51, 75, 139, 182, 84, 133, 207, 120, 115, 228, 93, 37, 233, 105, 214, 95, 222, 46, 230, 49, 15, 87, 227, 237, 39, 80, 86, 48, 194, 63, 174, 168, 31, 26, 86, 0, 164]), Bytes([21, 128, 222, 61, 54, 46, 143, 58, 29, 162, 173, 205, 8, 93, 130, 28, 235, 165, 198, 155, 110, 55, 178, 168, 73, 221, 254, 89, 22, 202, 215, 217, 150, 20, 33, 221, 81, 203, 118, 156, 127, 214, 131, 22, 249, 99, 25, 251, 36, 75, 178, 190, 224, 124, 42, 52, 203, 128, 143, 114, 226, 183, 124, 199, 20, 200, 170, 194, 34, 236, 242, 129, 144, 176, 10, 150, 160, 228, 8, 42, 111, 44, 231, 234, 58, 32, 91, 44, 24, 71, 168, 60, 91, 93, 222, 241, 58, 192])]))), (DatumHash(5a9e575b9c15ed46c23d13d6dca4332e65173baaed23a0a85c089605454e21ec), Datum(Constr(2595342282, [Integer(3451760200702215501), Integer(4010655019245624044), Integer(-8093943009169867001), List([Bytes([193, 156, 95, 88, 91, 123, 132, 115, 55, 37, 203, 156, 24, 192, 167, 27, 135, 198, 243, 62, 76, 106, 186, 69, 71, 165, 93, 10, 114, 226, 203, 138, 84, 132, 238, 230, 3, 253, 200, 148, 45, 209, 211, 174, 173, 159, 35, 89, 13, 41, 247, 107, 96, 106, 96, 145, 94, 249, 77, 37, 173, 207, 74, 182]), Integer(-16665941241912134423), Bytes([20, 84, 186, 180, 237, 24]), Bytes([103, 149, 173, 37, 34, 114, 167, 61, 2, 216, 158, 169, 89, 50, 186, 106, 24, 166, 17, 67, 58, 10, 94, 127, 158, 87, 232, 65, 73, 31, 74, 194, 21, 100]), Integer(5453360218659488194)]), Bytes([2, 117, 98, 171, 152, 219, 55, 178, 129, 208, 146, 96, 237, 7, 220, 3, 253, 59, 7, 79, 213, 97, 5, 93, 163, 33, 195])]))), (DatumHash(2f9de4fc167f0b49183bc40817fc15942ab2f597897940cf768ef87c93fa0544), Datum(Integer(11619849138673604607)))], id: TransactionHash(dcd169344bc415da546970cf271abd433f7a03753088565f726230b5c9f40c67) }, purpose: Minting(Ada) } +cc 4ea6dee47095eed7adb6b2f1b4469e3ca031194fcbf8f58cb6c857342741fa9f # shrinks to val = TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(000000000000000000000000000000000000000000019f5c475c78db))): {TokenName(1f4f6c406310702632f4c3fa47392446d1b98889c00f9aa1626a94b980159df0): 298478092, TokenName(4c24672d372a413cdf59d512547e7231f0ef38e178b7018cb52a5ed6e9fdf4d4): 3492788874, TokenName(52cea5842a7d2e038ac4f72bda0bd3c6bbbf089aee1cd4f11ef1cd3190b12f71): 964251169, TokenName(a40750b39fe5116fb949a2cd52c88eb9357a3ec26036c260a69bceed6b3887a5): 2159064232, TokenName(ed869353d807ec5cc5ecd4d2aab993f4b0499fe03f8d34737974dff784818f32): 1725260373}, NativeToken(MintingPolicyHash(ScriptHash(325e8084cbbe91a0a80e30d8cc27cfc349085d2001111a51514d4d0d))): {TokenName(15b5a50db50d46d5ec5514cde300e35009062f30992d3931d3c1667e96584d70): 1865081206, TokenName(4ab14e32ac37481caa92dd11a64bffd7f7b1aeb57d9a5d2b96d27996eac65ab1): 2349547655, TokenName(9a64b19570409bd4fccacc8a554282769978875bdce4d923b1ab75d10f1296bf): 1851207128, TokenName(afb8270e291d11257fa7652e55830f0ccb1f7acc1f4f232c614a87333535d29c): 4017700958, TokenName(bfc27034cd3673af9f4dc828ee1aefd4ad7df8a57adee4a867c6ff7525f48bdc): 854588756}, NativeToken(MintingPolicyHash(ScriptHash(8cfd71a4b893f1b0ba1a663cdeea73c0ff9a116fec5bfeffad7f81c5))): {TokenName(17afadb47268d366e5422aa9fef69dc008099528e1b09b6c486ec432d7216419): 674029915, TokenName(1e2a9944808d8babb9c9e1baf683ac3ba14f161ec62431578a54abd2330f77f5): 1791958212, TokenName(9be89f1dcf4ca802510a01aecc9691008477ff1f9c7872ec339ef518ce215222): 995249238, TokenName(9d4c66b90efc1b0a9705a873394225bfec7a4c9897897f43476e7435a98ddd7e): 873638795, TokenName(f859d8be597503ec124919ce41f49f86452a6ae4045e005fb550c41cf46a7894): 664491160}, NativeToken(MintingPolicyHash(ScriptHash(aaf82f6194c9a2c9c22a2d84a6018f3db15baf1eef34ac9112df0f27))): {TokenName(42bb0f091664d20924f1233561b35a78888dbad58e3b730366c3f8d2afbabf7a): 2130410640, TokenName(a038c562498b1039ae48c86f1e0d2caf745cf52ed10765c5ad50c18766fd1e8d): 2441312155, TokenName(b603aa5b76770eaa33b7aff1e2f08ff7766a167442ea3cfe32433d2e5d7c1898): 1235255672, TokenName(c4e50f0caf814feac611970baf05e6a95ef681a4d3e18b5241f86a47e0e16c80): 3111581855, TokenName(d212a2247adf4ed99ab7a76e151c01392164857b4072fc429cbba28d10d9f5cf): 696705209}, NativeToken(MintingPolicyHash(ScriptHash(e43d40d173224446ee47f3996602239ba997eebbc89b90c5f7aff85e))): {TokenName(08f7a3d6aa99731f8f1c29408f3545f34acd59be5dd3f236f54d5a944a1b81f5): 225263698, TokenName(5f9ce2dcd7818cf2083128f9e54f98f8f60828e40bbcf3ab1f0f9522f7c788be): 733392177, TokenName(b2de3f0aa352b169490ebeb0633e4f7b2a0ad5d4977f31cbc714fcdd8eb58ca3): 2712434547, TokenName(cd30493be7306304470842dac2612255d72fed4d2d9f50e465c2a87e065df13e): 3399809590, TokenName(fdae4677b30e10039e118fd2f05ba8e9a1fe96b76a96bf568a3d31993672507b): 1218974563}}), datum: InlineDatum(Datum(Bytes([144, 218, 0, 205, 49, 206, 112, 203, 48, 141, 239, 85, 127, 139, 47, 136, 195, 94, 212, 234, 63, 151, 197, 4, 120, 67, 14, 234, 165, 232, 150, 48, 144, 82, 55, 157, 8, 74, 76, 4, 173, 68, 162, 249, 241, 69, 132, 219, 251, 173, 217, 213, 57, 186, 93, 252, 23, 255, 92, 206, 182]))), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(a2df58c0f9342ae1a01de26bb37d3fa10a8a8de1f68792f93488be3de867bb13), index: 2288900289 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(1e5801da8ba2c61f4aad552ba2666db78e014c5a0516e114e2485e49)), staking_credential: None }, value: Value({Ada: {TokenName(): 9077772753944363893}, NativeToken(MintingPolicyHash(ScriptHash(17c19a9d3c9fd2721fcd21d355cf215efc1677f4f51233868240d838))): {TokenName(487d6467f40f902700815c1f753c7472d255968fffb9700e6a88ece58c2e3e5c): 2661724228, TokenName(6772362ef6d7f7e3d48932c682d1623232c7a37c0780627bc762d544a37301d7): 432390567, TokenName(7c23d2fb743212b3aea606e7105c09bdeb8f13c41796acee993d6621ee390b22): 1475735511, TokenName(9b999b9a1d36eb0e007ba06d96ae00843d7429374861d8a0016c0ace862d54f0): 3837974677, TokenName(d2506f4269053153d864e0af42bafded34403ae0c8cee18fafc42b3bacb7df82): 3627314589}, NativeToken(MintingPolicyHash(ScriptHash(352d5f0781220fa28efa8bc69f074289772b3f7c9fd491ac771686e3))): {TokenName(0403dd3da072efb42c40980e52efc6d5ffd0d5e7de0a5184a9933e5de0804359): 2443674359, TokenName(32ec0495fb8205d2449ee8e44f17f514478d4556b7510d569491c7cfe3bd3296): 326409729, TokenName(53ff5a21aa4bb3655d02c626878d893c9673665582de1cc894d5560bffec7c50): 2758731830, TokenName(66653c46782300fe860dea0a5ae9f19d72016d2f1a789a91ae26aa667f8b02e1): 2490347972, TokenName(ce898f46d5737005a5525cdf56eb77e1f90ee1e9d32d7d49e69d49d9ce855866): 1911570543}, NativeToken(MintingPolicyHash(ScriptHash(669953cc87a77b91a385c5ac8d70bac264bacc90661ddc6a6d97b4fa))): {TokenName(56cc0e046d8b300ef14612df0ec5f196fe2c0a245c6379992e275867106a42d6): 2967458774, TokenName(7eb354e2cac70aa2076485e569ef5b8eb2cfdff1b5d478b575a9be90bdab044a): 4252955295, TokenName(a1738371cf5dc8a2781d875c18ddd7b4240f186396cd5e3988980c0eb021332f): 3304613221, TokenName(c0d6e3f303bf1a4ff710b2c600baa688908b8c3cdf172adfa86401c0d2023660): 1865242021, TokenName(df281eb7bb8a6a8421304cefb45d5ccbd250336c0eb4fb4c9c01c73537acc803): 3531359257}, NativeToken(MintingPolicyHash(ScriptHash(c2a3d01e2c668d57015ac8c793f559bc2335dbd93b216d9a39b097db))): {TokenName(0fbf10dce451b0ef5938dd50612b00ddfd7568a3dc0832675569581fa8d788e7): 745911105, TokenName(219eef88f2b12ac6e2395186f96db803914e249a79f0fc9270571edb29cf90dc): 354711841, TokenName(5bd274aab4e5113eeb5ff08d12f5c2c94e99c6b505f04b3bb9cefc62868116bf): 3519212836, TokenName(b231222b345e2003f6ce5edb59b79d4ce9aa5083f2b1124710987b6142d61157): 866543946, TokenName(e35aa0de564f94f459b3600570bb3493f61201d36233570ab8c57e6a7c97cd7d): 952891787}, NativeToken(MintingPolicyHash(ScriptHash(e4d28ba4b28ae7428db79ba76bfde03480d979cba1fbecee20e01d71))): {TokenName(13348b10567872245a3ae7378351aca35d05cbbedabce6e1274d7d9e2b2394bb): 95487821, TokenName(215634911664a4316b7f02e81b6d26100751fe9b93b4542e837675a1a64390f0): 945209453, TokenName(6a5879902fd5eb999ec210f1ba9cf3924bec25f8f5afc0573c205f4222590171): 2628764579, TokenName(7913873afa53bab60882c4017b0e69f3de328079266b74ada2ba3747357c6f51): 1087784257, TokenName(8338e35b27f5757dec720221bbacfb7f16255b0451f8db02235fb5c6e2e8ab2f): 2074210583}}), datum: DatumHash(DatumHash(d45897f55f130908190639ecec271ac407ca36c981f40d5a644be632d773d0e6)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(20b81a65dff4205bbbeb1353bb9abce3d3ac873db8c5413da1eea8be82384e28), index: 1401515414 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(bf408dd6d4d82476144322cfca102a11207501d6a7fc0e0276abbf10)), staking_credential: None }, value: Value({Ada: {TokenName(): 17226239645628683221}, NativeToken(MintingPolicyHash(ScriptHash(05737918037b436a5e19b9a3b976846d9b884cf075fdfbe8ab2837da))): {TokenName(30dbbca2b96c05786840bc34d2c9f8a0d93ee3567866902e0c3ba9c63a715390): 1922299337, TokenName(68f052e86dd26d7657eb2e660f327beb8ba06824980091a02bf0ac4ebcdc416a): 4241694833, TokenName(7d486476de91c59f471c958f72946b3d2304e91a8ed6992de7f656e0c7ab7ba3): 1286087871, TokenName(b634ffabebe78cb006a382dd4a1603477668f221fdbdcb4fc7cb5890d3e00d12): 2722243297, TokenName(fa571a84a604363ef386b6667e638c811ceec8fde4a339e78f08a441074f5b05): 2572314377}, NativeToken(MintingPolicyHash(ScriptHash(089b760914e173437485ed05492680dc23e4692607c794ce784aa16c))): {TokenName(4b50c28899cd46744537a5004204c9d9d728f5f06b5d0a58d85a4c9b78093fed): 3055907814, TokenName(90c09083d35712db73fadfc7e3aae9e32f031930a0ac43a7d87bdabe8ad6994f): 2891085892, TokenName(a67f5a95dd298f03fa824da698785d4ee1aa9cd58f8a584a734ab7ce3f6d8049): 3604978156, TokenName(d4ba150d183a99c3f7d557d5c318ea022e03281b9c92fc58dd297c18ea687f94): 2119709419, TokenName(f801b35606a5819c8b364944bd7a29b6ef9ea121c2d2e5714129f9480d00637e): 3050410399}, NativeToken(MintingPolicyHash(ScriptHash(2e8cd2f85e70af3d9b60b3ca1e8901c9504b9692a574108f381cee04))): {TokenName(13158a46be1784110e381c1c922f81e9b7eeea899d51365f487fc139356e185f): 4105100998, TokenName(21c14848b68896df4f244589a8b97c96ecfc61f03fb340b80cf69547fd5dc94f): 2297652702, TokenName(33390b5ae6a08c25671b9712d86f57e0c5ec0a244531cf1901ac535bdd731d87): 1005754467, TokenName(e13acac311416fdd3c94b89f2cfe33d9216c4a0a1a92337438e8897124e7eacf): 3474217748, TokenName(fac1b7beb919570c8f02474c6454a1f6503a09a852c7632ebca8e89ed74728a7): 773564202}, NativeToken(MintingPolicyHash(ScriptHash(6e1ffe77b1ef21cc672c8571e46c7d0455103948e0ba13389138655a))): {TokenName(059c757801e8ece193ed78e8d4b3d10cd0b9e5165a0f563d3d60a3813af9e336): 2787529088, TokenName(6452c2fee5c3fcbc09ec4068beaf194979c1a63308561e3b2f79cc21803b618a): 1795408408, TokenName(71e6f03ad83cbebdae82f68e3a87aa2fbbad90e1e992ca49e0b8e8ed23180786): 1601844901, TokenName(e70008d3615b2d226bc617d9209ecf164ad856a10d6bfafbc3b3011f720e5930): 968495623, TokenName(f9f96d99599e0efdf46248c2a0e06f454dd5361174881f1394fdbf17ca8d5e1d): 3306415807}, NativeToken(MintingPolicyHash(ScriptHash(fbd3ebb4c1d925958b48e029b2ddbc42587ebb8a74957f779fc898b2))): {TokenName(13d4d39b83dc7ceef2756422f6b41a01176fcc63c767f9bc2f9cbd112917f75d): 2582056088, TokenName(6524fff49e693803978743da09b95209dd4158828db8e2277ca5cffc29cc274a): 2164982155, TokenName(8bab4483e62a24e056d6972f887d4203ded62d3fe678666df1706512e2251d9b): 1620361746, TokenName(9646bf625ca0578323664e482040061c4754fe26bb2499030a886d1b9f2ad3ea): 533109910, TokenName(9d5b726eb1e1b0642bd54d22f25b82eadf5675fdce754f89704112ae31b4f0a4): 4075031947}}), datum: DatumHash(DatumHash(f7178eff489ef41dbb22ed848e1bc5d9e6293bb548979d5e68a447fb1f1ed8c8)), reference_script: Some(ScriptHash(fb289ea6747fcdca3e7e049bfa455e8faff05017a33cfc2b0543f4e2)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(559d234f19bc9fd6b3c1601b5fab8dffe0c8763abb0e988a76bf5b862b003968), index: 4009668832 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(2e2f1e1cfe2c0bb6515d6d7695b0b7fed5c4eee6290d8110566081e8)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2666152860), transaction_index: TransactionIndex(4264677920), certificate_index: CertificateIndex(3656972724) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(28b906c2469c30a32687e54890d81e4fa305e4dae5a1c6aa904f4481))): {TokenName(588fbbe44d8b4162967e9a644987aa83c235fdc507a8d55e583cd42385b986a9): 381441679, TokenName(737b9a4468ce66070b24dc1ee40675f9aa7b13e002d3e55b30961adc440f9ff2): 3543701530, TokenName(79c76b9c30595cdad3fb62b0e16fe9702433fd0c19992f22a4f087784ec0ba83): 2387693680, TokenName(953f9d0bc5b4777387c0d963e51027cd662b7b6e9157e71e0dbb2517fa6f26af): 1049034266, TokenName(d1911b3f8d1cdbd93977e58d2a20498108d9d6aa537c86d7fb57856f01e42595): 285686768}, NativeToken(MintingPolicyHash(ScriptHash(521075444c4e02a8adeb39630f33204f4aa57a08419c5061a4d7b83c))): {TokenName(43a27d5e26c83ba64631942c4c9a283095cf87742799dc8f89bffd4ae2869253): 3945412173, TokenName(7da8074067919d62193c1523a67853a08666e3841e33ccc80c92168bd8f03b3f): 1773466242, TokenName(8c2304f2ae7992e7028d8c365f3b297914b1d204761c949c07fb6211b4522fae): 2147886411, TokenName(c8ed9873dbfcda2cb149fac2ac367120aa8350c0b9ffed2c7dcaccea65b9230c): 1652301103, TokenName(e1c58e70ae1f74e3dc53068609a983afb2ba2803985e081019cb4007c5a4a42f): 1647130755}, NativeToken(MintingPolicyHash(ScriptHash(9c2d2c5cbded3c9a7376bbe56776f7e72f3fc4e6b535c92f2cf3156c))): {TokenName(5230abbf696d75f31f70900a2fa9110c6ffaaa6810cc83a06b15d1bb3459771a): 1293869912, TokenName(6fdb5bf139e643629c61e44a7376574d55d06b9578ba2e7b963a4d4ebfb0dbd6): 374768536, TokenName(e23691b12dd6f37371fc685cdb07f887bb64c1011f5112ab906e60feeb342523): 3231861304, TokenName(e6ee99a53df32a5b763c19f5b6554edf9280d6003df607da0798cee2fabfef4f): 4159172298, TokenName(eaae34a4b19c419158b9ff98399f76b346555ae862a1d14e3ec2ab4ee1b9087e): 203744017}, NativeToken(MintingPolicyHash(ScriptHash(bd61cbff190876a881619f86d73a5d55264c86b56d02cc948b14bdc5))): {TokenName(3bb69975e72dbb1db6d4b9472c155db4e688cd9dbd816db71cf52c3efa13e0da): 3233720600, TokenName(8724e429a0c490b4c1c761904c0a4649503ba5162f23e3e2900c9263ef8ee348): 907798956, TokenName(ae809a3c48ce61182537914dee7d4ebc3044ef99a9bd889fda1d02a58a2c5412): 3122440309, TokenName(b609ca4c5bcd5c0c9b3aabd65d005a5bbfc1843481dfe549ade9e05ecc931f06): 2322382137, TokenName(f5740705a56e988c151cc398a18ed5837b1b25fe5f0cb49fd539c8d9fb9b958a): 1243817373}, NativeToken(MintingPolicyHash(ScriptHash(d420e0e5f8d8047a710a8f62654f8494c449af745732d6981862a710))): {TokenName(58cc66455a862097a010123985fef3c078ffa10680b0513a63d3712a078db254): 2202239110, TokenName(5e6cb177c2b701c3fa733e533f011dde3000e33a9a13a7ce2880a00e8fedb69e): 3534401538, TokenName(73d08fafff2bb03a4c297fd150437195c24d03328fa0656720ff4d5f078305fe): 3153435883, TokenName(9b58c4e16fbf0b715fc7cfbadbd7bf42329bf7ec6eb5165b7f9d46eb4cfe5e78): 2162236305, TokenName(daadf610c4b72759caf3cc74a68ccb4efd19c8264e0c95d162372669edab8b70): 779747504}}), datum: DatumHash(DatumHash(49d222c0ac35c9b277f1fb5dc57261e12bfd237aecfdb7997e89bc728c0e0db1)), reference_script: Some(ScriptHash(7195783a1c80a32e9bedc6f4c580272033dfc6a564e1b2f1ec439af2)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(5bf01807de9c6759a3040495c46900d6f1e1004f3f4f545929077f875853ddd8), index: 3510854106 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(3397e121372202825c4e91627e122623215a0019b5ad766d5bd3b259))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1e6319017bc6d35870dfbfdeeef73fd9ffb82a10471f02ecda7f30bf))): {TokenName(07ffde46fbb00dcba2284f68b2d54db29792c298a5323da8cd721077db38fcd1): 3007032970, TokenName(8bd025268c55fe46310811f006e3cf45e411bec5a9a312c9d0a1effffd359737): 573362926, TokenName(d4f6b2b4a9b8149905f5df2506054274e2bbcd7e6b337ef47b7e7eae4c23b2be): 1877352224, TokenName(d7a434c0b2a267afdaef4186da1b5163b246cce62c5810d00e52639cee538dce): 3875247984, TokenName(ef0efcd032b2ba178cfe8e6d1ce3488a7342725cb822cd2bf40755d807cf13bb): 2395546946}, NativeToken(MintingPolicyHash(ScriptHash(6096e4d59492507b837e304772ec84dfde49a2257cffc8fb1f9e1ab7))): {TokenName(49ff3246d4e6cd47f30c2574385b525c9c25dbec7a11845406060a37f6ff71d3): 3001461710, TokenName(58b6fcda5fd1478f810fdb91e93d590d563eb52836f0bda948383c82096f1838): 3909115795, TokenName(9f8c2968e3335942e64b8834377acd2e39ff74c49c7398deffa0d60d47b30a4b): 2820312981, TokenName(bf1e3ebc6ca0e89dad0c502bae61e0b80641060d423ccb5b42b16d6e6d6d32b0): 441029893, TokenName(d397907889f6e56e44d1e1db064e617c154c66bdce2ca6122a9b93f5dfe08044): 4227151298}, NativeToken(MintingPolicyHash(ScriptHash(91fc120a6bc95ed35e6d1c3de97437b88c9c0df7a42c3c6633609749))): {TokenName(8a2591f2823d48dfb34b43cd88ec0156ded5d20073cf600a83fbe7d77f90cce7): 906054177, TokenName(b74c12412fbdf969b8e25dcde612cdb30438532a9910300684ffd76c40a8ee28): 654832590, TokenName(d55b8371ced3d49abcd773d6c544eae044629b7f13c8e0649b8fadb243edefb0): 4096721826, TokenName(eb1b0a89d22d1ecfbded6adeecb7288c11b6d7f9f2fdaa9c9aeac2ae9ee4c961): 1432617745, TokenName(fa41f7f80953bd2d6a8f8b48d6de89167ec41048207bca1094fc9ec62badf84c): 3792596042}, NativeToken(MintingPolicyHash(ScriptHash(ca11f8a4aa299ed89410ca59f46056bfba173c541d1b17cee8b3ada8))): {TokenName(34a9842c88047e70dd7ba5f429fae7e4548afdb2c33f30b917b1b7f540460e05): 2855078087, TokenName(70f10b73e86031c44e9d7879f6fde7705357ad25f9d1dfed815bf3c1c57aeaaa): 3190021105, TokenName(8363d689f91d0c6a3ea19860e1f612922cc252b41ebdc58439e78d3f152a6b73): 630956407, TokenName(c2e8b562eb4372ed2e582efa03e416c6a0c072119e15a12bdadb43e87b745564): 1048663251, TokenName(d827c3f71c3f1b0e280af73253cff6ea8bd33f90beabcd15ec326ea8c8c46767): 2217654504}, NativeToken(MintingPolicyHash(ScriptHash(f326f11b693529a85b8c99d504fea277cfd8efd184c21542d61d4cf1))): {TokenName(1e22c06a65b4f4ff321ceea30a50b355c58eb1c2ee7c53f9b8809401c0ebb9fc): 248800710, TokenName(3cc271e8515140ea3fa8a9405a4bf8181b3e5d449856d9d229b9f82fc794e087): 2126954849, TokenName(aa47821195e4b19b9e7a85953c5c117d95207058bdd214c84db24883f78f69a3): 4016464483, TokenName(d0837ad600e0a990eb292b9b5987c8be5b05ed8a8a8234d9d8fc26f91512c420): 4214225111, TokenName(f48663127098c9ce94abbddb78b845cf38055f8e25df2b0f9bece6f6f1589b38): 1601232670}}), datum: DatumHash(DatumHash(04975756d0faf9b1b030c54f60108983d5d33b302e45f940736bc7f96f083087)), reference_script: None } }], reference_inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(df415a517550c6447e0151075818b245d038c64041b32b0e40ade78aa6ae0a45), index: 1616464634 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(5a739f3de0668e36ba44a52f4d49868efcbefe4083311254ac405b08))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(1642185967), transaction_index: TransactionIndex(1760037649), certificate_index: CertificateIndex(663801260) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1f523e96ccd098cd6df5a5564c7bbab3a15dce3b6b6fac5fb174a476))): {TokenName(24ade8d92c0b61f74867695068f41422fbfe4f2ad4af58a029152d31b54e4f0e): 73890963, TokenName(590d57b4d32c0f3ff17a0245ebe29d546081bb18a2540d4c1ca62d9337e9e82d): 432334435, TokenName(83fefc093db994f9f94e58d3b4493da6514e63f4a26d57205d7c9ae9e9999726): 520557240, TokenName(a390bf268fdd95cd2d7a3d4d5a36fefc44746363c0decf8fea06dc1fb810ba07): 2017639615, TokenName(ab2a2d6409074e673ce5d02136d684126ae5081fd056026c762ae682ba6566d3): 3371327882}, NativeToken(MintingPolicyHash(ScriptHash(3ff91680463d13e8658e6622e8cfcbb874a2c1c06b1d3d77a1f01cd7))): {TokenName(341dd49ce78f0d05e07bf7836a9401268df81394d5fb1e63dca1d1b7c624e2a1): 1636164768, TokenName(3ae27a73f159587bdc5e7a337dd8fc8fdbeffd3a83cebabc55dcaf2608e0edfc): 2434315557, TokenName(41b20167c545b9197f967307e9d7d6ce58a173ed9ff283054a3db3c815053428): 1875763754, TokenName(49bd43ec952138899db4dcfbf784ea824037506fef27cd4c2e90b78959b7f365): 3707640368, TokenName(58214c3b2e9efd3ff5b082ba446e879c07807df1c3ee7bbad4d865aa223fec3b): 1984329010}, NativeToken(MintingPolicyHash(ScriptHash(663bfe989ebc5a2c47a3d40882de274a7ad1b999a30c470996e15bea))): {TokenName(25b9e20732e2e4097b00f2b1c708be697d2c9310721413a5452591c104f9804f): 2953456755, TokenName(488ba5b3c0807faaa44f59175a45aad0f7418103355116ceb853c0c72663a78c): 1465740540, TokenName(ec0fd3cf042a8075bb044a640d5ceb1f9916600fc4a26ab577dcaf9388a2aa38): 1111893591, TokenName(f34082bba61c76b0d69b585f8bcbb47cf68b4c7ef6ebbc91b8cc7688b1c02dd9): 895735227, TokenName(fc1c46beecbed4ce405834a512e57e6525431abd9d34e1aab842503a10560df8): 1571903970}, NativeToken(MintingPolicyHash(ScriptHash(8272c6bf89dec17e0c7fa6f89112b83b981546fa5ecd21ed84b3dca8))): {TokenName(1cebb482ef4947b994c00bafdaa4aa940f63c3a9ec059d8667da977fd7376e5f): 3166366252, TokenName(937d23126ad90929c9ec06ad19648fbf8b7dd6ebe2a1fcb2fe00933ce9c476c5): 626618109, TokenName(98eaf07a98270c03afc15f8d0ccc99015c3b8b4c7436732a5834d209cb09b09d): 4274731156, TokenName(da08ead990006575b9a4bc9dafb61a54e3be96284c6b6e5aae55bdf642cd5144): 2040089960, TokenName(f9257d246196b66d06273f31f2e2ff44295b3d4500bd74d93f8c111cbaa1166c): 2184766469}, NativeToken(MintingPolicyHash(ScriptHash(a720ea7e0809c3ac5c713b5087ff3e644933054e60daacdf05ec3664))): {TokenName(4d9c8a991d927f5a3a48e23c6901e33ef40517d951b6f85a13e62738c53cdc88): 728993400, TokenName(6a2e66d1bf469d3700d9cc659789f48d7871af58f20e23d17e7bc4c5993ebbd7): 1636587822, TokenName(923f2410e1a26de90deb9321d6e8131513bd95997317af85c297db0f4ee98c59): 3168320013, TokenName(f4e4dae63403db9b5422f649344e93765b5939fecfebcf865ab43ad189012fd9): 1619540935, TokenName(feba086c2a67091b06654cf2581e0958433bb98a7684bdc45c4382ab0d2287b5): 1112864610}}), datum: DatumHash(DatumHash(aa381003c42ab45f09cde6aa098ba1d100c1102f1a95c03700ce661edc9d2792)), reference_script: Some(ScriptHash(9deca16118132eb6b89f3e97efed1c0017f116c80af86bc0d944b5ee)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(c79f9376867c429a8d6307bf1ba38a78b92ca5099b64d353f2bd5f13d21e47f3), index: 1046223877 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(5ebc06922a39ad8a6d8ddd73e2741e2d5213a188fb27a71d50e4e2bb))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(0b63d507e5a04c9716e3858d22a325a72a5eeee0a6f68a1484a43b2e)))) }, value: Value({Ada: {TokenName(): 1437288783675715623}, NativeToken(MintingPolicyHash(ScriptHash(0074a43a2693b26cffc8757369540be4be08d0e5b83eaf9161269a8e))): {TokenName(03a926192b9f9f59d0fc810a03723010edf357233ac3969bab8cc3266e439a26): 1131830174, TokenName(1b5f59283e42113f6ffd272dca36695f730d9bd0d4bfa37ed38e59d74e87e702): 1440155443, TokenName(2b9455fe459033a04b7b1c1b4838d4bee12154b74ff66b87bfbe89238908d9ab): 4054564423, TokenName(3de84e7135ca95aecc0d000c738094ce096fe02f1b5218e283b69b1c55457463): 737078855, TokenName(7569a3d99a6e907ff8c5656f2a1c6d2e712fadc5cef23a00124dd3e1727126a5): 564960642}, NativeToken(MintingPolicyHash(ScriptHash(a1bd784d3e3023605fb9c95fa2ad4cb30fb915c884551f219c8f33be))): {TokenName(06747581c17ec06e4411dd9ccd2e22816df772f1ca8c97244901d3b43713bc32): 3692834816, TokenName(a246734c268a8dd05ae3a670ad3c6ba506a3957e57c403ca70aa97d033f1e617): 784084324, TokenName(a6e0cb8449baa701071e0f177e348d5ea2044cfc71bd08386c013a4e4c7d0daa): 604805320, TokenName(e799900d7136ec8aea19eeec9ad8a32aa836004cbc95518cb079498cbba1edab): 278927102, TokenName(e89402e1d2b5691a22eaaf2d65b6565aa4b6ffa4a48d2ea8ccbec2e092bb8272): 3634787523}, NativeToken(MintingPolicyHash(ScriptHash(b8e9a529c5cea23ebdaffd63012a782443b1e19aadd5c0b4248b0b47))): {TokenName(00c25213c4b035d4103ff424dc82318beaf1d5c1910f5b132bebb6f29bd16ee3): 594035392, TokenName(3f13e06840cecfc2d1a615b3193d0a3e41c5e9c2ca0cc706c02d15ccb0bd95e1): 3394473675, TokenName(591f635766d756c3295d3cea405f872d31365962f275fb0fd3fed619c796207e): 2482322837, TokenName(6925e28f1645454951027774f31eed7256784b14e51d2bcc14b6cfcb59eba06b): 1270601231, TokenName(dca0e1ba39e0cbf67c07f9ff559bc7bfda83576e2d8319f436e75a9e0d334437): 1732855562}, NativeToken(MintingPolicyHash(ScriptHash(b97d707f5fafb96cdaa3e2a19c39f1f12a8d0081c2e6fea3cceffefb))): {TokenName(173172bccb64ddab80accb733e3d96f10a8d062ecca6859a19644ab94bc6fac0): 3621726364, TokenName(17e742690edb942f790c0f97ca1948fe64d9f575c9d0ef4d423b1f3f0e2c4b8a): 2191440209, TokenName(220eb801bbc5a14fdc4553788f2a9e57197ad2f56afa2030ac36ef591b6d36e0): 1170382379, TokenName(b5570a8fd206cbee80a07e58733deeecde9b7222b8897102fbacc978fb0b3d7d): 3932551032, TokenName(cd897fee77c48f0fa95ee408e2037e2b8ab3bf4c44c5d41a7e9b157c9b17bc3d): 2794123672}, NativeToken(MintingPolicyHash(ScriptHash(f672e09b3595ee889e63e3b9b4023fb5467711b252222ced42783ab5))): {TokenName(1630a8bd2d937d0d2070f26440e057f0e12ceadaa1c34c0460d96b466a004729): 3163183386, TokenName(23a039a307d2e849cdcf47db0a685036424e5ff57730c424b8c45fbada65b3d9): 3199400815, TokenName(29169bc37d2e748eb3600d47ca6bd98eb14e3817d6b7d099d144b52f84c5c93a): 1882230065, TokenName(7ccb634032bbeb2e1c4312c1a1cca9a9bd685f5306f751178f4076a8f37469b7): 4271780163, TokenName(7d3501889609d089e4a1a4274a8854b210d7d9b28e398ed272ad0df770f467b8): 1943632457}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(574dc3fffdf7f3ed60aca80d1ca2a2205b5e3fa9e1a9667091d42dab240bcc43), index: 1737862752 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(15311b4673879ef3dff1bcda3f0af14f1b655cf8de19a8ac983975a0)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(98b3e048de37f98c02a7fd31af92e9db6c20d781b0168c2822bb66c0)))) }, value: Value({Ada: {TokenName(): 16230381661492709578}, NativeToken(MintingPolicyHash(ScriptHash(0d1ceb7ca1121466f7ada249ca1c3e5fcce9d44021140a3ecf3e9cc8))): {TokenName(10fc501c063c1a74a2359a2172841ade6771462fe78d29095f7f0f3266968281): 2582985031, TokenName(3724a231d84bd925d7dabaaf5d94a15f151c2dd54ff9fe58ab199e7509c227aa): 3694507265, TokenName(39480acef125beed8909b29de204983105398b33f33358d86f98777c5451503f): 2205022978, TokenName(3f8c6652c58249e0c35a5da6546f80c5926f1f42b0285ea1d54999079df5f1c4): 3407071085, TokenName(e2b6e1f8e5b0e80c928bc651891b77e4ebe207db7e6c1f537c4bdc9a350bf4f2): 872356174}, NativeToken(MintingPolicyHash(ScriptHash(3c73b484f46bdf1d7bb96e1ae533d3e5aa1d16edd2863fb360fb7b55))): {TokenName(06d12763b7542590703fa42e2e43318df066acd7409fb22739d6515bb0a03d79): 1819498667, TokenName(16fde59d7533b1380be38121eea39be53709450cf2e726050d8c60e47ad62933): 806139923, TokenName(569253efe1ec413410968ef31e432def344eb3d2492a7db72fc3b73d21281755): 1878438217, TokenName(b1ca962fdce4f75ccba251d99f165a789ce31c6d09559a94974b33a03c3a88ae): 4007461623, TokenName(dbaada2cf21170b22e59b6ac3e7a5533d1bf48b34724aa92b62decd929c934f7): 2697836738}, NativeToken(MintingPolicyHash(ScriptHash(46d6ae712b079556715503b24eba3a475eaa94606f8d78feedf2c65f))): {TokenName(18b811a121897ba78680bc39eadbe33a18739aa183a434d59552ae7f24bc32de): 3777657427, TokenName(2326797398f3e07284b60b036c05f6590150cb1038190ca59f55377e206f5ace): 2877689602, TokenName(8362d78368776a9e80d66afa84462c2dbb6a5907d44729ab9279d4dfa723f6c2): 2145995569, TokenName(a9bbd487d4fcdbbe140d117b189d72a27a68c26edd9e8e5e54bf943f29692453): 1808718724, TokenName(cec5091ca8b1c71d5501f5fe589f285b175807b2bef03ad8ccdd457e7b08908d): 3272690649}, NativeToken(MintingPolicyHash(ScriptHash(e3338024c8a5ffb0c28de02741209d83447b3c0675e2eb6d70996a4a))): {TokenName(49ba7085f9ac95c4c599c4d52a861bc5426329867ff6021ab505e3b12ad48aed): 3370763027, TokenName(a764c5883ba2bf19caf1b1aa118a0f2cbca77b2e6bb8870fc2c17e5df8c57c59): 2806304134, TokenName(c43ac5b2c342c26147fc855afcdf90980b35c568dbcc9008372c046ff7de43e4): 1106846568, TokenName(fd898129fba868d557758e7e32ae34c8503d8c62e068a961c115ce212758f392): 339702258, TokenName(ffd9e142dad2df259756fcd01505238c02b9b13e3195c3ba5a8c82d196827c03): 2218489873}, NativeToken(MintingPolicyHash(ScriptHash(f0131469c07a63ea397e90bb085ef69d6cbe8edab961ad5ab1428238))): {TokenName(36412d5b62f159da7013a415d819aa24e04351e112cea03e3c6d150fa50f566f): 3116135450, TokenName(5e3d08814c6f9c2e1429277f69ec637133298007ba5e61c8073c7c4e5dced40e): 311137970, TokenName(7b725f052075c12b6a694ab63685621c6cd87db9cf3a7e4c676c9e4537722e84): 339725338, TokenName(d0063f34929204a161283b38bfe7b86ef20696150d9d0b2dcf5cfae7e57e97b3): 3418255052, TokenName(faa9585105f14e92d29cb2fba076ccc8825eb3a7554d99f1482024539f857023): 2693480752}}), datum: DatumHash(DatumHash(1eaf166dbb0bce4763cfeddc4ed3bd2ef481139d3c151016d768e7efb1f6c02f)), reference_script: Some(ScriptHash(729732baece33f3bc70839225a3b5c905e687e252a1f7012fea33263)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(a6ed2bb95a666a41b3c3fb8839b684effc7fa7bf6e9e54a7b33b46393fd65d66), index: 1928408220 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(4a1e2a6888b02a397b323e2533d0750f671bb4e79bcc85ebc4cdb531)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0fc8fc17b384722cd400d4c54cbd71d5e2a5ac29bb6cc09be8f2f755))): {TokenName(35938b0962341321406231d16c53e72c6bf689d8cc05ca674281ca11f26efb2d): 3055792083, TokenName(59378f9e0eb588818f85c71944354887f2dcee121f80fc5067ac767c42452775): 3070254985, TokenName(95b542ce3eb0392e33535cd223c096a958e4f3763284b1281f9c7e8815d87751): 449976769, TokenName(f1753a148eab554119b5a22104a5c6733122c84e856356e9ee61c8e91495d3e6): 2498916922, TokenName(fbfbcde34f443cabab43678abdbc28f846f39c38122ecce88b12dcbae1b59333): 1101837015}, NativeToken(MintingPolicyHash(ScriptHash(3edddd71eca5f8a70d09324867d7ead9f9d33233e1041810332d15f4))): {TokenName(1da1c3fa4ed1c921b34e069024199c079938272ebfdea23c6baf5b4b1fd613cc): 343871666, TokenName(3056be3c98d4c7bf3034ad5a94dfb0e9de83b7c53743a379e9fb763a92f3cb70): 1496672825, TokenName(566ac02682a92c4e51cbe0b585f70d930999a27bc060dc44bedfec1aeb969318): 2143451717, TokenName(84c4215a802391fa6e881b67ca81645235634c4436e328e2fe9e489c154a71ba): 582051554, TokenName(ab7df4886ecf1c201a5cc0f2c3e11732064c0383c12a45e8284bc6be35552ee9): 2477410850}, NativeToken(MintingPolicyHash(ScriptHash(50aad9b6b1457fb78ebe72a6d0c4c81aa39014a6ada137b03b959a4f))): {TokenName(058767cf5b7fe8aa163ca3d9d3815e3342fbb064f78ba69bc5ef35740a5fac2b): 89405133, TokenName(96bec1ef9b53b4b1bfd65c5c5bd1c751d365a535acd4bb11401a4e4172e83fdc): 1758977106, TokenName(a0f0d60221eb611b192c0318fe46915f41b03839e9922c40bdc1a326483cc36f): 2123971366, TokenName(d4ce842c79fddfe255e81c25bb4189e53e419cf4f74c35d5aaff12c198466456): 823370924, TokenName(d6cc40ab3a5f47dd590dc0bd2a87761f556b9277fc7301dfab8c1dc42327f51b): 614533644}, NativeToken(MintingPolicyHash(ScriptHash(7dc5472beef575dedeba07247adae0b43317f20c7d4f7d29d2ddbd4f))): {TokenName(201daf01c4717c5f43241ef5f170ae2e873bd73aa67444f5c49f3ff1356e9bb6): 1107385662, TokenName(4f55db736a7417bfa461633252e53767be23915fbf2262e308a0f843c6254d8d): 2200142665, TokenName(9028f491cb42e1f58077de7b860148eaba964c356aeb17948f51fc4d1cd05162): 3435285839, TokenName(c0bd6aace9ea7035000bdca54a0f75b94cc500ddb7c72a45e178556ac122e575): 1855012893, TokenName(f86c5c22cc8fc83b9ff9887919723ad0f52c74a35608b4486868d48309d12dcf): 292819744}, NativeToken(MintingPolicyHash(ScriptHash(d1e78e1b55ecc37099b09c19c4e43bc7d80091f6f7eb04a3dfecaf7b))): {TokenName(46fa6f11a1a1804d62e54e99c6008a8d4dbbee7e1ca8ece13723f41b7ae91ae3): 1958321457, TokenName(98b6a889c7f845563a43ae3d7b9b79175178dad15a89aa17857833797e478b2a): 3410658069, TokenName(991a5a44dff719183517b49de66e4e7e5407332e255997d4b00f9f2ca935416a): 2785847006, TokenName(b17a60c7d3b9be063fe04e5d7eac10680d3638a4b7c1d89d1a00b48db679dc1a): 3566753732, TokenName(b6ec271b2023f299b9be96cbb9eb0777f070f50b1c216e1dbc40bc226642bd6a): 495228508}}), datum: None, reference_script: Some(ScriptHash(82634bd33f7891bb389fcbdd6115237f7b65023ee592d3f11d24df1a)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(e8d0512bebc3f22bdcc230f16e701440d7658f93e54483160d65b6f62ab57c29), index: 2071800198 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(dcb280b41876837f300028983756d137e7215df92c08fb9b79f75a86)), staking_credential: None }, value: Value({Ada: {TokenName(): 5624235340638428308}, NativeToken(MintingPolicyHash(ScriptHash(1bac1e9619c62c8feef66128745efbb22d6f0a64aa631f461368ca63))): {TokenName(044bf02b9bcc5f707eaee855f0bc004a381b0d824bbab801f6d8c29fb58c9ee0): 3379296639, TokenName(36561fe689fba2eb8293e2cb270b3eaf53aeb390cf54f4f601f4dc006f8dbc14): 1047494172, TokenName(76b3183a61ea1fe69c0849452b46c6fd89d1a73e2f53de79bb6dd5d232dd4d88): 1290674388, TokenName(ca9f04a8a1510e023d8c044e4795ca4acb6596969280e22c37575e9e89c43cd4): 353384854, TokenName(ea41a6b1405d779ff6f61c6c8bbc8e0b9cda6bbf0412bc578e481da04676167f): 3704700847}, NativeToken(MintingPolicyHash(ScriptHash(1cd2215b34584d4dda4bab887b76f94d89de01a13abb61e5a9650528))): {TokenName(321a8831d15a104684ded815355bcf613f029df63346b4526b446880321c7a11): 2279194748, TokenName(52c417351a1782ae31c242a4cea1422f21279745f58b5e86351a755c5d049c74): 447980304, TokenName(58f95e1ad406bffc94e98d115ed4143f6da0fc5020344922e2d1d330c4ed4e32): 1746535223, TokenName(89887ad74d75176efcfd911b64d5e91155a4ae30fddf75b3074fbf215fbd4e4b): 3134212159, TokenName(921074537b962c105e1bc93216b3206fdfdf532c9a5f84f2691d5de18b27bd54): 495942185}, NativeToken(MintingPolicyHash(ScriptHash(25cd2e487a68d1714489f0bd1a74544ff02faa453ee82a18bbc666b9))): {TokenName(2b60bb3694f2894cd0a0a8b384c54cff4dd4e742998634bb27476bda6609f533): 2655304319, TokenName(3c86f4af2e89fddc5617cdde51d98dcd92fb90dbe3d97c7399e52e99f758ae73): 2837538083, TokenName(cf8ff5e5069ed337f0b84eca5b5ca2245db5dd7a3f1f5876d45ad887e306489f): 3133768452, TokenName(e870a213c3bf8136803d4a89c5562527828ee169d5a656bbe9f9083365e7216e): 1159067530, TokenName(ea558ec6232b2e6a59f3b92b937c9448f9d37ff4da3329e6b7291b6b3e1776fa): 538535041}, NativeToken(MintingPolicyHash(ScriptHash(87bd1e399ef87a366c2f862af586f7a88f07966a2e0688a2ef75c166))): {TokenName(02c2dbd555cc125cafd605272dbf268cca09067dfefdaec562ad9e1f31bdb59b): 1031204712, TokenName(19d88465a294458f0e949947be5bdfe74f6ad0e52aa92d7e69d714d88be82509): 1211739728, TokenName(3090a67fba097b8f60b320ba8a0eb0c1b73d1c37ef1a9e9888a50b5a9dc948ba): 2089163239, TokenName(74f2a85523073b48388f8649d1981d46bda39db4aa82ff1775b53ab686b83ff6): 2360565832, TokenName(ed16ac0eeae5444117899b1a858abbe2b9773633165a15d33b94725a0138dca6): 434838110}, NativeToken(MintingPolicyHash(ScriptHash(e1d315f27b5cd3cbe257dd6503679813d062d5c657841c5cf9c70367))): {TokenName(0adb1377740dfbb286c40b30b42982ea96b55b2d1bdc45486b72eb361d27429b): 548348522, TokenName(62e52135eb6d417910f8f8a88e75c9d6e6dc681f555633c9e25320305a02a46b): 3899433438, TokenName(6d83cc65bbea2df50bdd3ec930330892797278df582d8479dfa624f3a63cc412): 1029726376, TokenName(d80a519c322837737f5a3a91920577f3c39d398ba4b78626e032be10fe8ba3a2): 284355618, TokenName(e71556ea487ef26bfbcecbbc1e2d5b51cebc06b7a2f3b87f9ba8e70cafb92700): 2559183258}}), datum: InlineDatum(Datum(Integer(-9956574158313405922))), reference_script: Some(ScriptHash(52cee8e61aab51d5f7609891697546ac7d87eeed93c2c6dc3acd04ed)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9c58589c8daea6e0b0409c4f7ad0b5f81c77da6ea341f3f41bc72905)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(3059909667), transaction_index: TransactionIndex(289629170), certificate_index: CertificateIndex(418984329) })) }, value: Value({Ada: {TokenName(): 1778766396015761356}, NativeToken(MintingPolicyHash(ScriptHash(1197c6b68c6ea8cc3bd9c65e839851e3da58a6361c76251bc74117bb))): {TokenName(321d367c79a4aceaa2e8bc758200abe1f124f537e911df4fb33b4445f92a4900): 3508830932, TokenName(64bebe7bd1091a3eb2c1c8434ab3a20920e5564d1bcd8dc0df82d7eef7dbfc86): 790197286, TokenName(6bb8ac3d79705dd2ee39d16cc1c4a10b8ce210cab7cd570da8e9ae0cf331bdf8): 3371814343, TokenName(aee720de84015b51f7e36d957c7f6fe676da8baa71343c84fe55a1696714218c): 1578127368, TokenName(db14a6aa9dc0f0d2cb7610fdec3fb3b75a5a91c51cf8b31f8beaaf69436ca212): 3210872368}, NativeToken(MintingPolicyHash(ScriptHash(2a5ddd5284b67cedbbc0b9542944c54fd596e6a43d481de474ef0167))): {TokenName(1f8804ad5e8d32d68ba6e80dc84093fb057f25df3966741a3cefd239f779a289): 2829558214, TokenName(c1cae4a50ab84144428a9000d3e3fb22ba871982a53722ee99d65a41dbf2eb46): 1823425964, TokenName(c1fabaf56e2d6b9b575e2e66a1179a86e36660ec9acf91371cfb6d9c09490a32): 550930646, TokenName(c387c1bced5c13129aca014db0288e2244027e119d113d09a763c350612cdc67): 4216692701, TokenName(f4fc067b6a112f17b33008aec89995b5bf82a7d713d7310d655665ba75b0a0d8): 2786331769}, NativeToken(MintingPolicyHash(ScriptHash(35ba236db90c96c3c68b24a811395ecec20ad533dd5bc7a1a5e201da))): {TokenName(341e212c607383fab014eedb084bee56f2748007830aef3de482b12435f3db07): 3512203437, TokenName(562569975b624cf11e43043c032a114f8c7bb1d599a42a71481b86093e1234c3): 3589545001, TokenName(79dcb3e70bc3c6d22526a623d219c8bb0de1a8dcb45997a41a78b1a760e598bc): 3627015719, TokenName(a72a5e390b047db8f424664553f2a2f66914a974d7d5ad613f6e673e0b66b46f): 3523736973, TokenName(b5a42eeac1876b471fed880f36d92f4039dc906d2d518bf44122382b057088ed): 645553009}, NativeToken(MintingPolicyHash(ScriptHash(60c58a89772f3f858ca9ff76f1ec016afba91f196ff136a65439928f))): {TokenName(2362bad679a7ef42722ed43dbaebcad84b37d0054f9c64222d5d791cb4002e65): 2033594753, TokenName(48a009b659e52be6a9d9965f2f17db6f67203af28f5d0c92a21a1a0cb1ec7bf8): 598407792, TokenName(73989a41f7a31ce95ed23c1194448f66f5ca8fbd22f3c9fa83aeb7f3906167eb): 4045763823, TokenName(814d6964cd4464d1ab56f8e37105c739074096e16f0603d6889390431f362326): 2385763296, TokenName(e20e4a40482613712852f8299166bfcb350d3df88ac203fe43463558ef580228): 3226393680}, NativeToken(MintingPolicyHash(ScriptHash(b44b437978704052f799c0dc85035e0a00418d70341e4b215131b99b))): {TokenName(8a840ac55856e507341465ba66a1b23c6ae7fba76c73d5fdb415cae1eb8853fe): 2344408113, TokenName(8d81c723280fc3c49b8a09ac006fdca235cc712d764ccc4b2ac973c7cb3b067e): 3349808160, TokenName(b3bc1bafa4c4310fba9a68a081e692371d8c7b735bd62d84c1d336640fcb08e3): 4201247644, TokenName(d2fd15449c1b0168df70370038ca3f7b4ce291be306af4ca47672e6d891d824f): 3290109883, TokenName(d6e4c6a99371599e79f9412425696f389808809c52793ea63cd860fdf0742c59): 3890841551}}), datum: None, reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(0faca775bb455e5e7201dc2e15b8419c60b5af395a0ca6458a4f45c3))), staking_credential: None }, value: Value({Ada: {TokenName(): 17191670480344166570}, NativeToken(MintingPolicyHash(ScriptHash(13b616f498a53cd6d76ff003cad8dfbfb943862699d6ae1dd2f6d634))): {TokenName(1461c1038be0d7c206f85ea0b74bfe9dc2ee27274ed6712dd56cffb7898c7696): 1324640563, TokenName(198bad8abb024b7a1eb03cc65b6809f546b0396a90251df6c6b754be3aba7b84): 1867992264, TokenName(534228e3eff9fb336aa0367983f54199fd331220b4218d01b8123a981a80495b): 89428173, TokenName(97801264b4899a0a218373e01685c6dd4a9434a01ece135db94d15c6ee25d67d): 359436282, TokenName(bbfd804238fb1c4d9cb616ce09448145efb2a2dd549fdb36debf6bdbe4833e4e): 4275275621}, NativeToken(MintingPolicyHash(ScriptHash(8dbafc2e9759cc031dda7d36617b7e05560f192a2c20f2af78fcd76f))): {TokenName(55a428280d87a1eaf60a893a0f60fd237400df3466b7ce5802487bd2de8163dd): 967396829, TokenName(8499c0da34c51e108b13d1c676e3a9c6856d138be064c386570d11099bb46253): 3160710516, TokenName(9a727bda26b5febcbdf4b453b59224649c413bdad806a554698e8405547d7bd8): 1816487296, TokenName(9f906cc1e3fb83b442d8a23944015b45f4b6d71ed71c1e81875ca77e9050a0bc): 2866195868, TokenName(ee0afd07c03db18cc80f8d773cb25bac7165e63b2a6c68462d0b9247553b831c): 1570877030}, NativeToken(MintingPolicyHash(ScriptHash(a251260a0b82b0d05a91ed969ef66eee43699da7191faa844dba8425))): {TokenName(4ee98a99dea47d7d7284bad0fdd29a0723f769d63c05806134739506a2021b89): 2346037911, TokenName(65dbf707d2322852c658be02d749b38c59401e0409e300ddde0d12a34447b6ab): 1315013433, TokenName(6d0db7a763a6f24695afee481a6416327c0568c9fe2689568a04d332e54d9881): 1499516955, TokenName(7b874bf3977c665b77d50cc4eb476fba32dffa6e2b71f5d9d5703a28e228f5a7): 580680245, TokenName(8d36fd16080e83ceb493dee8288cfb8bfb79aad0343111b1709d617d13927918): 3616164132}, NativeToken(MintingPolicyHash(ScriptHash(a3cd9d960a5361d08a68a62b391bce02f40db08014e790fc50237226))): {TokenName(01ef3f234dd923cdec095839be17822c67ef030c04b575d9e095e39d897a434d): 103555697, TokenName(2821f1e8c7e4f204bb4fbcc85a963902874039f8dc2ff00b703954e3393da340): 1155791812, TokenName(4fa210c049dc8d7da88885b68dc0eecb2fef421fbf3415ad37eea80d10cfe43c): 398998325, TokenName(882f0a31380fd236fb3a37d2d265ee00435de875bed57f9535ec842d11c1f1fc): 2842051405, TokenName(98b2bea36a9a055d2c13012ffde883f02876d1a9c232ec7b400d0c19ef209db2): 626549601}, NativeToken(MintingPolicyHash(ScriptHash(da54406e8a31e3bec9e2902f116a036b657cd4edcdbf1abafecdaa15))): {TokenName(00ded037e41a50f777d585bfa6d5c455aecb2d44ba4106d23537b9e214d2ecea): 2915435893, TokenName(0971f6078400812c5e84f8f3b2dda6442b60d4342955c1262a8668e10cd7e84a): 4088687709, TokenName(acb5df938c0510ebcdd443d28e98fb4d3ca3b88a3f5f80147cfecadeedfb6d17): 1175270776, TokenName(adadbbdc61b5e5553fa34ff6fe9ad6c6bddc9083017300ae994a1cdd1bf277b3): 225174560, TokenName(b5ac403a4a9c86760b29815d564fb7835acb9c24dedd2ae20abf3ced5ee2627e): 3526364138}}), datum: DatumHash(DatumHash(1f1cb46dde0b2e062f29bdd4eaf704590dfd4e75a24a594fccd6efdcad82c28b)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9a3bc0719ea5cefb5c19d499e7f789f208d186900d5af551f968ef90)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(09d8289290e5a43c238a7bd3e4ca9c165fc96ece0d43acfded07d0a9))): {TokenName(003f5993d9e6be11b15e094030b592e24fc6bd70e3bb475fc1e6a9f8a1480449): 1815528716, TokenName(7ad73078397aa3477623017b9a3264df30a68b40d65096e13c9af7555f083cef): 1229163749, TokenName(7dbfeae24bca1701c87c91c25697a06bf478e35bcfa0c2444e93ebc20480ab68): 1382274669, TokenName(88b26817e33204a94f0898c894cbdb6970f41a699c4ee2bd73749b01659302f6): 411281757, TokenName(c089595ea7ac47a21b89c9383af436dcdcd6a93373fc42bd9f2cb5f6e0d6c7ca): 717514761}, NativeToken(MintingPolicyHash(ScriptHash(86f55c87fdd257e4bacf0136c5d28ea39d360f855c7e5cf6f242bd45))): {TokenName(23b21e6cdfcd23c5a999b219f085f2053aea2dea8bae3e5c75c36fe5e2408a9e): 2338625822, TokenName(4a7bf08cd87cd3bac81e17ec6552ebad9d2c140f70a39c0bb5745a0220ba8146): 3024758461, TokenName(5456d402fbfe36c7af4caf42fdd39e6f4a0aa1661c0fa10fc0723f8271bf89ef): 2136873665, TokenName(998f379a2407323ce62513463f459530daab36205d0aae750d86978d29660cee): 1783137114, TokenName(c24ae0cf5df8dedf4dec6f0112c6d0dc4adafc90159bf9651efc7fa2c701de33): 2718346328}, NativeToken(MintingPolicyHash(ScriptHash(8e81ab149961745cf535f1cdc0cc81950d076f4e98fa40847ed43100))): {TokenName(176b0db781b4cdfc59c2c2e4fb22733e1c228bf81107c7eff14d8213a1a00a74): 3843140964, TokenName(2d47eb236d7f4f8f422a27329df18b7c9d52202528be053c666eb9a968a357fb): 2710449835, TokenName(3779482f325b3889e3ba4387017bb05bcbafe02ed258f48363d42bee29fbf693): 3203306923, TokenName(4c97ee670e6061f0ef51987ea97c630c026c3895466e0e94db71a40bad69e112): 1343640868, TokenName(9bde7c9632b4f7bc5a0578468e510d860359416cc378d8580f82042bd2d76e23): 1013243267}, NativeToken(MintingPolicyHash(ScriptHash(b55a221780d89ed4cfe3446500f37676f8862a18d5fe9ffd029e6b54))): {TokenName(2faea7bb72d2f4f42f421ca3474f57ed7a0bc49bfe50e7fe6b4aa0bfcd7559f6): 2052560625, TokenName(5f55ff60553ee1d98dc86caa26f9f54feb69183fe583e9137bb2aec2a072c000): 3241834987, TokenName(61c6b54180c029682f51b1b918d3fc22b6bc053964b6d35801f59271a752dde5): 3108922155, TokenName(7e5a58d41c5b2354da63977dc1d505ebbad9ba92badc235cc74d4f9f3e4b7849): 349744316, TokenName(81b1b4d3f19c1e926398d6509d7459c1b4b4a5e3f487e4b152ff11f495ce0d6d): 2585552279}, NativeToken(MintingPolicyHash(ScriptHash(f95aaaf4f41f58473d9950d942dd875f619a55983bf4d437b18ee209))): {TokenName(33542a248239c86bc6a840b57eee80168862a706ef23a2aee3df3799f0a3ffab): 424813100, TokenName(59f9c15b98b54f119212d7828dee1b9c550fff5a2f9611bdac7edfeb8081bd07): 852321931, TokenName(a4b10c965633930f1c7e035b8c6aa2c3b4a8ccc7aa90486054ab85f355d87013): 902256490, TokenName(cb10703e6869e04bd24c9aaa966e90077ab20f5693703afeb75954372d684b54): 2343434831, TokenName(e306aa8b0e176caf6d36fdf9133ca07913a7e1166bc235f9b3f44be504fe033e): 3855295454}}), datum: None, reference_script: Some(ScriptHash(30f531f0d8f059a6b00bb17e95a7c718959fa751558f44a327857b25)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(ec761eea39c340a69c6fb3eaa372aeaf800555638c910e1e025c9a7d))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(03ac18eb0e12b53579997623a8f72fb3c429c5ebf5a41a4ccdd21d70))): {TokenName(19ab57f5fa488fc110644ebbf08da6fcd4b7f1b544f38da09b040f8739bbbedb): 2518964382, TokenName(62416073bdb421c7242bb19a546771a2b0409daaa66292d95c1cb33bc8943f8d): 1656408066, TokenName(a151df70ea8442edcebbde742098385809fad19a7b5ca9a467352a7ca1958143): 3908199478, TokenName(b397d9094ca4d8ac4c5890f63535cc519961a2fb6ed2ae85f85762d71ee39bd3): 1352267552, TokenName(d9e7c9df00f284849ccf4a99facb9e93a3dd6086747da76aa8676b4804bdf618): 2861143482}, NativeToken(MintingPolicyHash(ScriptHash(91fa53087d9026ebf8829416fcbfa3cba44ff5fd2de2cbf4dae4c766))): {TokenName(04463079dbfede339bd942f061f977f96d29eb8dd332c95ba7a83fac6dfae3d0): 144548287, TokenName(0924d74204259a14f3d79dcc4c562a9c6ab0117e6a27a88f7bfa7b739fa96e07): 3509554855, TokenName(6f27b648acdaa4746354b892be555c591747a0cd6f913548cc2473e4eee6f3e0): 1675798510, TokenName(8b5353741929fce6b960b675ae375bf2e94ce5f82889c7346c29b591054cdfad): 3578297260, TokenName(bde71f055d9c5f0286f337a6b82f6bf66e29aa8d5a5f5bf5302477be2aadf3c2): 608042687}, NativeToken(MintingPolicyHash(ScriptHash(b9064d7a8c2a1110a531d561d7b6bf7337b4e1960fc29a4eb8eafeba))): {TokenName(21056bad64decded64532114b0a37e8aa53f6149b07cf63064b0ab36a2cffd8b): 2632119827, TokenName(30ea01ce043be88cd6b868c2c7ff30cd91c2f17c9dffc0a53d264d6ea9528011): 1463337029, TokenName(456a14b9402437b057f06aef1918df492c47449f647845b9195042f40edde7d8): 2064017649, TokenName(648370902f82759dc8d0c3bca60a64b846b69e5334893a8458c1c64286ba6403): 3348192523, TokenName(bbbd9e146deee40b156040457e7b754dccd7c9a0867e6414980422b5e227049e): 2358894817}, NativeToken(MintingPolicyHash(ScriptHash(da4e9f3ddfe199c006d0f9ab721925c22c30b7c8772e7d0c230baf37))): {TokenName(620317ce5c7b640b464c7f273df9901b8472d8a6716d31977174050fdc3eaa16): 2076682926, TokenName(a3f5deaba8007f644a26988f6cda2a4d809799eab21325b21c2fb6fdce086f9e): 2412943953, TokenName(c5030f54495f3701c9e2887469a15ceaea3cdc15bb40f39906bc831019ed31f7): 615192849, TokenName(d5c5be324bb653d422258215ea5443be65d9ccbcea6c5cd2b3b5631bb4725439): 1142290255, TokenName(f7dc7edf6ea29fddd77a29324effeee617d2d45432ee9cf2cddc6d17382d9a26): 880307032}, NativeToken(MintingPolicyHash(ScriptHash(f2c054a52cfba3b2a48a2f5289be9a77e198260ec32064194a2b7998))): {TokenName(2213ca331cf1f07dde0a0718f74b63e2ecc6edb3d215eaa2b792558e65ee5447): 4208271782, TokenName(4b29dc7827b40bfa065d39957ec18f96bfe9f58dd0f5c076aa5324210e733521): 2669906136, TokenName(6d98fe0599f37e23d774f1a6cd209df36f85483c03ca564a22589144b2f9e914): 3749525743, TokenName(a6c0242a0756a62ec28075ec9bafe4059a5adb9cb92c3cc76bd8bf3a8b983e3d): 3155040882, TokenName(ec1605860834af7b073dc112ada90e6ab530c5ab9fdc1fbcddc3dab021d25137): 69909880}}), datum: DatumHash(DatumHash(24a7af37e514f61fb4bdc1d22c1ee8ececb9afdf8aac797571b5704c237380db)), reference_script: Some(ScriptHash(631d2a7109fc05b54a600e1172cbfcff9ef662b4883266c285a2283f)) }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(08627132179484c51bb35060102f121a0735f61f8d1e42c220dfe487)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1efa734d67168fbc8d93170f7fc65a9870f8f43b212b0cbd57295751))): {TokenName(17268d28e91d74342d4991fa12c3bae621a7af526238e3095be461fa9d26e46b): 2570813478, TokenName(36b28819d1ca7ce52536c5cf0a9cca828f96644b7bb41bc6d0d4467537bebc8d): 3393761679, TokenName(7cdd0baf63bf3b26b4bf8069bca24fe336646bf65c66646568efa80df3b90560): 418721239, TokenName(8a2d4ec9912b245c011791cb914e9904b29c7466f51fd45dfe07f4259a694639): 4033126661, TokenName(f768447ba0fbab3ba8ac8385859a0d89c573706179ff8c7bc41dd1dbaf3cc015): 1275518025}, NativeToken(MintingPolicyHash(ScriptHash(30b958c36b3e9506471e962ac0d6ca6409cc26940e79c2f17063d43b))): {TokenName(0af86696aee816f944107fc689dae0ed62da4f78b7a8eba25af007e366682ab8): 4102103124, TokenName(42d0dfee36a8fdb7a522ce21366da8e11f54e79b1ecbd8f4e36481adaab5b395): 3750284091, TokenName(60c7cf7a2b4bc6cf0ebb20a6faf7585d323649b72f8a912ef213c7d93e317c5c): 3130665970, TokenName(71419f4cf1b8686ca6af11192ac643f8617e2dd3628748654f0a864c9c9ceddb): 3747489957, TokenName(7d4d39214d8ebb33e3c4c4f1b997274d6f8d93bce93fec7df8c5c2943ddc5899): 2707795912}, NativeToken(MintingPolicyHash(ScriptHash(3d5f6d8bb70891a015ce82c8b7d55638f61ecf52b7ee2ac12f557a02))): {TokenName(148a2348d53afc797ffdb9df38001bae9000793ac8dc60804e745b8a87404a9e): 675953931, TokenName(2999da457948714f1ad9c33bd540ef5e4db4725a3789d7532f3abe87e9ebfcff): 1144848020, TokenName(3ab918add85b549820719f580aa09e5cef6d82b1e447fb5b0a2200d75550ad1a): 3837268611, TokenName(4ad0746080153f2099046d58f94349e051314a13dcef24add1027f15e53d1916): 1350699108, TokenName(6760b9ff5ecdb761b4240bfb67764d9f10f3171b738611945a7ccf0d0c55ef1f): 1646471413}, NativeToken(MintingPolicyHash(ScriptHash(45e3ff091c274f7dab3fc0b6bc8522150eae804573e65d4060a82458))): {TokenName(89004b31dcee69f16fee1d1c14f339e969b5f8e5622042e2ea6a60fc18c1fd6f): 3535052531, TokenName(b0514600cdee8a5c64d4c5f94f232e2ad5cd7bfbb3705f18e52b2aa3de278f57): 3551698795, TokenName(b71760084577c9f984a3801b1c549ba7bea5699da16e9a3fd6b88ae2824d18c5): 4130989591, TokenName(bbedeb8f323991e258dfc55530ba7ba8c66c572c83da45fb4e64d85bec43baf4): 3803686025, TokenName(f36ddf2e0ac6ff05d34598255d1773c22f42ee976c817ee63678962a42653f5c): 2086145863}, NativeToken(MintingPolicyHash(ScriptHash(bdc5fdddde9806d91f7da86b3abcf56400aaaee4e1713f6ac3791ce9))): {TokenName(383b831d85af8a481a7d3eb6e755fc66a307810bb6a8c7cd4408aedc7a169729): 1587342539, TokenName(84dd802f39b9420b27b80b0008df3edf69647bd075ab1fe7454c6a6ddf9e7c7f): 4029852972, TokenName(8d2592f85c7d81c201b05cc8b5848a3c881caa9266744023d76df570460b18cf): 2123956503, TokenName(db8016743c4af9aeb82ba48cd4b92a35e674e9f2a6e5d3e408b49c044e625843): 1811830174, TokenName(e78f7a8668cafe8fb9eb907d11310e2e7a2c91586c7e65f26b4e4e1edd6594e0): 1199343382}}), datum: None, reference_script: Some(ScriptHash(dd3246fe6e30d877cdb57609b8756a93ea209cf83d17ee3e549e00b5)) }], fee: Value({NativeToken(MintingPolicyHash(ScriptHash(2f9863727367b0d7e2acc0779f9c4d7276a3ce14434168e939788955))): {TokenName(429a3f398cd615e887111585b6e80098cfaeaf114b041ed632e59b9241198a30): 1555683774, TokenName(4d47642d7314dfebbc8e604fdc780f696363ad680403355e87ae4da7816b9638): 3592907140, TokenName(4dbfdfa0dd57671ad6d070e511f3dcea18f6345278f5236b0f0a760071b5aca7): 3408980460, TokenName(562cb1afdd67f13de123f96ff4a329e164b1d1fde34e64c5e000bacf443d2b5c): 3168086864, TokenName(aa5f81ea275a4b5d4541c1593376bb4b6daa83b4ffcb00be9e9e07070ee8d323): 169981035}, NativeToken(MintingPolicyHash(ScriptHash(3a4df10551937e229f522b733111206a4c59a2388628a8749004108c))): {TokenName(187e6fde82358b63c03451b8dd1361fc53a2b6905303bb9632013cc1be34ab5e): 734045897, TokenName(3403e18344cfbb6653951c9edba43e1aaf427c9f5a635db3aeb96079c556ea45): 4010288560, TokenName(bb520dd935e854714c3167fcf8b605928c56f1d087f26440593b67dce8264ebe): 989031355, TokenName(d5f9e314b5460128827a0dbf88b0fe21df985ea3f3405461fb5b6d3a0d1b5d2a): 2046624902, TokenName(e882a0be331fcc394f7dc1ac99e729972d51b9d55aaa1cb7f97341cae75450d7): 273147440}, NativeToken(MintingPolicyHash(ScriptHash(68110ef703304ae479c444a6201c03997cfc10b6295f998274dbf2ea))): {TokenName(06f4266e7f2c030891cbb9ed55bd1f0c3fd41f54c0063757f5070977f4df742a): 895390465, TokenName(538d1edde8cdcbcff022266c300676a2deaf83659c1b51737340585536ad0076): 1716482888, TokenName(62b19a0454f9c2ba8f44bf1bc53bbfc3856d11b30c9f0958f2fdfe6e7973fe51): 1173906700, TokenName(a34f088141c5c4bee0c735d8bded3da2122c6279c33fcfe32cf900c0f4c5cd5c): 1478004184, TokenName(cfb00dd9c985a6c5cee0444bbcf147fc7afc6e05c2d85fbed2833ae410e3efb8): 3063484456}, NativeToken(MintingPolicyHash(ScriptHash(9d0fe31ab7e3f2f7406e878e08376aff36e10dfd56844f8981ea3a66))): {TokenName(132efcfbae23f5c18a0ffa9bb7b258ee701abb3797f38a1097dc6851308986b9): 985486808, TokenName(24a8b01676fdbc399e6a1589e6a7bb33d766395c9d78da8d113d451201d54690): 3241903114, TokenName(598c739a09af4bb634c708c30fdd6fc34cd633f5bcd1a7d6dd7731f83c5c98e0): 3005678126, TokenName(a8b0b1e5142cf0f1cac3f104fdcad8dc55dd65800ef64d1b6e57829a8891cb4d): 2988582047, TokenName(c80a9edb35ff6b5fe9292140e284f3b110034ac1cea95bef2eb2a4c1849b4dd9): 553307105}, NativeToken(MintingPolicyHash(ScriptHash(b2fbfbf224eb9cfc223bd3ed11f6c0a4cb4375f5f4cfb7e34754a613))): {TokenName(1d14511e247931cb6733fede871fb50c5b889a8191b26d534ea2420e6b5fb793): 4043197660, TokenName(49617ae47d57e3ff6dd8129b181f3f4bda7df20219a6be2cd2265c23449a96d9): 273104966, TokenName(6288fbea5a0135345990f9f79adac3f81b0644e8e5175f6242aab3f387084237): 66366596, TokenName(72b6c30b1ee0e44aec201e0361e8e3df1e18ba238d8aa6ddc4b0817755d11b8d): 2062758746, TokenName(83622b675752a919f2aa1ff4c68ed11354374b2abebb1029ad88f1a93a831fb4): 1099160643}}), mint: Value({Ada: {TokenName(): 4104180352706495912}, NativeToken(MintingPolicyHash(ScriptHash(1a5eb483f29e60cf94d6db289237c92aefb6f00cd17116ee999734b9))): {TokenName(25da6b3e9e675b6a8bdd597de4ac48c9b3a880ac5ccc63acd65cf62f27f9008c): 1231233814, TokenName(427420e13c51ebd62c14bc0efff31f770328482a204911d1e6b32e8a6e3146d4): 1996334957, TokenName(710e81cc94a0cbdf08b522ca8e02ba017b2c57ed3ee360b0bba12f1dd39afbda): 2661078626, TokenName(ded843f4173fd92c5d1b6c343da011cc5373eaebd74046b8effa159b95b0b4fc): 399673598, TokenName(fed348c8726ce77dc3e317ead26f820379e5eb998e3215a6c45aac9eaa1434ea): 4151868046}, NativeToken(MintingPolicyHash(ScriptHash(1cf98e68f452aa7d791c36d9495f37dd9d98a44cd70deb233aab4a8c))): {TokenName(488e54b0111d8ab0110f091a930ab1a3bf29648f15e9ce291b445fa74c271e4c): 427903071, TokenName(96744d9e07184dc82d51b499e984838834744a02a59d6d5f0b213e318936cb85): 1997947289, TokenName(9b6160513350d1f3cd0bc865c76ac9ff4f17b0157220d569226c7a10b636a24b): 669481020, TokenName(bb3a60a8f39d1df1afd753eeeea00993bee72535f3ccdb5cdc3911ec1cc31021): 4067912973, TokenName(d2adcb9b62c6646a8653c822e91b87de8a9abcbac84b799b808ef43639a4b016): 3918566276}, NativeToken(MintingPolicyHash(ScriptHash(870ecba83cde3dfd018ea32d685cb450d2d4295f5cb4073f29bafa9a))): {TokenName(0403f0c9cb67117c895168ae75deb3bbfb9c9d13b43a2ecfef164b3c9cb7a855): 2905897182, TokenName(1f6d139cd673123d10495454fbbba2d3b72c8bf630011164b8ddb16e078808e7): 2763742922, TokenName(9b4c9f57c613b8dc4ccdaa59ad95dbf3bbafecc90821b014f4bf77211b2799fa): 2647325274, TokenName(d7a183b7753afe71a94ffc4b9e1f23c8f59fa916ed981127f9b2741a24243acf): 1630302619, TokenName(fb047eb4525d6ef3550b3e87597cebdadf66dfb547dc23250ffc478ee03e40f5): 2645150031}, NativeToken(MintingPolicyHash(ScriptHash(a186daa8e4f866e46d68808ad115232a5ee746fd0875bfb18ac1b8d7))): {TokenName(7a134f9e9c448fe6e97557fd36f3d7a81639d04e609bce6dc37d4a8257596a20): 149746960, TokenName(7bd98296d4c5a45f14e45f1ef70b44e323e1a4a342d5950048ad28ed102bbfd2): 3131521095, TokenName(ac9aa0564b12e5ea103a569c59713d6ea1bc9fb890a618e39a87597121d3be55): 3147076479, TokenName(afc3bec871cdcf99569a69ac50dca88cc75eec498d1d1c269e896fda014a1c76): 258148948, TokenName(b5348d158cb92e19b81c56990d7ee1e705abc19a3a422d77d81153ea5832ebb9): 713428795}, NativeToken(MintingPolicyHash(ScriptHash(c92bdff49727138c31cb3d49176e054816447dbbc79d39f189f8f676))): {TokenName(153334516784cb259748056bb312cc5416c04e15c36db4fe9cc2336b21ab4253): 835283426, TokenName(591e68815b2c0f8d66418a11fd031d6bfa1e1c64587d7988963fcb158dd6f8be): 3356235553, TokenName(8b9065fa54273dacc3752b3a703daeeefe6dcba97e0a9db43c97fca1224b4858): 3794081327, TokenName(c9401e06d8dcdd84d9556d06589915eaadef20ce3897ebc5df76607b06b61435): 1689084015, TokenName(f944a8b7e0c7f94173f35a1d7a0e4c51174f9ac89e20f71df3aded3db66feffc): 2290874670}}), d_cert: [DelegRegKey(Pointer(ChainPointer { slot_number: Slot(1255069606), transaction_index: TransactionIndex(3060645162), certificate_index: CertificateIndex(1133172045) })), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(2058101779), transaction_index: TransactionIndex(2683260422), certificate_index: CertificateIndex(2332862830) })), DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(2949232829), transaction_index: TransactionIndex(2376444952), certificate_index: CertificateIndex(1584659227) })), Mir, PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(56a7cd13edc88705dcc4e7b5c3a4be407e4cc15556fd31ff61da3de7)), 1704978752)], wdrl: AssocMap([(Pointer(ChainPointer { slot_number: Slot(2518930256), transaction_index: TransactionIndex(3594332237), certificate_index: CertificateIndex(832943901) }), 283529990), (Hash(Script(ValidatorHash(ScriptHash(99b971201b74682b3aec8d3599b5f7b04f69787ae11b56381e2e89a8)))), 1315944064), (Hash(PubKey(Ed25519PubKeyHash(8ee1d52a365940ccd463dd7e9c5ede976637263358db336f85ef20c6))), 697469854), (Pointer(ChainPointer { slot_number: Slot(1144497856), transaction_index: TransactionIndex(3973812288), certificate_index: CertificateIndex(2551665535) }), 1781367262), (Hash(Script(ValidatorHash(ScriptHash(166e40822092ce009e3863b6af2192415ec2bea68df4d223ad081be8)))), 1007921653), (Hash(Script(ValidatorHash(ScriptHash(6f60de84d117a5e915908cbdaf4b4516b7da7d61c745810f3f2587a5)))), 3106659847), (Hash(Script(ValidatorHash(ScriptHash(b7bae71e2d057c4ac0f4337c854bbb30ede877c2d7f9c5adda3f5ee5)))), 1053145090), (Pointer(ChainPointer { slot_number: Slot(3714372803), transaction_index: TransactionIndex(72042050), certificate_index: CertificateIndex(1509327066) }), 3940037914), (Hash(Script(ValidatorHash(ScriptHash(7067f6b6fb9add1cd4409a061781c24c8f9d2aa56b630b312db2e3d5)))), 4079720784), (Hash(Script(ValidatorHash(ScriptHash(a4b4a8e347008aa489f35b98272a6ca4fc25959b0bd20a68f8592e44)))), 1584515697)]), valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(838409353)), closed: true }, to: UpperBound { bound: Finite(POSIXTime(361863719)), closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(b4819d111711ba48868cd06ff8d99ab5b55e7534aece8ee98e6c455a)), PaymentPubKeyHash(Ed25519PubKeyHash(2d3ce5635fd6ef2beead54164759fe87df4853d7f504ed1061c8338e)), PaymentPubKeyHash(Ed25519PubKeyHash(a0d48ce56b063a264ae1828159fabf544ba69525c37766835b6bcb68)), PaymentPubKeyHash(Ed25519PubKeyHash(f11701c55ba58e812def810ce8b5c18d49945dafa67456b3903b8ec9)), PaymentPubKeyHash(Ed25519PubKeyHash(ad5b51db58abaea6ee92412e6b8c27f95d8d4c6e5541edd97b049e81))], redeemers: AssocMap([(Certifying(Mir), Redeemer(List([Integer(6239320199750037689), Integer(15913589025057844587), Bytes([133, 208, 148, 171, 114, 67, 36, 209, 169, 38, 209, 97, 67, 163, 204, 172, 104, 82, 231, 119, 134, 19, 204, 55, 74, 236, 118, 116, 35, 78, 54, 53, 104, 127, 234, 93, 97, 1, 136, 194, 168, 56, 83, 218, 179, 78, 64, 76, 211, 140, 137, 196, 45, 229, 40, 84, 74, 108, 200, 193, 96, 13, 20, 253, 113, 214, 237, 215, 101, 39, 154, 249, 114, 229, 169, 161, 170, 19, 210, 86, 32, 56, 11, 48, 207, 147, 209, 27, 150, 80, 46, 39, 62]), Integer(-16623484847137450040), Bytes([36, 80, 100])]))), (Spending(TransactionInput { transaction_id: TransactionHash(79cf6c453b2acdbe0bb65db560233f5a227950ff0880c3a2a3eb775c679fbc7d), index: 2947145207 }), Redeemer(Map([(Integer(10749594368703218252), Bytes([113, 229, 13, 115, 192, 166, 124, 147, 99, 41, 140, 63, 8, 115, 75, 57, 186, 46, 31, 55, 114, 209, 243, 143, 249, 212, 236, 67, 212, 53, 60, 154, 211, 97, 73, 162, 200, 224, 182, 175, 216, 214, 186, 10, 11, 106, 166, 155, 106, 231, 208, 60, 39, 70, 47, 238, 202, 215, 225, 240, 19, 231, 63, 166, 171, 126, 253, 30, 22, 220, 251, 116, 226, 194, 175, 6, 28, 223, 222, 35, 97, 43, 59, 74, 192, 58, 147, 111, 59, 69])), (Bytes([202, 49, 16, 204, 32, 74, 62, 160, 224, 58, 222, 187, 174, 91, 237, 234, 57, 89, 93, 11, 49, 122, 142, 239, 159, 142, 219, 204, 85, 238, 86, 8, 80, 102, 79, 15, 243, 138, 205, 202, 75, 86, 77, 111, 35, 212, 106, 250, 82, 122, 8, 179, 55, 121, 68, 62, 112, 167, 160, 174, 5, 98, 250, 250, 108, 63, 184, 95, 213, 212, 254, 125, 247, 233, 104, 222, 14, 5, 87, 51, 1, 38, 91, 79, 75, 87, 172, 159]), Integer(-16105624062234957364)), (Bytes([206, 100, 252, 224, 85, 67, 0, 146, 168, 134, 14, 141, 81, 163, 252, 204, 27, 37, 184, 60, 209, 69, 172, 37, 216, 220, 201, 131, 24, 255, 210, 173, 18, 180, 30, 27, 195, 201, 108, 124, 17, 229, 134, 3, 13, 93, 143, 181, 22, 222, 66, 113, 71, 26, 184, 240, 82, 213, 23, 220, 232, 88, 169, 245, 143, 171, 37, 48, 173, 226, 1, 103, 3, 75, 183, 216, 69, 208, 12, 242, 53, 187, 227, 103]), Bytes([49, 98, 69, 40, 146, 13, 63, 49, 174, 103, 155, 108, 107, 131, 192, 222, 105, 202, 36, 61])), (Integer(17641650114553881220), Bytes([19, 66, 173, 252, 116, 20, 193, 176, 60, 114, 77, 32, 12, 83, 46, 11, 241, 32, 5, 15, 184, 106, 252, 164, 244, 132, 224, 65, 158, 241, 107, 104, 107, 169, 176, 206, 32, 67, 3, 171, 142, 133, 54, 95, 43, 225, 86, 220, 155, 165, 230, 61, 219, 16, 185, 72, 208, 213, 81, 82, 25, 190, 195, 183, 161, 182, 126, 50, 130, 58, 200, 128, 130, 214, 11, 206, 120, 145, 226, 233, 122, 232, 80, 155, 39, 51, 181, 59, 140, 73, 224, 9])), (Constr(126032016, [Integer(7787559864735705180), Integer(2127818927508617713), Integer(5155631119871866475), Integer(-18396566547523949959), Bytes([63, 188, 198, 248, 216, 139, 137, 73, 106, 210, 221, 155, 224, 44, 66, 140, 68, 4, 51, 22, 74, 125, 60, 8, 202, 245, 241, 108, 140, 43, 50, 209, 231, 253, 2, 38, 123, 153, 16, 65, 52])]), Integer(-16409732504822602435))]))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(db6549ac5a932d508911a7343478c85b8519a13fb960c15e7442bf14)))), Redeemer(Map([(Integer(4864576940907377842), Bytes([175, 126, 3, 7, 3, 123, 228, 255, 206, 187, 163, 236, 222, 174, 77, 185, 186, 43, 203, 218, 255, 102, 34, 200, 39, 35, 29, 12, 207, 218, 121, 145, 223, 192, 194, 214, 27, 219, 211, 230, 233, 174, 251, 210, 215, 238, 139, 249, 167, 19, 144, 139, 108, 208, 188, 111, 26, 120])), (Integer(17866170359980033590), Integer(9968111103518514952)), (Integer(7062931128494742539), Bytes([188, 212, 63, 126, 119, 180, 238, 112, 224, 137, 119, 72, 21, 83, 225, 164, 31, 97, 157, 123, 61, 101, 47, 197, 225, 249, 4, 135, 207, 56, 212, 79, 16, 84, 226])), (Integer(2986177198920072604), Bytes([205, 136, 177, 63, 94, 84, 219, 157, 150, 134, 131, 146, 214, 32, 175, 103, 31, 187, 171, 187, 180, 180, 205, 39, 117, 68, 99, 159, 96, 73, 228, 247, 183, 227])), (Bytes([88, 132, 17, 231, 27, 248, 82, 197, 215, 196, 142, 69, 179, 145, 113, 95, 202, 25, 91, 116, 94, 207, 21, 43, 242, 200, 199, 29, 138, 33, 236, 4, 24, 132, 241, 112, 84, 194, 187, 116, 22, 131, 75, 30, 118, 48, 138, 240, 125, 34, 135, 115, 236, 164, 122, 214, 65, 2, 27, 192, 10, 235, 145, 20, 138, 243, 100, 213, 6, 108, 50, 19, 185, 8, 175]), Bytes([243, 50, 250, 219, 146, 10, 119, 162, 24, 46, 123, 40, 64, 77, 233, 17, 114, 235, 37, 32, 129, 131, 127, 214, 129, 134, 15, 176, 86, 230, 81, 87, 199, 75, 107, 27, 228, 190, 25, 132, 190, 237, 99, 177, 137, 249, 184, 72, 188, 106, 216, 171, 71, 2, 3, 95, 120, 102, 202, 178, 6, 31, 153, 232, 3, 11, 136, 192, 194, 61, 126]))]))), (Spending(TransactionInput { transaction_id: TransactionHash(7224c90041ca10dda085de5afacad591f9e7b847242c3dcff572f3b04e8d172e), index: 944131020 }), Redeemer(List([Bytes([155, 139, 250, 173, 109, 126, 116, 148, 239, 105, 35, 166, 250, 209, 138, 254, 143, 100, 91, 188, 57, 202, 217, 165, 20, 197, 58, 251, 25, 142, 25, 220, 9, 166, 0, 184, 86, 229, 139, 202, 24, 255, 67, 234, 104, 32]), Bytes([137, 215, 194, 162, 74, 174, 65, 28, 13, 61, 160, 169, 76, 236, 134, 201]), Bytes([190, 87, 61, 95, 191, 155, 191, 200, 213, 232, 191, 174, 140, 244, 84, 142, 24, 244, 149, 238, 175, 31, 67, 159, 192, 88, 153, 133, 62, 41, 181, 131, 165, 0, 240, 101, 162, 100, 211, 89, 179, 132, 224, 61, 147, 74, 142, 247, 229, 79, 191, 178, 76, 12, 39, 235, 39, 197, 108, 190, 27, 131, 214, 210]), Integer(10877039398281208866), Bytes([245, 49, 133, 212, 69, 170, 182])]))), (Certifying(PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(0e2c3e533b548d4ad5b0cddf94dff6140554fcd04df242a344713595)), 3596605903)), Redeemer(Bytes([237, 84, 107, 181, 142, 178, 35, 247, 44]))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(34acf9d27298848ceb4c0d40c846e2647f5d7af9cabe7c16250fff36)))), Redeemer(List([Bytes([78, 90, 214, 144, 251, 187, 188, 123, 244, 237, 165, 1, 72, 126, 218, 125, 133, 234, 74, 239, 96, 94, 24, 90, 190, 3, 60, 95, 181, 152, 108, 110, 41]), Integer(5731157922341262668), Integer(-4335164808407264972), Bytes([134, 242, 84, 26, 178, 183, 212, 54, 149, 70, 5, 162, 180, 53, 242, 114, 206, 81, 85, 175, 206, 100, 53, 103, 209, 73, 207, 182, 228, 79, 115, 193, 145, 70, 95, 242, 115, 87, 106, 159, 89, 91, 30, 68, 193, 124, 115, 47, 31, 40, 133, 80, 151, 255]), Integer(15690818283624318033)]))), (Minting(Ada), Redeemer(List([Integer(2069942577745421945), Integer(13319561239276934380), Bytes([196, 179, 178, 122, 8, 111, 2, 199, 170, 233, 14, 123, 96, 184, 66, 46, 225, 233, 3, 53, 155, 75, 255, 105, 39, 145, 114]), Bytes([56, 119, 56, 131, 146, 197, 103, 153, 31, 8, 223, 37, 83, 233, 80, 62, 156, 89, 168, 164, 218, 28, 160, 9, 92, 136, 167, 173, 41, 222, 180, 128, 42, 87, 188, 131, 254, 134, 213, 86, 80, 160, 7, 55, 235, 106, 226, 219, 204, 69, 37, 195, 38, 32, 113, 52, 133, 95, 193, 110, 228, 97, 53, 180]), Bytes([29, 31, 81, 90, 253, 98, 22, 39, 253, 185, 103, 37, 32, 104, 81, 205, 210, 190, 31, 104, 156, 109, 252, 171, 217, 248, 61, 253, 159, 190, 24, 150, 162, 35, 71, 9, 77, 217, 199, 96, 35, 190, 214, 40, 167, 249, 82, 47, 216, 16, 95, 234, 130, 233, 141, 153, 102, 238, 1, 119, 118, 249, 47, 59, 194, 46, 190, 53, 2, 238, 46, 216, 239, 12, 200, 247, 206, 36, 61, 53, 4, 32, 16, 248, 175, 190, 107, 208, 110, 99, 213, 178, 253, 208, 76, 40, 64, 192])]))), (Spending(TransactionInput { transaction_id: TransactionHash(4b9a8f093e2e8b1822e4c68ba111a60d7ad9cbfcac0674f6fb7c5b16bd0d8fd8), index: 20566719 }), Redeemer(Constr(597936047, [Integer(-401514188748236140), Integer(15735402432053599665), Integer(-3275194184185951579), Bytes([248, 175, 249, 54, 46, 96, 253, 85, 101, 158, 120, 145, 117, 109, 38, 171, 72, 81, 53, 87, 129, 96, 39, 255, 77, 147, 31, 182, 206, 87, 21, 181]), Bytes([141, 216, 99, 172, 227, 36, 116, 196, 8, 1, 233, 126, 99, 32, 214, 115, 145, 152, 137, 183, 242, 86, 151, 33, 219, 162, 67, 26, 178, 51, 232, 189, 40, 92, 28, 68, 193, 212, 246, 155, 115, 27, 157, 43, 152, 124, 113, 68, 176, 176, 125, 154, 157, 23, 13, 226, 127, 242, 79, 239, 221, 243, 183, 24, 221, 237, 111, 127, 157, 194, 99, 110])]))), (Spending(TransactionInput { transaction_id: TransactionHash(48eebeaef8deeffd6fba7b1b98e118a5cc2086b63641eff458daa48b6553877c), index: 845727722 }), Redeemer(Integer(-16728904964620355042))), (Spending(TransactionInput { transaction_id: TransactionHash(0d57988e521e371aff11852b58e1088fe19726abb33f16bbf1206a67475d575d), index: 2941169133 }), Redeemer(Integer(10497112379505076689)))]), datums: AssocMap([(DatumHash(2d193c5ceaf445b29ae12d5ba957b3824cc13133825c9da6f963407ee6cee6d3), Datum(Constr(196802684, [Bytes([14, 76, 99, 234, 208, 48, 115, 11, 29, 123, 216, 168, 109, 191, 12, 116, 70, 21, 116, 253, 152, 47, 3, 151, 129, 0, 214, 127, 244, 166, 131, 139, 79, 80, 150, 48, 189, 167, 181, 71, 183, 127, 21, 201, 37, 213, 8, 17, 111, 13, 243, 233, 41, 139, 217, 234, 6, 148, 194, 164, 241, 138, 82, 181, 213, 52, 191, 176, 235, 60, 150]), Integer(81961458671434559), Bytes([240, 107, 34, 91, 249, 1, 37, 212, 169, 237, 172, 193, 25, 129, 199, 165, 217, 53, 77, 159, 67, 196, 182, 226, 50, 54, 83, 202, 145, 29, 240, 51, 33, 36, 25, 231, 192, 71, 49, 200, 49, 19, 182, 243]), Bytes([100, 160, 6, 29, 159, 137, 51, 13, 245, 169, 84, 74, 167, 90, 1, 41, 176, 246, 93, 181, 98, 116, 75, 182, 159, 109, 79, 71, 90, 92, 105, 208, 44, 195, 220, 176, 194, 116, 180, 187, 198, 86, 160, 77, 110, 41, 147, 67, 82, 95, 185, 81, 102, 44, 23, 185, 79]), Integer(16239469322319425174)]))), (DatumHash(fdf11482da690539eef20c26cd27cecd7f5cfb6d12852a4b72dddaded7158c74), Datum(Map([(Bytes([214, 212, 251, 238, 8, 244, 215, 48, 250, 101, 190, 51, 192, 14, 170, 57, 47, 186, 48, 216, 192, 147, 47, 92, 9, 198, 24, 233, 73, 134, 93, 64, 172, 119, 170, 191, 179, 11, 50, 112, 144, 229, 125, 97, 210, 147, 168, 202, 158]), Bytes([5, 14, 29, 114, 190, 203, 143, 180, 12, 165, 116, 1, 182, 219, 108, 83, 132, 117, 54, 100, 31, 156, 211, 88, 159, 68, 197, 29, 114, 150, 232, 216, 77, 148, 92, 125, 136, 191, 36, 188, 119, 221, 156, 10, 51, 10, 69, 138, 150, 166, 7, 223, 31, 253, 113, 25, 145, 56, 125, 79, 174, 179, 20, 23, 12, 167, 229, 207, 70, 100, 75, 114, 220, 175, 221, 159, 194, 103, 16, 67, 253, 138, 44])), (Integer(-13599185349541535264), Integer(12320948268393618043)), (Integer(-6026077469102340747), Bytes([147, 219, 79, 148, 176, 252, 123, 58, 118, 60, 164])), (Integer(10908679578297618426), Bytes([25, 54, 73, 167, 50, 78, 131, 108, 146, 58, 96, 138, 136, 33, 116, 32, 23, 12, 107, 202, 25, 172, 104, 71, 132, 79, 154, 117, 51, 97, 230, 166, 231, 148, 193, 57, 53, 193, 129, 13, 117, 143, 111, 38, 180, 130, 164, 214, 184, 233, 165, 215, 5, 124, 47, 140, 166, 210, 103, 157, 118])), (Bytes([110, 19, 70, 212, 173, 55, 3, 64, 181, 219, 160, 252, 245, 170, 104, 163, 6, 200, 103, 164, 16, 62, 211, 89, 125, 254, 49, 12, 64, 24, 139, 34, 88, 54, 65, 84, 173, 82, 114, 24, 118, 150, 178, 136, 212, 111, 234, 169, 23, 28, 18, 201, 156, 63, 208, 223, 147, 25, 3, 7, 195, 63, 145, 209, 248, 125, 23, 173, 215, 13, 0, 48, 195, 77, 235, 204, 238, 85, 250, 32, 167, 73, 94, 154, 132, 208, 219, 171, 242, 104, 215, 146, 91, 252]), Integer(-9199529737147709059))]))), (DatumHash(f033e4f6e37ed83b3145d1d01525488437d7ca41bbe52a39aab31a97f1224e43), Datum(Integer(-593552128947493946))), (DatumHash(e8aca7e61f69e1260d8d8e0cb8b6ca34b2b6a11a26f22f69e88bbcf644fb08b4), Datum(Constr(4088868737, [Integer(4177234764228082000), Integer(3603356264052409860), Integer(8465656476941222898), Bytes([202, 93, 174, 183, 221, 67, 107, 168, 93, 30, 39, 68, 104, 207, 226, 0, 230, 8, 86, 190, 251, 78, 138, 209, 6, 212, 115, 70]), Integer(-17617145114892162587)]))), (DatumHash(d3da487bca94b2ae59991c9704d0a3d381b88531125c0f9ee4dc13a0e0061067), Datum(List([Bytes([186, 52, 194, 43, 73, 74, 176, 184, 214, 121, 67, 158, 62, 120, 30, 157, 180, 112, 132, 250, 216, 165, 198, 213, 253, 98, 230, 17, 32, 53, 165, 193]), Bytes([148, 34, 172, 191, 198, 193, 41, 148, 30, 153, 51, 181, 164, 64, 122, 165, 155, 71, 126, 89, 76, 81, 248, 225, 168, 50, 118, 52, 67, 34, 147, 134, 165, 234, 234, 147, 202, 6, 209, 137, 34, 136, 11, 10, 203, 12, 7, 128, 15, 136, 64, 4, 45, 8, 82, 239, 86, 206, 119, 96, 89, 163]), Bytes([]), Bytes([146, 61, 87, 35, 59, 214, 192, 241, 62, 172, 13, 232, 50, 195, 214, 253, 2, 218, 189, 136, 143, 1, 21, 241, 175, 218, 119, 49, 125, 166, 227, 48, 202, 165, 176, 149, 43, 154, 2, 125, 194, 198, 90, 147, 21, 140, 237, 246, 227]), Integer(9971176567098175649)]))), (DatumHash(c61c8ce968a5382e749189706386376dd97818d9ec3e59123fbf224fb282605f), Datum(Bytes([107, 27, 72, 2, 106, 154, 29, 15, 2, 16, 140, 88, 37, 220, 111, 108, 172, 80, 114, 175, 140, 140]))), (DatumHash(0d7e84d00ba68cb161e724f157f15b429995bc6bec06219abb6ebb0e05321182), Datum(List([Integer(16237504671388057912), Integer(-16285226431970625050), Bytes([247, 109, 75, 197, 44, 133, 186, 4, 72, 71, 51, 193, 0, 113, 147]), Integer(-10372740837566876008), Integer(11123773230320431390)]))), (DatumHash(598bf36b92c1b696f4edeca936c026ea54fcedc4a9255c78794fec17379be8c8), Datum(Integer(13795168235298107099))), (DatumHash(49624a0f85084a48045f84298a6addfdfa6479473e82f77e4ade173f07a4d772), Datum(List([Bytes([71, 229, 111, 177, 61, 96, 150, 100, 214, 56, 249, 163, 231, 18, 20, 0, 217, 46, 148, 214, 164, 155, 11, 75, 184, 34, 147, 94, 115, 69, 195, 23, 213, 203, 128, 138, 238, 122, 53, 173, 210, 12, 74, 94, 43, 183, 228, 164, 95, 18, 159, 11, 131, 5, 119, 178, 85, 181, 88, 168, 61, 102]), Integer(14293894423366455123), Integer(1221696318822708709), Integer(-12695428866911314187), Bytes([37, 105])]))), (DatumHash(61284967c2a9fa4e359cf84d716a443fa4a1e6deff58a59548aa74c89cd90b88), Datum(Integer(6734396926988172344)))]), id: TransactionHash(17b27f69606574edea9d5a1f15e8c9abd732c7e2fd2f123a654b341d88b08e12) } +cc 6754dc117f31dda503b9cea982aad28214fd39069e2a35e276e7a80693b5a7ac # shrinks to val = ScriptContext { tx_info: TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(00000000000000000000000011d5322bb28add0c541afac5f59c2415cd39baea), index: 1172339953 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a1321bc06e424938c7e5a3db667a16cde2f7d4145662c8a8cbcc7eae))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(132492f5ef8c29cafeaed2adfe4abb1009c40bc2bd1d0cb7fbc73482))): {TokenName(0563cf40cc97ba5f6e71e11188fa463b3caf052a5f888afdbddd0231e05890e9): 4267529379, TokenName(319d34aaef3166fc693e7da784a17b3a380ec8413adf4a053a89fbdbfa8c8688): 3022272300, TokenName(5d1f501fdbb8e2b043051a37bf3e6f4462f58ea3459b168e06566d7a223b4964): 1472647335, TokenName(7c780c5081be1ee268e5a8983b2093b50a6d68188442c6cda8f35a61babf8f7c): 1407873443, TokenName(8a318158cd161fb7a25a338c20423bc2b7f3fd53b7b2349a64c36efd87965592): 2983736929}, NativeToken(MintingPolicyHash(ScriptHash(4601585ff8414333098dd5c528dd7164188ef66b73e7a50b5403f7d4))): {TokenName(21503d22ee6638c1b9f86d9f216749cfcdd7b9c3f05cd63b3735bafc99d56e35): 268819850, TokenName(690a9d25e0ce3f8c96977cb27c91255e5c8251779a9cb890ec23d6b56df5ccbe): 2049992157, TokenName(bfb672e721a9bb93772abd070b280a57033d1217ea7e7f82fcb6c84b194b4513): 314390417, TokenName(d10cd94de9a3b91a3d0b156a0f8b656c0f0133d0fef376dbe85ee1247cb47ad8): 1019985646, TokenName(f76c898e35e477b7d4f658dd21e4aa3b7d99b9911f53134287474293c1ad5c48): 1337489045}, NativeToken(MintingPolicyHash(ScriptHash(4f9ee1cbdc2abd45e53841e9bc178930148d637edc244f19827d1b82))): {TokenName(4dc84a6f8f1db80a1f074b07adcc80f559465cff416470ab6095b767de801458): 226509656, TokenName(b665e1f8a1bd6c867aa6868bda6b66739b2c4ad97130e7d85167b92933e612e5): 3081002613, TokenName(d23696e1a682f98fd0fc046476049f42f89d5cc24835b0784b7100254c818ee5): 1540836842, TokenName(d3f3a02c9e046d64f19caa44f964f0d043ff655fdbae0dcef4ef2ca6279d1da9): 857302425, TokenName(e237c96477dcf222829b69dab4d3bbdde33abc18bfb9d43f995a28a085a11600): 4025060393}, NativeToken(MintingPolicyHash(ScriptHash(ca7fd51fbe9bb1cb116145a4f2870bbc022b6bd0ff423a099b159b51))): {TokenName(23708eae008cf5a8c0f80de6e7a234f5da2a7bd70e77dd982b9fffa737931e48): 2826237570, TokenName(3c39631b60c542bfed5c5aa3810a46ce8a16a7bcdbf85ffef02f82a610a8e0b7): 4034833149, TokenName(45e3651220d382bbaacc96a1fb53ada50353788b1455514b3a81017c1564357f): 334707204, TokenName(e76929505adeb664e97b73280866c39e6d7a7375f3d2c07db9e29b2aaa1a64a9): 4267139948, TokenName(f43d5d1b593a13cbadbbf2ff662ac97c07ff7b612a4dfac10780490fe5c77eb4): 2861426176}, NativeToken(MintingPolicyHash(ScriptHash(ccb13a35f256b140e44c02b4af30764b1d12c57a7043cb1fb326f377))): {TokenName(44843230b3fcfbc9f25a9ace669fb0a80d65cb45e0900c346bb8dd464c1e2c24): 3886874923, TokenName(59c78285a99d5f06d60e33913bb25499e7f191da5e7e5fe0c19b34e0c4b8de24): 2372979482, TokenName(6ac148aece10f6c09c683719fcda91b2d1a5fef071693fc176df2942bfee6afd): 2142107358, TokenName(b58cd5725e4b0bb298802dbe2b7a6f294bf4e771f6f23e584487b792cf859c67): 1813112534, TokenName(f1af2ca64c1aeba2037fefb1eabc8c385da50cda787395ad88102ab05287f69d): 1241001126}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(2b07b7877a2b46bc4579ec595aefd73b398b1bf1129edabab45f9dae2958d81f), index: 1243967587 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(11c5699e46aa23a4bdbb1521e5ef13f0af4cbd8ccbbe11a7197d55f9)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(1728648231), transaction_index: TransactionIndex(3590170767), certificate_index: CertificateIndex(4283880003) })) }, value: Value({Ada: {TokenName(): 7748603629653168127}, NativeToken(MintingPolicyHash(ScriptHash(0c02e4d718f96291697fb0bd36769f5cd5b37bd67d1bd272343e9fe2))): {TokenName(5c72315a5de9bc63bcadb6dbec2af6d5dd22e67ae080a75b692cb650dab05166): 1927482761, TokenName(8099c9a487bdf002ee3137cfa733edd6244225c73eb0da98e404fe2d472ef4cf): 3185204016, TokenName(8d1d8eb3f49354015db84c27b0dde13c4e35494c822ad72ef79b81061322c556): 148143710, TokenName(91e2210236086e3326cebbca8e3113d4b2245c9d596cd38d05fe5a4b537fb3c1): 3953111174, TokenName(e8c032c78e4cc50fef69f11cff90ea4d005acbdffc12a8d4532858dba1e43264): 2028865169}, NativeToken(MintingPolicyHash(ScriptHash(280be125df57f2457a23dcf6051c2f9d7a808a4525cd863a3da33627))): {TokenName(189e7dc25d4453ae7fe26c665e2678ba87e01e8edb4a468006ccc4f201571a9e): 4185894986, TokenName(2d08b6a48320fd20d083e3e2d5bbb552c6190990b112c51f72a53ba50416e1ec): 3575835787, TokenName(4784527077bf4fae44b72289d7f386ebfc85a7027e666e343fb77fe30f9ee062): 1633553840, TokenName(5afb59bda895da2ede5739ae3cdc8a3822763fb69b01c00e5e1508c15cab8ea5): 490427526, TokenName(bfd5ab94d71e159d4b1f8e0100285868d4db2ae35478776e7a6cec74bbff5758): 2797161448}, NativeToken(MintingPolicyHash(ScriptHash(4ccbe3c3b80623782fa30aa49abc0b5d90810fa18f997f183fd745e2))): {TokenName(23222734017052d6945e2e56deb35b2b1e7586a7d98c4a4645bdac533dcf5f51): 1708191530, TokenName(423583311cc5510ee57122a1153d6215049a53819927d9f5e5202b00d6eb36a0): 4210856024, TokenName(5c002dba64cb8afc8c7ea7533ece13c195d029ed9dd664c85559f0674407d920): 1179183873, TokenName(7e590fa6de16d366094f4091043d7d118ebf719fac24313646eee33aef392089): 2073268386, TokenName(d7f83d86e2b4c8ecdd3b4ef5876cb2802e6100cf1d09963bbdec106dffeda8cc): 927853813}, NativeToken(MintingPolicyHash(ScriptHash(7cd50420383651da418a92da5c91d727e31bc34c07ac3d22995435d4))): {TokenName(0b059a492843318861b9a242173695674ee3730818031d31e9393b6725aac77b): 2317693307, TokenName(4547699b8126d931915793b4bd95852b6de579bbefbae3e88a1531fce25fcee0): 583744481, TokenName(5e61db5b1a03c309654f1a4d9bd65477011aea838970b1150b8b18262f02ba49): 290296387, TokenName(9b6b72305e7fbd0c3ed605e23e474991582e70f63878e53b4e9c869b040f5f5b): 1480523016, TokenName(c83fb9d4f892e8261037fc7054011a0b5a374a23d488d535dd49b108eb191442): 736650869}, NativeToken(MintingPolicyHash(ScriptHash(8d673ba1a215d046ea7bba4d80257f6499134acf667d658633f276d4))): {TokenName(02ca529425c42b3e95e4f42e49d16bcc6021554d7400ce4ae7dda185991994a9): 748377391, TokenName(5f82bccb82a27e6566ec1011b5035ea3655295c2be1e9fc0c40829b731c8c961): 2438112588, TokenName(7c27a2a9d896ac4d4b4fc1c80a15311a430de3b5b37a3fc7f3b3a7cdd861334e): 733744395, TokenName(91fbe467bc389da8540eefd9aa06340927a19a56d727b0fbffaa47accc8d614c): 2138315087, TokenName(dc2268f072bda291c348b91fc1ffaa9821e2c848662b239319a636ec39471579): 3177580649}}), datum: InlineDatum(Datum(Integer(15075788117240937958))), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(603d1fdf0eb705103314a22989c4e5eb73ba742026913342c41ed86d2fdf3660), index: 2051295606 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a4216e25edb29e77a8d0aad24d129def1842d9579c9d4e3f682dc55c))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(ea7b33747144d1d7d13aa14f7df6697eabaec5fad6ac2161f0693214)))) }, value: Value({Ada: {TokenName(): 8925537596683938766}, NativeToken(MintingPolicyHash(ScriptHash(29093716b5f94efe6dc0d363eeb0597e465edaf28e3d6ab44147944d))): {TokenName(1981ac8871574081e37734e62f42d59e5694a149d3e1a8a39954f0b9fe2b591f): 2432836977, TokenName(4acd5d154c2ab392c1710859c193efcdeb9a4535cbc8e0dcd046b640d4eb7552): 902076967, TokenName(753bd5b750c94c9f6ce5f8a3ddae424f72936cda90ac9aab4b38b95f5e714cbd): 332318396, TokenName(9a9e5e9f0223500222f9b75d0ffb77d2ce7531291c845e8bb6689de491d692d5): 340392667, TokenName(9b686d2e05165f022cba64fadf1088914bb366a507ab213c8c3ddaf7ee7a46c1): 3685600604}, NativeToken(MintingPolicyHash(ScriptHash(4d626f6a9399c5bfa902fff30c083c3fab316fb674ceb3cadf2ec9b1))): {TokenName(74e5f89afcc7d5991f383af40c46ac32834030978c0189980e190c6bc61927eb): 2660653260, TokenName(7d85353bbb7de907ea35ceaa7d1059e9673af6e70cf03b7795d35f64b8d989f9): 4038719552, TokenName(9aa7e1d8519ea3ba3080f75482fcced303c43a06ddb5fc86cf1a1d61ee9647a3): 3376008048, TokenName(c9d0f508f235c15477ed3b0541c7df528d194c81e691322502c80bbce3e72b93): 2552040617, TokenName(f45c9fd4835fb6862c993e732af56ce86f6f80fe52d87ad2b34ca87c33ddda5f): 93882121}, NativeToken(MintingPolicyHash(ScriptHash(83af1664cf3e4ffa798d43afbdb681e14bb316513ded6f041717ffe4))): {TokenName(0c8d91e2eba3751e7448c2993f15d727f9be1f1a761ad02e14fb0ce89f78feb7): 1580835092, TokenName(1c6ae29f6ce2d7da849da44b7a726196e68095729ef6b4d8c7c0eb361747a31f): 3375235636, TokenName(cee109e119cdb548e08d433d900d28dd53402b097cb2e2b2660da4d1def1d60d): 4128095315, TokenName(d05c690fae152227daf62a7798b42688152838022e541483ecd9c035c3e0b98e): 214072117, TokenName(f47aa961eb58d8500069e96172432cd06e985d50abf1d5cbd1ffc7f4b76b5d4d): 4115183080}, NativeToken(MintingPolicyHash(ScriptHash(aa8ac7ac8c3301cbe6a4f79f7bdbebad4a135d9638a6a8c4fcd6a79d))): {TokenName(5462d975dc29be0ae56412567c9a4b3402cb41a8032a14226434147c5da1c03e): 2745335079, TokenName(7d663f36b92ef6ee6eb57c396344f199fe9e5de46db02fa4ac77ce3e1d861218): 2197791936, TokenName(8a7729799beb6cc12532b6354bf9bd7cb9e286c3b3fd876de4743f4d51bc9a58): 824585603, TokenName(af3af3e4808cf616c5d52524c3cb4e661c51c4ee8df6f746030e2777518cae5d): 3376409866, TokenName(ceefb226d3775a95b9ffaf22eeb5de5e07c140610d7a35c777c7d708db648999): 255007278}, NativeToken(MintingPolicyHash(ScriptHash(f251d0a77f02db88b11a55a7e28ffca19f7784971cf06bc8fb59b3b7))): {TokenName(896fc5052de9928da0dce4f9f7027c82210dff01137734a0cfbc0d68b6cd3223): 306344900, TokenName(9ac2f97ea90bd314e1f3e367ee1822b857c932254fe2e8af46ea400845bf16de): 4186517141, TokenName(ae7833ac678940e9ae4fdb023981607f48622f1887201f1ea87b218e3d4a5802): 2705283853, TokenName(b72b9e7d554c3bc5f31594c249d56eec8b49bbf65cdfbe1dc8379940a38b7a2d): 3341327994, TokenName(c91ffa8366cacc28917ed8b0b951fd276c9cb85ef3a6741b33825dda546c1c50): 4167661001}}), datum: DatumHash(DatumHash(2b4131e00a320d0725797d982946dfe0c11d9068b0825c8465712f66be2d87da)), reference_script: Some(ScriptHash(ff7e2343bfe108a8a274717bddb6bec8765505c848218d03c78f2e05)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(63e71f3ed0b72ce795acd81022fc40804542770cafac1643749ece536c82f743), index: 3473660016 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(01519a6eaab23e224e3a730777da99c9482523f48f947e068e20d67b)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3c232332ad432fa3bc474d1448fc06ec13c9045582f7f1532bf65f36))): {TokenName(02ced3f4669e6f1d5de68b002773f43a303ac1f818ebf36cd4cbc6e52f5da94f): 696656815, TokenName(0c915be63ac8e42869e2266cde84695b1d3056e6c716673cb4e3f4a8f1a5b6c8): 425545477, TokenName(251f94d99daf5dd6b9cdbe7d6cdeb03319ccba15d7be17e81400304c5ad2c88c): 1797429777, TokenName(28d62192084e26396fcab568e94896c7345857172934f450539cfbd6b947733c): 836609154, TokenName(a5ce984550eb3ff4591d37fce44e3913b2187f3bb5a9a826d25ee64b1b098eb3): 3380257614}, NativeToken(MintingPolicyHash(ScriptHash(3dd797a91a6823977bff7c3cd03170d1de3348a0b210adeaa88b79d6))): {TokenName(121ffb277c0db5ec48a8eb058e0c054cd4641d75780b415ced1318886f26e35e): 4069578957, TokenName(b7cddd8baee136938f93127de502055a5bb6da34067000ff30283a94d54723a3): 203685091, TokenName(d8092b3cfdff2fe5e1e8247b794dee3b7e6cbd8c9703350792705916e19671db): 2208159976, TokenName(e81744921f1aa0f3a441c788ecce3b6204d8d37b1bc1dbd37cced02bcb0622d7): 3789726687, TokenName(f5b7a5111b8feaf9f47baa25bccda014ea60ee1678b49e61dcbdcf88857aa6f7): 2781647908}, NativeToken(MintingPolicyHash(ScriptHash(768f53818971a0ea66b0ca1dd4e29d97963dc85c778c9ec4d5fc94a2))): {TokenName(08a33ef1c5c75d2b979ededfc7898535366cc743fe6d92097bbc1ef9e304caa6): 1663049919, TokenName(0c2aed8449ab1e4e0f0acd5caa6c4f22d46192a72b013721b48d74d72c8a41ac): 2294787973, TokenName(7e5c8e73cae565519aa6c4ed9d6647a3d18e44cc8af73708847892bf0c40102d): 3966512321, TokenName(a4482d820e7f3dfb2e78c953784c3578016a5f74dc3f24b8f900df70a6a25c6f): 2867611653, TokenName(d19427fb71c83d685805532e52bf798f9d68b8887a071781dd98af27169e5a08): 3457975349}, NativeToken(MintingPolicyHash(ScriptHash(9216b26e7161977e8d6d2baa59622d4f61e6e1719181a555734a2f5f))): {TokenName(70e9a2bb2794875b847fd4692f3300c4032e4d36aaf3a0a1cb48504ec6e898c2): 2409066633, TokenName(98091904386ddc71ad16d277bf544467ffbc66ce5c0f19254cc5c401087ca94e): 2236215107, TokenName(9f931891cc743575035282022929a975b8605fbb332e927c2822efe0543eb86b): 1825752575, TokenName(c3cc1ff4a516b48eb26501c419409c253b463f5873e26a68acb688ed10729f7a): 2543388652, TokenName(e88bc3947bd1256e59ebafef62dd42cc35254e32bc6c1d8e2c1af8082515f876): 1955706972}, NativeToken(MintingPolicyHash(ScriptHash(a9b68d234435c5920f22063eeedeabb3d9cebf922f69b90fc4912103))): {TokenName(10d53d8555aa1d766af64524899283cdd58d9b2a3d0522966385131f0c79f090): 3709039757, TokenName(552164813a95fb2a807e14bfcde12d897eba1888cce42fc506b66d6ce2e27aaf): 2570348155, TokenName(e6b46e5ae30378002de0f194a4d6e12dc2974e2cf825765b5c029b79c9ce3ea7): 2735422298, TokenName(ee9457852a462c0485900378df8a82db5b9f294b90ffadcda8d3ec23175c3202): 2913431510, TokenName(fe73f1ba83f705dbfb669c68524f91a66ed434860ae9134a7eefed52605a7b8c): 3067821360}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(09cf43b747a5975081574107d549c120ac31d43b991410677847c96e37d3a33a), index: 995961261 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(2544219b3b272f8affb97453b893ce3f618054a41ea2f4698b4926a3))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2612535545), transaction_index: TransactionIndex(2837987253), certificate_index: CertificateIndex(169250896) })) }, value: Value({Ada: {TokenName(): 5785086996295989328}, NativeToken(MintingPolicyHash(ScriptHash(24d3daec3335fe935a2dab1a9f72a106b491ea9514446b6e6eda7a44))): {TokenName(261095f4c6c9a636501c1a9f286ae75dda843399ba769b11ca9eafeed99c999e): 3372569647, TokenName(396b56bae233a8791c740f10d69e169acd6db3a77357355745bf75f83f5fa6a2): 3445609636, TokenName(5fd3a4024903053bc81ebcd2572868f726650252760de89549c1dbbb48ea8ee4): 4098907285, TokenName(635afa33d221ebcd8135c51d2c6ccef517ab8a03afabca02b1b3daa2f2e40d49): 1937604927, TokenName(bf171ca9b23bbaa1789f7608a3b0822263152ad7f17004a04c4806d8f49f5574): 191326486}, NativeToken(MintingPolicyHash(ScriptHash(73a3c06e278dbff68844f15ca850c7961dd572d7cf7dd17896ff7018))): {TokenName(305a534019a8eaa982f9e48ebd7fd29832e61cee7dfc4ef484db78d7c68d5532): 738652252, TokenName(61c785b7f8c206a14dd23d6154fc0dd201df0a50a70ef286610c4d4e789f45ea): 57281176, TokenName(9fbf7f92d5eb1e7a67eaff98c0028b6bd6d66c5866f871dcc415053152200634): 4024650166, TokenName(ec23e54ce23e1c3dbbf1b09b8183ebcd8387600823f4daee6323f0443373f2f5): 3484556259, TokenName(fb5c66d2dc5fcb3de669a10464d8f338e87c3f52bb92bf05bb6bb44774ff5e4c): 750166036}, NativeToken(MintingPolicyHash(ScriptHash(977b0103e7e4e19272752ce64715f8186441f6bf1f1d488a4f6e5740))): {TokenName(0a82e97549b50abdbf4d773a369231b08c1b7b6156f3c9a7f278c22585e577b8): 2913503834, TokenName(16a46677b19c6e2943c38dd581412e0f6b9b3d900dce33faea712a6dfb427776): 3758849122, TokenName(d0603db40b588c5f3859ea5928924537869d1963394f0aa63acda40143850d5e): 663744825, TokenName(df0364ce03c1c98d81a39ba2d3ea20ed7c95ad96532460d5a98fda854d7a6adc): 753062651, TokenName(e784df7764e83764422618a1392e20471d6ccc29a2ecf52cf5bd7caa0a6b75e4): 2955831740}, NativeToken(MintingPolicyHash(ScriptHash(ec5517e94a51a1578d4210c84c9ccb6aad4d9787e320a24942c33546))): {TokenName(0964c4d537213556c3b48d1ef2959908da834856189b4a396053d6722534bf30): 1476539119, TokenName(70780e606c49e25c446f369684747ef0d741d1f4ed0a147f7011505c842221ca): 3018400531, TokenName(a097f076c4d43992236e75e78a33ca6739151a846c903b7cf6436ec021255e66): 3888307119, TokenName(ce883d696c8db1229ae4ebcbc0e470407cddcc736bf7cf58827a8ae9e16755b6): 4070548983, TokenName(e3bb6f9753811c1d98c82c4a145c31a16204900cf53f4e6790edd6273c82d66a): 1174691894}, NativeToken(MintingPolicyHash(ScriptHash(f4ccbd6a6de163cddf206c16ef35b190f380459a63952d1b1895dd6f))): {TokenName(05c0f563fdb2515ff573c60a8388d47433a14e2e40ecce72ea238f82725c8170): 2294748904, TokenName(19828d0731bc0fb884b6085a14e70867dcbdb58a0e0ef0cd190bfd64ade91564): 4125510808, TokenName(3917ee9c0502cddb3cb8eb5f664b3cfe4f831a77c7ce23bc434a2017576d210e): 795989689, TokenName(7bb9055244ee6059f459922e9697febb411efa46aa7f02aaf04c8b67acb87751): 179016285, TokenName(94710aab52e891351cb3215b1190357af69efb64fa68dd3ed0fec2f8af5e124e): 627950714}}), datum: None, reference_script: Some(ScriptHash(19d34805b0db537602cd9e61601b0ee891803db283a88cab71641068)) } }], reference_inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(646c5ab020b4e0bdba45dc39270c69c1578f6275aac4e5c7d2e1994a1d4a9ae7), index: 2130406616 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(96100aa59444a37b9fbd6f905c83b4ccfbb6756361795d7079ef9b0d))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(974ba2cbbc09ef5d0edfc553b9e1d714cf5c490f3b30e6634da4e4c5)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2025c1c32ec8e186d74a28f893fc84914b6f889bdd159d3c3e4294e4))): {TokenName(30bc58ed8dc6e5d1239e196ef0333a1cf8734bf2719f25e210f2b581c17c283d): 3138538209, TokenName(8b6543496f447f20a4412270f317dc35524ee3eba336add3bad964ee1fd5973b): 4097751066, TokenName(b8a6fae91dae37a54c5f1f2748d1702f1829aad1af6ccefcfa9be575386ad69d): 1698135801, TokenName(d1ece0fd967fb550c45ad773ab9216f074f2290ae8d861aa334aadd8a83e3e43): 2379338132, TokenName(eeb7979e4f9a0fe0ddb6ddd99f02bba8f369d2deeabcd634d8b3bd0d17762e1f): 1144425251}, NativeToken(MintingPolicyHash(ScriptHash(96431eb431dc160ce8528c595b8527fd37d8623a658ff5b4e2910310))): {TokenName(187400bfe405947a0c85026af447540639c896f98168f1b2a321bf70767329f9): 780087136, TokenName(229866110b973a27788d02e04c82facaeef7f3baf3d10304820fb7c3f7162e6f): 3698607039, TokenName(26287b743dcebe10d2c79b2de972a578ec4f114be1824f3286a202ab779c599a): 3551441967, TokenName(b7e5afa79a5c6d138357f37f4a7d2aa891399a6aac98aa6ad53c547de534c69d): 188390724, TokenName(fd7481e9c7e26d8ced3941a1bc9e5aebeec9a1cb544fdf950f00f88bccf8e6ab): 1096813748}, NativeToken(MintingPolicyHash(ScriptHash(b8ceab26b6ec226c0a59e3253ac1983a0ae723b4b05d4b664adbd75f))): {TokenName(8b0e37aaa16b68908baec30d4ef4f15cbad1552e8a7af5de7d490f26ec221ee2): 2958418805, TokenName(acead95d21b48bd1bd984290391d9ade32cac36cca9b20b6d99f85069698b735): 764473882, TokenName(cb1bc51b825125e32fce52e5df29589e45d9d3a75bfbdd35ba7517d1c66dca2c): 158222626, TokenName(cbe38044887af69a5eb7a3d6d8de642a6bad8c7dd94b51f4d2d7dde9a098728e): 733176453, TokenName(de2616b83869ddfe31d427a7bd915e6bb481f9602e4deec63367246536b6d170): 4096836745}, NativeToken(MintingPolicyHash(ScriptHash(bb8a610ddbd715ba31202d918f194b8a91be206d9eedd8895a20cc2b))): {TokenName(6c9323150bc643e37322e95d33a8a14f429f75b8c7c62434e2d976e626ff3ad8): 72174935, TokenName(78d6fee92717c0d497933bab0ff3e8e24e420ffdb1ea1cd1db1f1080d77687fa): 3839528739, TokenName(ce0a9672afbff271b9a6c717d7dabb85cd0a280aedbf8f9708205b087a510a3e): 190791990, TokenName(ced17423c8acb2ca8138307e51d3d87626a6f37412e1c1f28079b542c324a9f5): 3341648181, TokenName(f61de49e729b1fef2493ecc84890474faddd1ac67d75588ca2d7e8b3e1c632fd): 3007165824}, NativeToken(MintingPolicyHash(ScriptHash(e4294bbaca3f5fd9c0d411d58dcf0727c1fa9b2fc2599cfa762dc10b))): {TokenName(05e1943ea4866dd92d18ccc944b702d14b8b9fc54433301314bf79ab6b189c7b): 3287269245, TokenName(654fed4b393e723741eac2833f6308f46ef79a23ed0d4634b1728ec047b2929b): 2637736497, TokenName(6decce0caacba946cf43c83beb736f44ce8845049af156cc8acd7d9ac3b8099a): 1185579404, TokenName(e14f8585ad69f0bcb39a99891a7b0127158317343627765717aac9b109f10e72): 3437265369, TokenName(f9bdc38e8c0b819272e5cf00769d0bc5f968a0ead94c046f03f6818a2763ccd3): 776023997}}), datum: InlineDatum(Datum(Bytes([144, 173, 223, 201, 140, 121, 148, 204, 192]))), reference_script: Some(ScriptHash(94007b6185b7346bc984bd7ad95afcfc40d40f1553912a99dda88794)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(b6b64499eca0629b83b141ff8928ea942f12f43b3499dd22cee3ec324b085075), index: 3829671490 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(e26318be52d90808041b52c61dea2742f853bf5256f8efda5deba934))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(870375327), transaction_index: TransactionIndex(1246192293), certificate_index: CertificateIndex(2668375927) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2d29d583a565a7c5664554ae73786ecc852b3705834a56207904b9b5))): {TokenName(1606f7628e7732dd5ae6464621e4e1455a97c7a4f4a7cc0286b6943be5915a24): 1832724581, TokenName(88c34e27758409463f67122289d19abb38829c0e30c7ff737b56817c097bb4f0): 518606772, TokenName(d74c5e3c383a4fbacc69ae35e824d49f7dea29b8763ce837eec4d8fce13864f5): 3713597674, TokenName(e069beba1b8c7ca90e7c2cc24c3d2baaa0d7345fe017225ee751ca5cc04e4677): 247823558, TokenName(ec6b9e4701fb6cd7788cdc49eb506ac29875a4edb19e2662a95d0f3d6f02588c): 3728361650}, NativeToken(MintingPolicyHash(ScriptHash(419e1f3287f74a6ecd6b7dda0dc332fb85c4b2b9a21965073b9ae8ee))): {TokenName(186e64b3bf7f12983292b62c47651d7f609b11c461a370d8a907e6e83e73ce1f): 3809259102, TokenName(3c89442f9a1013a06894baf60361a50cec905c672f4e8ddfa0bfd2e6f7852efa): 2030150634, TokenName(cc5e1525f397c479665ceb6dba4f19fea7bf8738a56308dc8e045f8d68b42910): 2779674349, TokenName(eb58bf23499953ed40fe55dfadc766b5e87c04fae463b0a05871ded80a89a4a8): 2622975792, TokenName(fcd607e5f4333727b779480f9e95b9d7cbed1fda1fc20ecdc219bd9c2ffa8792): 2991420154}, NativeToken(MintingPolicyHash(ScriptHash(90ce09cac5a7c5999221bc657e06a3f5d0e62ce0d33878d2e41dbce8))): {TokenName(9acf4262141f5acb8e98de1ec52bfedeaabf2b18c48264fe823adbf57cc29603): 1924413208, TokenName(a4802f086ebf26a2b4e3d16bfc04729cb8ed709c29451e8654fe5c969f249852): 3388478348, TokenName(c1434306da913ffa233a5b2006ff00de3c6483f591da63fa8cd61dfaa4759f94): 3354611819, TokenName(f28be7ddd7371e33148cc070296929277679733fc5af5feac2841662434d259b): 2551327226, TokenName(f707345ed60c0fc657fb699f7528a5d77456161f2aab5873f984421505869d81): 4187154854}, NativeToken(MintingPolicyHash(ScriptHash(95cd10afb254ea65079c3843e18cb313399b126dd042bddc38e86fca))): {TokenName(2c025ca7026d843a87832fb56a0d95c3d2b629d10eae2b287fbf2a57ebe01bad): 99849342, TokenName(97a30ebf70e75b14edf59bda226ad48a236a97a526f53a45c4241eaeb09cb216): 1440733641, TokenName(a68840161fd5d25b87a703b724d6ee62eabe573d16ddef143ce434994bcfe7be): 1525056038, TokenName(aa740250918bb880ea544664c1513ac01431f3fe698237bdd87556a0a3570e44): 3675185957, TokenName(f29b9b52614134f76b39468df80c6c6767ac0289c5b21ddea01222935793f946): 2328116611}, NativeToken(MintingPolicyHash(ScriptHash(9751742fc2515edde873bd9dc4709ffac7e44afc6311899d7b120fe8))): {TokenName(3a305ba2e185dfbe658bece2bf4309d98a27150cb911daac96dbcb3c88825579): 2013425254, TokenName(5e3cea53b9975b1540fa5e97e1a4cb8d47286febc4e37e418874ee00317fd42b): 1430243102, TokenName(b97cd54dbdd4f5339146bb7c12f86233097539fe99437d3e7a132608a89f6686): 3640949646, TokenName(ccd68210c540d2e70b1b3b8ddb3da71afbc3d84c80b80f19fea307270bf91ca5): 3085066512, TokenName(dbe81cf006fdca9a3b4f1126fc829e46f0f0b3851443bdde4a6d8e2263337920): 1798570448}}), datum: DatumHash(DatumHash(6ce0fe1ddd86f2210d67b6768c34f26aa206ac0c7fe63cc045b4fb87f3d6da08)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(1a8628cb331c8ed648bee37951f17a2a4ff16ead08d374387745957df684d510), index: 1909219806 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(bc17ab562fb24627336dccc799e7bc3a138ed82f77b7fd0279dd9b96))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(761437903), transaction_index: TransactionIndex(1679473444), certificate_index: CertificateIndex(957930270) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0ae3735fe68192459d4b2ef8ae30ca9560528b586fa40b95008f9219))): {TokenName(1b48b00ea46a5ce95a01c4fb95874c6a1a4c180769069bbafec6bd42d9e9584b): 1271347592, TokenName(3121d8b957fa7c96206960b7b84c589d60f02e5581bfcdd1d8c9657ca3e51178): 1716028803, TokenName(487cd18ea350068bea61713d305c27effc6e05e1247b59ffafd2f8d130ddcb06): 1980622124, TokenName(5eb9f51b040f78203f5c185c46bed5a499ea00e3808614c4573fe9ca9e8a29fb): 3367802477, TokenName(f7c612d491d33a4c3d6fef580134e5a4c599305bb08b295c924a3880e065d67e): 507756363}, NativeToken(MintingPolicyHash(ScriptHash(695a8c13b8152b5ea46cd7c9f1d0daf2e4311286ccb26b5b8af50e1a))): {TokenName(1f282df05100229503c87c1b6f001c7aafcc823231d81b1ddcb36746b20af82d): 3786938144, TokenName(873128617bfbd595e0a784929f6dd84b6bd28908df6fd3339c7948788c3cf7f4): 4262995817, TokenName(b9569b2eb0974527f78eed65cb4a329a6c1f4f80469fcc422737c71f466e0984): 1292462706, TokenName(d066788b9cbf13df2897e6d918fd506016c0fb96c8be194fb1673bb313f10496): 2349739461, TokenName(d12bd2164a090ccac674be88b6d9d5ed89292773f0caddf134463787d4e58221): 2541659157}, NativeToken(MintingPolicyHash(ScriptHash(8e4f4fe9648492f0360f4051d94e2a92e6d75f653af78bc482c7013d))): {TokenName(0f87b3a2c1bce2f6bd26854dc946935b03adc3012ed795fc8577dddb707fd543): 3227061065, TokenName(55a2fc934fbee7247339f0c52a1e1ce7faed6d4e13d03337b449467982dc9216): 483049655, TokenName(6222702ef60fb8506ff5d1787203b0c6472ccb98f4d561ea4ddcce01297a7cfe): 1725796137, TokenName(dcfaee0cc3f32cffdd57d822861179574880de2f6e2dc58c0ab0b5704cd4dc34): 3670968241, TokenName(e61632ca43edeab1bbfe8562d31889b65044fb6b79f6a83e7f35c4b9b378065e): 3962241471}, NativeToken(MintingPolicyHash(ScriptHash(a37934a127d3e87ff3c99fbb1137c9c8e9ede17817fc2cfe4e636bda))): {TokenName(8cca9cff66be72436b1a33c005cea8b5e09af05a68ee1486155dc36ea8dbf89d): 1332569697, TokenName(a20ae21714fb6005c71a6da893f6e0ba7742428708a383f920014e87af72d865): 3704577329, TokenName(b8373ec1f3bafde0c5a901a2021aa868d3b6d3f5a62d86e06cee54150be43a56): 2244211345, TokenName(f84082a08bdc5cc91c570a0e5122aa56c81a2c9f875f42f02efc99d3853b1eaa): 3317333304, TokenName(fd429f5dd49fc8d124de2be99e0c726325d3a128557619593ed3b19cf47324d5): 2247405293}, NativeToken(MintingPolicyHash(ScriptHash(b6aac5a73a52ec1eae3b182fec231e3d42397d63ab0533fda93ccbf6))): {TokenName(01859cfdd9763efb845bf2cb8838e3e0d3a54f06fce3cccfba72a10878fbe4ad): 3826300014, TokenName(59b873b6e1badb452077003bcd9c051289433db2810a40ba45ad3841bc63f23c): 2818072503, TokenName(7141ade3951c51424a1e0aa5abd99d1b46afb62658899017e1692a5712cbf7a6): 22430721, TokenName(ecafb3a36da7eb4e41fb5582be578cbb27edee114d49c5721fa96e641dd390cb): 170615864, TokenName(f0bdf9fa62e0ea72ef9ed9d2f77fccffe658dc6d14097b9fb72bf26aa3197996): 420350960}}), datum: DatumHash(DatumHash(9b40e29d7da6fb93d37c4bc8e9a0c2a0bc4414d7074b27b9af6173f586198bd7)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(83f0b03d92da9ea6aaed8b3168c6bd1a0f2d98a14e4139a5035ecf4c01749077), index: 540155390 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(1b4366c158dcb5bf5a9b416cf881327062682339bb6db13dbb35ea41))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2067503976), transaction_index: TransactionIndex(2585448354), certificate_index: CertificateIndex(3646125818) })) }, value: Value({Ada: {TokenName(): 12552441740616864806}, NativeToken(MintingPolicyHash(ScriptHash(3d51228ed975c19514b4f11f8bcf1f803878e75ed01337c8be8bc19a))): {TokenName(35391eed4337bea447bd9ef1f525f99dc9bfa5ea0a748cb3bbfd2c9715876625): 1179301494, TokenName(3600788453825ea4304b2ddb7575d8abff9326a66f55452f3dfb4203be9e3427): 609877132, TokenName(395db378fc56d33b3e28da1f68455a82473507e7047aa3f1f6f5e25f7bf1624c): 4063400532, TokenName(bb0baec22640b1096f65430a14405fe7d100988342ed94d40b73d1a521ac356d): 2159632668, TokenName(e867990428a8f4dcb694b1479ef2b39448287af311013575e0377dbb80adc077): 183808920}, NativeToken(MintingPolicyHash(ScriptHash(49e99cd9d95cee180c7b468834e430781c0e7cabfd936d44d03b0b0f))): {TokenName(2abdae1c2337b9c1bc424986be62f52267d7675ecc260fcb8e6f459673737b1d): 3155480505, TokenName(2c440d4964412914f032b0b32de573782682a4433180c7bb9aa3216a414e1e03): 141822420, TokenName(4720f24fa43f44926be7616861058b8e36190452a0cb158956be6908e659b3dc): 3085723435, TokenName(5a2d2f37e9a6baa7e1016c0cb1eac4f63ff5dbd57b97a0895b594c85be8760c9): 3344221632, TokenName(e67ceb5b0f0199a1f9b9d308e23c82aa2c261939e4d48aab9647ac1940ea8221): 87311652}, NativeToken(MintingPolicyHash(ScriptHash(67a17765d3a41131b81223cad0d53e560a18f58783d45997595e97b1))): {TokenName(2eb7795cd0b7e76bd99b05447bbc60da4a97d1d2a1cf762500aa9a29ad216f02): 2183399998, TokenName(33e9d80e08e035e914c82cdb8e0329be399caab7545ec96b0b3e33cb995bd75d): 1095828543, TokenName(4d4549797dd6bd2ca70832e7b70087e11d02c36bd085b79f703718cd10fb84ce): 1627164280, TokenName(9d48819ab9b6155bb41ca8c431a3ce317284b9982ea74941d77bd20e76f5a2d5): 660108007, TokenName(bdbceafa4c1a9f584a877fb01a14256f599c65e3aabeef247fc29329da931435): 1372680189}, NativeToken(MintingPolicyHash(ScriptHash(80f49de9bb420f7f65e18db26b010b18f1b391a4acd7b51701d9c389))): {TokenName(23a9b01506659529a62658bd37ba00af9244afe5675fd205e3fce00ecb1b26fc): 1479964789, TokenName(7e634331e067fa27a79a95d40b9255aec2d8107e644d72faa2db3cf1efd42c1b): 1821433452, TokenName(a30b26dca267b7e932f6131f6b8bce807eed828d4b74a08190e2739b533b3a10): 2263626605, TokenName(b753886ee2bd686df8ca7a36cab6f5a87ff3775a51421a1eb5bfc681064988c7): 1850967796, TokenName(ca3f7c8b2cd8771890fe00d3d341cb542d1cb8cdf09aee894ceefee459e73d4f): 1639961577}, NativeToken(MintingPolicyHash(ScriptHash(bdce1a0f7ad780af057293a8a64ceef56f8afbc51c01356a13974bcd))): {TokenName(0c0fccdb20591022833ca0e7708df3b0cd506a68e4b83293408bd0cec2e49d6a): 1654625365, TokenName(1cb71f74ff9debaa2251f91b962654498792947ddb105ac7e613402ec29572f7): 1271857943, TokenName(9066b032e01080776eeedc15bc2bad71f1b8a0e831d9087ea22533537730e7e7): 1269402878, TokenName(e025b7ffacd4edb007b6d8947417a539d130a5605ed13569884671248f0c69af): 3368054984, TokenName(e63c0acf468dafbae64fcdbffd6221753500b67f4df1f4042ca10a494a4b2db0): 615929597}}), datum: DatumHash(DatumHash(c8d371812b1cb8b53f974c16c45a6b9c46bcb9abdaa1e442856751a65a4a6706)), reference_script: Some(ScriptHash(c82fd2f11a9194e341c61a2ae7225ff63ffd7e630417cab5916ced87)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(c7cbef04dfc2f87d2999e1d0397f53a53027fe499a2b32edd651a6d938d6c0ae), index: 1077270253 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a71b65ef8c2ded85bd584a8e2b191bd63d6c60bbccf3421945eb4ecf))), staking_credential: None }, value: Value({Ada: {TokenName(): 7156803453470119240}, NativeToken(MintingPolicyHash(ScriptHash(1161b610c86c1e75edf3f0d038d405f8f59ba8eaecb23eef6fb16620))): {TokenName(98a4513639f157e409cad17ec3a235a735cb35ae4f5ff7194e3f79d667784c2f): 3163495675, TokenName(ab0752e01c794dd2287447e78a45d7e9b49f78e8c22942133a2e9f601fb01e33): 1210163815, TokenName(bcc334756c5974daebcd66b2998aee37c70a8569ca3438040c1d4a2fd249d78d): 487106306, TokenName(db15cfa89f63737abae9987d3ce7ad2ed4be9c8e9d3ce82aa2d3b5580e3329e6): 4253691530, TokenName(e9b9c4cac8fe3b45ebce38cbcfc262c63aaa02607702b2e27b5addeb3cbd0812): 2339395740}, NativeToken(MintingPolicyHash(ScriptHash(4e8fd2bb2a6dc8ab479e7c8bc1a4649375cd8127a3cd9ace7cc2497b))): {TokenName(91bfdea1dd2b9260abe7beb1e38cb66574d59e54b6985e1d01e33cf97c97a947): 916427158, TokenName(bc827ef5f962681762fa3aaa69930fbc08bf3417fe94388949dedfbb7f7ed4ec): 891234669, TokenName(e94eb3cf8e966322a3cce9c85282cf754af375ab0de6b06dc8023fb97e0572f7): 1598503206, TokenName(ee51f54f8d1510b9cd8d7c83953933158276d17207fca777ad298d178a513aca): 539141427, TokenName(fa6867c6d93307b281feb2813fe7ff70f4e8a8ef14f7199313052a8fca2e2974): 729910279}, NativeToken(MintingPolicyHash(ScriptHash(5516f34e8fb492032688a7b273a9358ec32b3cbcf48061c220cb4017))): {TokenName(4e90d7a121d81e3623bde4b482a81ae695caa5b475d505f078116c88bb44d80a): 1845425198, TokenName(626d9f52379dbacfb2d09b7a8c75313facc4e8ce2f280e1deec485adf3d7956c): 3593534598, TokenName(a4d4b930af00a6fd82868df4d51207b17e9b41343afc66ee8fb6b1e48facf1bc): 1311996403, TokenName(af74f5502ce5bb7a731903bd84c09461d8d241db6b6d7222e2c8b14a4205c465): 4208117114, TokenName(d13b4c2742b5678822bd7939b32ad4fb7ae90fceb1de1e9458df258b703f3062): 3037895863}, NativeToken(MintingPolicyHash(ScriptHash(b6d3a54f8dcf71c9f0c61322ba8d9572f1c47810881c1e87ddae3cf6))): {TokenName(161506d868904713582acc1df6b36e39fcbd19381a799e1af71ab5e688385242): 2340600922, TokenName(16edb18ed24c99ab83d90fdbfcc78a0fb0093c2b124e1c4b76db08c34d006dd3): 3502052496, TokenName(35f421d013e66786764f5945e355fcbbc7654d758e452b4b399a190c117f13b9): 71254364, TokenName(9088b8384e5e9fdfd8035f16b705db02059a79c6f6293adeb8f10b75ea40a655): 1823461577, TokenName(923e9cb3206fba7e9b02ae0f90c974b94317a650eac406cfc14ab6a811dc6b12): 1856719175}, NativeToken(MintingPolicyHash(ScriptHash(bf2a05f904d60252a7df18749b600e002df789ef486e9fdb71d0a49b))): {TokenName(31f826f150f88681e0f1c1e73c4a58663344449ec089476eb0deee5fc6e5ff26): 95503230, TokenName(4508b41507b3d60d806d62799cdfd6c79593cbfcc37e2043ed34403cd02b17fb): 1008817678, TokenName(5e01100ea0d776e9a3c473f8c816415883c3e75e84eb2e9c1cb42dbcaf524759): 1872868478, TokenName(a696e051c9382ac9eddc79815789b5e25f555337a02c4199c457080443e4aecc): 2154123498, TokenName(bafd57ff69329b22c461bc3b169d3190c149bc6dfc74886246a169ecf6e8401b): 2108335683}}), datum: DatumHash(DatumHash(14eb14d5b8bcbcacf39f126e689a849a031d34dd03d6e07ea437b0c2616f1a0d)), reference_script: Some(ScriptHash(49e78fa1de3cc9640d11c3f5f7f119126a7f927c2b55f680fe6fbfb8)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(ba445747b88212fb3149fd9a4e2114bb17bbac60e3e5f2cbadcfcf98)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(899768585), transaction_index: TransactionIndex(2759915814), certificate_index: CertificateIndex(4112801973) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1bff977e7da5f5ebb1ccf27789e223aaf6ebb81c25f12be7844811b7))): {TokenName(10cf1a17450644793a81563cc2fe53bc4a01d27d1c541ba1b1c0a41b079fd5a3): 779878032, TokenName(4b87861edd9328c6726d9232dba42b7d217f84539d9a0146b576f1027ceb38b6): 3901662060, TokenName(7b6084343b304f8fa95b96f6561844a12ea60fc89704391879318be2792b6ed6): 1875546898, TokenName(7c6133c8dd0340e41ae5f0d2317497a4ac4c5d50b08a16ff3bed5f6255b7e94f): 3707629028, TokenName(83de5db633ef34e346dfb0a7c38fb28d8e6272e3718aef89d87b1dd9caab9369): 2343619670}, NativeToken(MintingPolicyHash(ScriptHash(24d043b2017560d073f421021cecba5a0425a4ebc0efedaa6a45d454))): {TokenName(259a7e7efc7706e523bbad30e85c8dce6980c5867e169209e544ecc9cadf5fa0): 2895044326, TokenName(46a84240b4a1c6ef8721a4f763f0d9475d2d79d70f83ccdcce85ba1cba36618c): 1222114718, TokenName(db322ef98973afda5164ec3638450be5453baaae04fd5a54837654acca642f7d): 3738279108, TokenName(df0647d7590282ea27752b0434446c827380ff7791b9c1cc7a162552431d5bfa): 3147940003, TokenName(e3e53108ea87e41484bebe7ede167bfda6389b988e7182438598f162fe67dc92): 1985240142}, NativeToken(MintingPolicyHash(ScriptHash(71322fb14a67a2c0eb30db7083ffce94a516cbd67178ef81ee86ba48))): {TokenName(132f973fd88fa462fbb0569bf6356b4fb87eedd7abab1c09c6f54a6767462724): 22415309, TokenName(4f9297d598fed68e8a083cdc2814d31b1f9dd0b98fa6f096b3ebcea6c15b4755): 3055702483, TokenName(9726f3a59a7efd85f21fee20e83a8399b80133f4895cc7556efaf86e663ce3d0): 3426937370, TokenName(b00c59e99b9e18a80f477288887a30aa3fa5261f8c26ce0d7fb502642d01a572): 3636537275, TokenName(b61d1cabbc7baf1714dbff1b50d165b08638c53dee7ec98785569ce05cd7f4d3): 88385042}, NativeToken(MintingPolicyHash(ScriptHash(9698fab4dda9983aa171a07503c807c3f6c34624cc1349268dded999))): {TokenName(072355c208e4158d58a8d61ff048b4c2d90a19ff4918495add3b7f23ac187a9c): 1573299677, TokenName(1aed6b0a4fe3d21668cc913580c3e81b4695b2fb75bdb6b80cc644c475054dde): 423429763, TokenName(7ee6d0cc3cdef3c7d254caabfcb13006afa6de3d01d116cf58875d131bdd97e2): 267477376, TokenName(9092e84be17b25a85c1489943b195078d880a3515fd055be7e01c53fe491e0d3): 1698930157, TokenName(a1c5d50d8dd3be80119312674f25e57a871d9950afbb40a0f44cf7dbefb3423d): 345034190}, NativeToken(MintingPolicyHash(ScriptHash(9f4c36211c209a17f4efd9abf60646f325f8e7dcd612c25c504de62c))): {TokenName(0e95f2005fb3a217a8dd6eac3d86f98888e9e69c33ddf805e8305f02dcbf443a): 1351697681, TokenName(188d5931fcfe4e6445e7fa9caece48bc33477782ecfa5695605cba2f1f20ce1d): 1178440262, TokenName(c3c3888825b634b1607e7cbe7f861a419d2ca8ce43326fc8abc2e4f8172d39f5): 3300428800, TokenName(ca61bd29644ec9b78e2095e3293a88ec49c6b2e7ebbbc19dc3015aefbd23ff92): 289391054, TokenName(d5eda8dfbb617d151e13fe600c82ee3a0370beca4b35950982a6ae7cc3c302a1): 2203548854}}), datum: InlineDatum(Datum(Bytes([172, 204, 122, 65, 176, 130, 242, 101, 212, 76, 35, 122, 89, 174, 206, 189, 109, 183, 207, 132, 59, 71, 112, 58, 71, 137, 112, 254, 154, 221, 37, 193, 138, 1, 170, 244, 230, 10, 62, 69, 166, 159, 94, 195, 168, 210, 140, 36, 184, 208, 204, 11, 253, 18, 218, 169, 94, 94, 60, 143, 103, 51, 82, 39, 229, 172, 224, 43, 64, 4, 180, 151, 6, 160, 108, 129, 229, 1, 45, 59, 85, 250, 215, 25, 5, 85, 56, 226, 150, 85, 216, 42, 152, 28, 68, 213]))), reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(bdbfa23d8deefb93ffa4bf890462dbd7616b99aa2680ab1672241099))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(31619c614acc3222f75219a01ab74b3cd9708b00f62bf520b041e225))): {TokenName(678f3c6ac8db8612e9d73f057f4515ca08f7e404fa0cbcfb71bd649fb0980d09): 3589168136, TokenName(91c84501f96205bdf4b6aca99d7d2f5c709aa014800e20006a21a5cf9c59b92a): 759784216, TokenName(bae7c0271cd70340268dfabb18d6f54913d985bea566066eedcd7707d1bdc6c8): 3929250270, TokenName(c6af7d45c3b984df6b0757022f8861b152299af8d4d38bdf298b4f601cea8b58): 1029156462, TokenName(fa9bfe0586b8880408a0af9b05b40f123290a085acffcd04d81c3b21534a0e65): 2698477718}, NativeToken(MintingPolicyHash(ScriptHash(4a2c57b3c17580c1d723f832ccfc0241176153ba975e85610913a300))): {TokenName(1d2d2d7d5168c9997d4b9d4329a2dc94d47d12ebced35b3d36a06131b4fe92ad): 802237653, TokenName(200fa9f4ef1d7dc517f0403f54ebff78e8f1869a69580ed006b59555e561c838): 2312135985, TokenName(6f41355034af0ed50f3a4025f34c3899610f3c61fd6203e361cc6cd50003b20f): 569937628, TokenName(ddb162c84740652400857a798b265db775e8dbf8292ea4e046689d3a7906f898): 1871747574, TokenName(e11640b32d4d9056476747d0bb7e66b1ad3aebf591028fbf43a12f984221759a): 1080171958}, NativeToken(MintingPolicyHash(ScriptHash(640fed20ef8924e123f322e14333c773c7f1b87c6a5708fcedeb1a79))): {TokenName(1ed1e9839d58ecc982023381f05339b42dc26a5a98cb9c0c3d108436328a1ec6): 4109321831, TokenName(285cdaa0fb44838fe4c27185e29a855b17f895bdc044b73d980c39fd5289ba9a): 1479211059, TokenName(4000b3e6566ebfdcbde1f74c603feff94d530bff71a291655311580caa81706d): 1971840017, TokenName(9b95a24a591bc88f3d223c228d716148e8fc19029ab41e65de58dfa912d09c30): 744486814, TokenName(f5c3d8e8a58bbe712cbb355b0e043aee752d7fe2bea523f1cad591dc60f09017): 2299665746}, NativeToken(MintingPolicyHash(ScriptHash(69f1d75647d26ff61a254714e978d787b753c9a7db7588443090eaca))): {TokenName(5b27a5e9b66f913386a3872645aec1e61d5541124301c55c19fd3c77d4046b4a): 1010087636, TokenName(908b399df3fa67379d20a785d7377809c503cfbb186022c52e8c50c2a550e78b): 1071051906, TokenName(9e2022e53b37914365c63da9f80f65e4021f30476e0d2732301af3f97a10ef42): 1959909187, TokenName(b6941e9be539426bfee82fff33c3c712ddbc3adc1443dde8ffdd19affab04f54): 2115767810, TokenName(b7fc7f881762a1449ebe331d17fa1b5f1ebfbc59ebac954698e26ae22f418543): 1344923748}, NativeToken(MintingPolicyHash(ScriptHash(cdb588931bb9cf54a180db3b6f4c3f2a421107afe0a387fb7ad733eb))): {TokenName(073e40ae288ca3dca695d8a1d67f90cd144aaa66d9c70750f31db0730abb4b72): 720007408, TokenName(106ec0a096501f488e0971ccd91a10e82c6ec3d825ad717cbeb80d40103132b8): 1978215740, TokenName(8143fbd0788dfe619e0c6ad0fcb20b37af6db08f762afe0612129bb6edc86737): 2023491291, TokenName(94624006be92dcd0c635049f31e965dee7884809da7b283f6ebce1251452973d): 2458305516, TokenName(d2485a5e03eabc36abb9f53605c126743f0e1f93ce238c5d02a6515962eb9498): 2130436929}}), datum: DatumHash(DatumHash(30baf44468c67d2ca8c71cdca08e011c5198f3ed6dfa5f32230106fc689b8730)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(e6bac9a34c5d8e1d87f4de324bd290972466b8dfc37cb993cfe4994e)), staking_credential: None }, value: Value({Ada: {TokenName(): 2345619003581031683}, NativeToken(MintingPolicyHash(ScriptHash(691cf06acd0567c9e228a3e5464163b72cf74df61b3854be97fa4a4f))): {TokenName(3ba833e2f71598e57b6b3e56680d073f4d202ead017e4c957ba263f808e19175): 982856673, TokenName(4b5d85d9a851ba616ae76c36fb7a9b8767d90dca49997135e3c7a7553391448d): 2722557260, TokenName(e9beeaac7ecd8154d4556eab163516d2f23f6b14f1b0df35b3991becd729c8d0): 2236608870, TokenName(ea139e8a13a72295e43c47471b90bc1c60c36e1e395fd7fe291899f5d9f839c1): 2111553428, TokenName(f133ec5ce25e504fbea1b5f07eb81830b6aa51ef0a444a7c66826e445d270067): 567966558}, NativeToken(MintingPolicyHash(ScriptHash(6d6bdc127e5a142df4164a58634ed279ee23c7dfc4d1890e01f710c7))): {TokenName(120399209c28732de97fca2258f0a5882ab7a43e4908c6d90200c020ac475654): 2232606251, TokenName(1c016c718141e3e32287e07e21006b28b198f4209da3d7eb9e5df107ab6b935a): 1783983425, TokenName(7ba4b45f6dcf0836bcbf8c28ae5baf0ffa628feb868c080f3c6b7f8fae3ce2e7): 1880185242, TokenName(b33032b9cce3b8a353d8decebbc8b4e3098b8d7f175cf7e4caa49fc0960f8285): 2946189586, TokenName(b68f1a7ae21895c735848a47919039dac10232e7c0bad7dac31f763298cdf78d): 2148785780}, NativeToken(MintingPolicyHash(ScriptHash(95ccc105961f20b642d496575c8618ab45778aafeff72114eaca3c87))): {TokenName(19d50a0aedd0c0af9f4962fc29848afea286e8a25cf76676b72794055e5cdf24): 3486082732, TokenName(4ab6a7f6672103b16e90215284bcbc305cfa09efca1cd7d5830c85fbdb1e95f3): 3539097440, TokenName(7b7b96f68731e738219a3d4a9c06443ad74aa5bf064d682ad74f0bac2485181f): 3176132363, TokenName(cde11ab41bbd39741a04004079f2eaff3e99e2a12bd84af790a392e84aeb7541): 550985563, TokenName(f5bc1a1db541abcedf99c4ff89fda1e0c9db9006b07ab1c564969aebebd09a22): 4087481348}, NativeToken(MintingPolicyHash(ScriptHash(dac03c917ea11a9a5a2019f0ef38dc71f50ae6da4fef7ab249b59a92))): {TokenName(255915696336604e690d5cdcd5e8caefc8c2cc7ba14c4ecf90d14b27e3cfc127): 3785128112, TokenName(2cba8c1eabc7864239d980f529ade5101532ea8fe09d77203c91f61e34c5fcd7): 1135484162, TokenName(b2f11129a271944764222ccf1cc2198da61fffb57d369387682fde0f20f34879): 2814977963, TokenName(bf7e8119e2b3dec3d6cdc6b303139e166939312940949de45c5cc4371ea7a907): 1892917545, TokenName(e20e58faba49eddf0fcf29cd18de169efd245c4144d6c3f3c90d6a20901913cc): 1380583014}, NativeToken(MintingPolicyHash(ScriptHash(dc51a951d79cfe5723775a9b68ecaaf914c0bd4ca333c97a33bd5a78))): {TokenName(1b4c96c4f76fb3977b8ac414d12cca36bafeea1b18c9332b6527c567b3dc0ad3): 4047894026, TokenName(4a251d7b17c1688b67436848f4b085a6e85787cf4367db02f1f339f0b639d8a7): 2105094856, TokenName(4b657838392205527c62f57656ccbb43b8ebb557e56797a930c6b007d60675af): 3999884748, TokenName(d22e85b376f205061b77fdd8635ae3519b91277e6573aa5e05404502c092a9a9): 1098536676, TokenName(f7f65974967b3c0f0b59ec46ab1e39f4b3ef7a01b578a9a6be72aa1e2b612979): 1852889996}}), datum: None, reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(8a1f70957ecc5bcf07237a514caff635f9756113d819f5d76f699f51))), staking_credential: None }, value: Value({Ada: {TokenName(): 1875050608586845498}, NativeToken(MintingPolicyHash(ScriptHash(5ffad07ebd776892eb9cf70be33ff89959ac8bf23e9144aec3dade9b))): {TokenName(2c0e09f291d5fe4e56308a4d053a30790d8180afe401474a0a9b8d9a68fe84b0): 3419174824, TokenName(33d20e7e257e8115bafc6277f1528150275d7532d1f4d40a84160e83f400d09f): 1233415608, TokenName(634c0f9175f3b7f80a68e4d6d0ead26c37259ba69359e4e045f22f99c93de76b): 502702735, TokenName(7642483c7c5b82394543bd6a0e82e39b511473fc0b11aca15a739e0334548573): 1957847211, TokenName(fbb16ae3311e95d9824500586e2d40ef71fd93b9e04b92baa6b629c991445644): 3743842378}, NativeToken(MintingPolicyHash(ScriptHash(a7e61d902489094101ae4065dd67f63c8e194e7d04c4e3780f3db47d))): {TokenName(1cc2fdb067c066553991327877808728bd064116debb5db6a475d37dd6b65435): 582182882, TokenName(5b42bdc1cf920a6926365f2d3c2ea62ba7196bdaea0381e879e0cc1064f63edd): 1077275549, TokenName(6c896858fb9e11506a9e7a7ed52728f9ceb432ba5756997be71e0728f35c2d84): 842216307, TokenName(cd50b8569e102c9b1227161ce0e12705cc399b70706ec78e4f64a19a34511aa4): 2394710341, TokenName(f5be742a06da27af05d251af4652feb6102a306824a66338f074fab8a13b1719): 1958201718}, NativeToken(MintingPolicyHash(ScriptHash(d0a6bf87db69adf84ce36aef9ef5befd4bb6be47a124cc219fd76802))): {TokenName(07c3d821c1485fdcb00810a3b5c141217252c61a24513271f30741078029f92c): 3890529542, TokenName(229d8d778334b7f0a3988987575c2e6c9738cba75d8bb04241309cac0ebbec40): 1630686667, TokenName(2703fac3434f25c23a336dbc8c60ee952fd606d485a8f1d14f7d45278f902876): 2142684854, TokenName(43b46257959c0067e91d1678d6d1928031584110bc425d362de0f470b3bbdb13): 1155914263, TokenName(57498f6d566edb2750b7786de3273213d38d784edc1b5663795af6d83000df05): 3798578233}, NativeToken(MintingPolicyHash(ScriptHash(df3d1ac555fe681926052336f96b7237f896dc98b5fd45ed98a4c118))): {TokenName(0aa392ff72eb2e15bd76f081ee194e9c92ab0c5a9cf13f0c1afb98c5d23f923f): 3632623055, TokenName(37988b88ccfeebf8c96553676844d522808a9c189a93a1faafd75412ae41b1cb): 2529992407, TokenName(8cbdd7d69d4dd33c5fa25020b6fae979778c101ee1d15a021de2c4d2f0205f90): 1159873407, TokenName(ab3e2eb78d15c89f7534cef7f735391072821ef558368bdb99c1362465f8fdbe): 2838666169, TokenName(f9b27d6f3432e9dd010ca1dfc51af6b592f1dc6be77f85f1453cc89c0d5f794c): 320800172}, NativeToken(MintingPolicyHash(ScriptHash(fae71851e0c869d670710c4cd5cc380cda0b6c77cc12bc8d404a088a))): {TokenName(19561f4e59d0b31c731632465805369636a0d830fd373808d343c881a515a98c): 1523624715, TokenName(4b95c6d6eef55e7860333ca1c77fbaf416ea40462e464d4028fe1bb6d9fa8a8f): 2672564629, TokenName(5e857d5d57f459d890316b3d7279aa5c90ff56a7ee089c93f20558898bd56d8e): 2676225451, TokenName(d0fd43d731f7636b964dea6b8c80a3d5318b285d65fa18cd2644343ec79d0042): 2068220055, TokenName(fcf5a2a03633681227d43c0168f905c4b67d3bef71fb713d18f169a2b718d064): 4168155326}}), datum: DatumHash(DatumHash(826d7a66d45db89c49132f6f0d47bb60dd0c671eed8bba33cfd1cf722f0752d4)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9f5a9609101b26415da5bd82fd838ccc530fddee001b04415f659a21)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2202497918), transaction_index: TransactionIndex(2126350206), certificate_index: CertificateIndex(821134753) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0c6f149015fbf25e0bcb8a612d06d075c985fec2854fb069ecbe5d67))): {TokenName(0fbada78724dddfb7dca902d36487563632ef647b0d12b7d286a6252decf855b): 3328392272, TokenName(29f966bb059400c62d419aeaaf87f7b152261133371b3ac137b53e07c428efbb): 996923888, TokenName(57fd19bf614e4a3e5ba431ad041b359b8b74b8c58760c665504f937ec8fba8fb): 4136587877, TokenName(59aaf95e06f3bcd456f1838b11dbe8d68365b7dc64093a9dbdd9c9cb41c5e4d7): 3090979415, TokenName(d2ae5bf39dd75fca8e7f26bd7344898e5f42384f36c76d0d86449ca7d1cd6e2c): 3907724448}, NativeToken(MintingPolicyHash(ScriptHash(953d1aa7c8a6597ea255436096b7b8653d3ef99af22584df3be25b9e))): {TokenName(160adfb15854c5ecd6adfcaa5c6536461b42af6d802908dd17a33c6da70015c6): 1063620687, TokenName(1808a791db8b06d9152eb2b36b5b1593e20f11d2a4a4e3e29d567c664a40638b): 3788863571, TokenName(7f39bd22a48bae016ffea03a21da657edd97785eadc12c044ce8e185466e6e33): 3102480397, TokenName(900b2383360942743b2d715045286063849c0fd58d0baf4218cb1bba36f239e2): 2873646979, TokenName(f1ae7c12c75370249b24a2b4b6a0bcd583e67f08933c5372c87b999913c91bb4): 2416656345}, NativeToken(MintingPolicyHash(ScriptHash(bba45db883e225c91725659b7cbdad0b4e3ed6fd762a880e757db587))): {TokenName(1e234a3b4bdf50113ecfeb00d6499751654ab66e314e26d453d7db2ed89df561): 4141472780, TokenName(344822f1c18b6021081821ca1d8a6fe3dd62b1966bb38c5596604cc4d857c6f9): 3120952892, TokenName(df630d96f19a6e9105a7192f1d5d5d2d5c0b087ac03332fcdbd560100634e5f3): 639708949, TokenName(eb3ba991372a4a3d8c55f27ffe66ac4eef04b7af7daebea3d6dfac437fab9384): 2233927639, TokenName(fe0b8f25d4e3823f5f33c2fedad4b225ce9e1402bb2cba591091e4b9b3fc5350): 2923985628}, NativeToken(MintingPolicyHash(ScriptHash(dbc813806f603986046859c9a1233f82a60a5d5be22875c7257829e8))): {TokenName(223da369e60152a4eccfba4f5e66dec74719a7e11b707ed045b2722040d387bc): 2816803314, TokenName(466e9624f30622c39e429787d8dabcebc433cfd97ee8f74c7fcd30eca007ad47): 4241284657, TokenName(b59a08ea8d7638266fbc88937361c010fc97a487be00e214c6a27237aaecc6aa): 2793411479, TokenName(de16ee01ccaf7bec5d970f7f8eb406b30a0a519d7a21ef8f13e619435fe51359): 3457509201, TokenName(fcb79dce7287c26da98445c5633171009fccb8f5d4a9e10cf7fdb8cc2988e9a4): 1973183991}, NativeToken(MintingPolicyHash(ScriptHash(f93c4aac2c238a53839dec1f85e0f6d7b0f794a5d26d5a547335a57a))): {TokenName(2044ee496ab8736a05cf92574c9f02947d107804e3be9156606b614f379d7d4b): 3903125479, TokenName(7daa60cd5695a6fe07e4ce83510aa5948b8af205eabf83683dfdc8a546f5caf2): 3447520966, TokenName(8836545aa709f54efa76dea09acd6cef5e79aae6327a92241a0a1f750ff75284): 766065464, TokenName(b49ed50fe0f51d3331947f589665125b77728606188fa49956a4d70eac4a2253): 2263306418, TokenName(d8f448fef891d6c37018e9c7e77d80fba9df64e4c0818af64306c777c36a9ba8): 2507925515}}), datum: InlineDatum(Datum(List([Integer(18341390424677414674), Integer(-15188219571950571493), Integer(-12618291903575643987), Integer(12604060985820067889), Integer(1711885320080205276)]))), reference_script: Some(ScriptHash(567a963be3f865a25e5a36ed088b020dbc7ee2824c99f1061f0c470c)) }], fee: Value({Ada: {TokenName(): 15803115623070617160}, NativeToken(MintingPolicyHash(ScriptHash(51af9658be40865278fd47f42d017d860682df63a06f1c0b6e14864c))): {TokenName(00576a3a5f458896aa30b52876cfb69549af50f0058f1b28560c1e3530f7f655): 1891164644, TokenName(346fe26f4fcf7436e8d3d1d94159a86a136beb779d05e610474ea5a5fde683a0): 231309602, TokenName(6a030d5bd54aefb998274c8305eb4915b359a58fa39aec5ead75b67ba94a51c4): 1408961262, TokenName(e368b8e6a939313a805442efcf28bad130952f255a3c0e554acf962c3e925eb3): 2028257270, TokenName(ecb5162c612556f713b3d434a6fa8b7f4dfbefa787c8f9ee8340c335a2f95ead): 2505255268}, NativeToken(MintingPolicyHash(ScriptHash(59a48ee567ffbd294754a2e58ded4ba6ab3f327cd8c7c1f1bc6a8701))): {TokenName(056aae0d11e020963fde9202797e0ba7a6155a5e03a9e40f06ed001dff1f868e): 4062212792, TokenName(6398b5866d75538c40b3114713c7e6e927b19b777e69ab3d85d585ba683e39a3): 179831580, TokenName(a32be848542f1c36fcb05fd76957d93f9a3753e35834d0cc4cdecda2c959c713): 2573060774, TokenName(da053c704706ab24b9d4d6279869447c0609a973850d7cfdacb0b5650bad39b4): 1744184575, TokenName(f8a507a37d0c9f936d3fffa96a9bffdbd7b7c458c6d7e8db3bbdc1c89abd6889): 4216496880}, NativeToken(MintingPolicyHash(ScriptHash(67a0397effe1d763f3065fff9555c652dee27c9c3b08bb2dc34544c8))): {TokenName(417ef25e64dc8bf269771508b80f09daf2c793f2761acdac2447c5f4230d8964): 68891500, TokenName(833e13de8f099d6438ce362f4ebd4011e8583dd1d08c3105b51856db4fed6d72): 2842042184, TokenName(89e79630f1a370d4a9dcff62a4b9e733f65d77a189c68cc92b976a8b47ebc458): 124004641, TokenName(a6ae571e2be0904fdf544d2c1050771e23d265fae40e61d5bcb43fb913e1868d): 1140594532, TokenName(b6cb38fa26dd3c6d4e44bd30d92cc0df4ae412db903b3a12c6c562d8830dbcad): 1884238911}, NativeToken(MintingPolicyHash(ScriptHash(6ec5286b5cd9e1d99247cb163669b313fdc2bcd00caf3748bd2cee4b))): {TokenName(0368a5459a02f850ac1a593ce239f37e2c8b086be8af88d965a82f0a67d9d82d): 2103763571, TokenName(4b4d7e8c41ed1e4824ec752ec88a0f5dc5d69ced7b42fa86f12211626aa90053): 1150630860, TokenName(6a845f861fbd500421b52b4d3be75efe66be526061f379c2517f3e30d809ef37): 611065587, TokenName(9581c41d62560ae5e71cdfce8bb299dd3813e640c2929d4fccfb72cf8153f12e): 2733787951, TokenName(c00bfc5e7fd044062e6902173586840a2fffdd4abbf25ff2b42aa1d4b02e41dd): 2640075632}, NativeToken(MintingPolicyHash(ScriptHash(d695c62120cd646fc72784bfb336c3c16d6b42ce98120c34ea8f7886))): {TokenName(0299561ef7c9a456e1780ba3804163bb2d9693e0722c89902b0712c0e12611f6): 3896231851, TokenName(0e6c1a5f6061a79284b3ce2d29bb0db5e06d95921035dc94dd495a0886c40040): 715083743, TokenName(9af7bdc7bbc9c28f9d17174cf8aee887cb08c7f839aeab22b9f680fdd3f0f938): 857505909, TokenName(c3e407bd1fcb3952f0489287ffe4ef81321ff1bbd120b601fe81edae5bd58ac8): 3247714681, TokenName(e5297cdb851b5d5d782a6885c25b2e459a03f14e8b816b40345cd2953af034e3): 67613300}}), mint: Value({NativeToken(MintingPolicyHash(ScriptHash(333113c894fe11a52f1141e3e7b9ee9ead73a981547e952f654e4bcd))): {TokenName(31b5a8c6e22bbf81e0e8580d4419d2a8a9c8410594ddf13a3f587200ff3bf99f): 3510970424, TokenName(39508322dcba87e333b88e27561450e92b9ed21f07c85897d0a5ae27a6328037): 2623597566, TokenName(3f27fbddc77e5f31716cea0741ca384aed2e0beb2f0d10d42e841d6555d416b4): 4223901033, TokenName(bf168eda2ad99e4ec1f18925c00f61ee99764c3849e1c828d332cb6e4d8c2866): 745442573, TokenName(d86514ffb5f7395ac2345689684e2a49efeaa199979ccf366e6303ecae38de2d): 2070654651}, NativeToken(MintingPolicyHash(ScriptHash(4855f437d5b8f64369d4f22448101a2a90d400d6465befceb9f7b644))): {TokenName(329a1bf5d5969a43640a8969f8be7ee09cd2be00534eafcaa963995dfd74bd99): 1939130107, TokenName(a9d2be008e98ad835a4cc68913f50a5ae80b370d78510fe7a1ee488d2aab3589): 2400496195, TokenName(aaa74287e48b6fab53ad1581a6ef7ee6ce2f86692e0175071371e7232c9af9fa): 3336964384, TokenName(b13d68dddeae7aa3eae33ab1929804f9181b521283f7d137d61ba56b91ea7adb): 3587800286, TokenName(da96e9444c0fda9a2bfa20da460fb30cab627a8a3cb912d881e44f062a8076ab): 1083941161}, NativeToken(MintingPolicyHash(ScriptHash(ba30dda1dbcb2af4319fa18f3f97ee4a40b881e94d83f735350212a8))): {TokenName(126b2ba20d350849e97d2ad5535debe2ab61f8192117539aa08a0046786d5184): 2037947589, TokenName(2d2f0c2fab2b10b2b2142ceef43259bc0a33634d19070a63843cfa9f725f6987): 3683714516, TokenName(3f17cbd53d6c15154066c664668fc69664f13a8176ee62d77d91b249844310e9): 1356465783, TokenName(7163f2327a83e4a8e60334cc8359fadd1c4496441631fefea0d3748cd47cb095): 153963067, TokenName(8e849037f18f4144bf0dc017fef9b889c5521f5e635e0dbed6afac762996e0b5): 1439049856}, NativeToken(MintingPolicyHash(ScriptHash(d2887e00d8e7aea32a0b0fd2bdf41f71f06cee73806b40ac6a8aea16))): {TokenName(1178f53dbac3ef33fbb8dd891c8e3576d616bce31de995eae9f666d14f87d538): 3700885807, TokenName(2661ee1a540c4da700f528edfbfaf601f132ab14e4380f5b8ccaeb25bffc8677): 3840572024, TokenName(4a490ddd6dcacdecd2daa50b57463ee62203d3514bee6bdc5801f13529bf868d): 2529075641, TokenName(c36f6439b01b042fedd05714e11d3486e6458c62398a148027be8cf7a70a69a1): 1293554079, TokenName(ca8ba4a96cea31e139f9e7e7cef3769280c7750c44ae24974179c58086912d95): 1370877010}, NativeToken(MintingPolicyHash(ScriptHash(de6e84d8a6687b9d0448ab71958dde1d1f3f3eddd3113862c3216d53))): {TokenName(2b27b7e3ffc5f0fa11809739b7dcfa4f0174375506be1ea4c26ed74a12c4f85f): 1503890893, TokenName(2da2fde1bb357aa579dddd8f57d6c399786519ac3de7a0126e01b3018eaf8b91): 199024162, TokenName(3755b21f2864e630e52af59406dff60761821a7f3da2e59140e41aee956031a9): 1152035766, TokenName(85df67e42252466fd8c73c04155ffda08f1aef716440c8a09e26701f80d78363): 1718120637, TokenName(8f07d214cdcc525faad400498aab4495bbcb2543f388e8c9b9efddac617d6d94): 4225038705}}), d_cert: [DelegDelegate(Hash(Script(ValidatorHash(ScriptHash(2026c1e7a5a9312222e66a86b1df6a56c74f0f54c7380649503be4e9)))), PaymentPubKeyHash(Ed25519PubKeyHash(7eda1c44fd39f1ce8aa1c9502b43dbdd0a1f787c42940a7ab77a588c))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(2851043036), transaction_index: TransactionIndex(2709126557), certificate_index: CertificateIndex(715274452) })), Genesis, Genesis, DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(761337367), transaction_index: TransactionIndex(3811942017), certificate_index: CertificateIndex(894925047) }))], wdrl: AssocMap([(Hash(PubKey(Ed25519PubKeyHash(de3d5474477888f52dc73c3219a9df08929721720c1ffbf7778b46a4))), 1188800935), (Pointer(ChainPointer { slot_number: Slot(2561259123), transaction_index: TransactionIndex(4083476119), certificate_index: CertificateIndex(1585308347) }), 263857381), (Hash(PubKey(Ed25519PubKeyHash(87cebed31148f5e0c6434f5b29f19ed709538c4b86addd8930b2aed7))), 1856686000), (Hash(PubKey(Ed25519PubKeyHash(68d692439b1d02991261428f3565deb31e19b207de1670aeb001b348))), 1338798631), (Pointer(ChainPointer { slot_number: Slot(132451218), transaction_index: TransactionIndex(221312802), certificate_index: CertificateIndex(3760676452) }), 3400108145), (Pointer(ChainPointer { slot_number: Slot(2964679271), transaction_index: TransactionIndex(1953655207), certificate_index: CertificateIndex(3832592502) }), 217527895), (Hash(Script(ValidatorHash(ScriptHash(5b2bce504e16c9d1b9f1e72fb9da01aa37f7369823e109516c44c1aa)))), 3742334973), (Hash(Script(ValidatorHash(ScriptHash(939d095936089874fed61fbcb4b6ad1bdc13a2ba2c557fdbbf903732)))), 2677634697), (Hash(Script(ValidatorHash(ScriptHash(f1d99bfe32b36ee4ea5d278329b23a99fb119823517f69277c78c88e)))), 2637902573), (Pointer(ChainPointer { slot_number: Slot(3188648279), transaction_index: TransactionIndex(3069628652), certificate_index: CertificateIndex(2280472759) }), 3561615259)]), valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(1947697823)), closed: false }, to: UpperBound { bound: PosInf, closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(84232c9099056f56e6a0a9f0f749f65ea5c64d2eb528daf7e8799df1)), PaymentPubKeyHash(Ed25519PubKeyHash(6e8667593ac31ae80eb81d65f51f07789992ff9ad7aa8b1691f71f30)), PaymentPubKeyHash(Ed25519PubKeyHash(8ed98e3eb6fc1940eea87da038ee40b0f1b692e2f901638c4577e739)), PaymentPubKeyHash(Ed25519PubKeyHash(a93d3a6ce845817e502b34057e09cd1126cc2003a2cef4ce492889da)), PaymentPubKeyHash(Ed25519PubKeyHash(fbd74df32d509d3534b1eb660bd9b2d756207bfb1e97116134c794ff))], redeemers: AssocMap([(Spending(TransactionInput { transaction_id: TransactionHash(3684758d3317af19ab7e0f19f5f060b1b3d85abea6b07b5c39f2b5494895b7df), index: 402668050 }), Redeemer(Integer(2810963777676229418))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(175fd4d257035282bf6cc6aaf5ecad5e14f33cd271603da5a9023c30)))), Redeemer(Bytes([174, 91, 255, 132, 236, 210, 74, 206, 199, 181, 33, 217, 105, 3, 55, 121, 209, 111, 245]))), (Spending(TransactionInput { transaction_id: TransactionHash(45597a6c4ada1ce6df045684b4ee6c1582930205ab9a922e4e31e9ba5396d984), index: 2195186866 }), Redeemer(Bytes([155, 103, 42, 214, 236, 40, 73, 165, 239, 119, 211, 29, 147, 176, 117, 7, 28, 206, 207, 208, 249, 171, 103, 247, 248, 61, 137, 254, 220, 50, 154, 132, 101, 60, 15, 72, 17, 155, 23, 70, 132, 1, 81, 83, 120, 7, 69, 180, 132, 97, 114, 186, 220, 171, 103, 86, 23, 156, 194, 217, 142, 55, 150, 88, 10, 223]))), (Spending(TransactionInput { transaction_id: TransactionHash(f7060289b31d2eee6dd60a50f49781e9f797c0b393dd60daab103b8d3fb3a889), index: 2516227782 }), Redeemer(Constr(2228932073, [Integer(-10040748169353365345), Integer(-16348844488077936941), Bytes([118, 93, 98, 129, 35, 22, 191, 164, 62, 30, 202, 33, 85, 193, 208, 111, 241, 39, 106, 154, 19, 219, 98, 56, 12, 246, 117, 89, 106, 46, 233, 205, 11, 175, 53, 10, 6, 2, 31, 95, 164, 14, 60, 19, 178, 150, 29, 233, 66, 93, 85, 173, 148, 167, 108, 49, 175, 34, 103, 17, 119, 89, 95, 164, 147, 83, 198, 248, 64, 131, 74, 211, 39, 75, 73, 29, 53, 18, 140, 103, 143, 10, 54, 33, 144, 84, 101, 98, 215, 250, 206, 78, 102]), Constr(158106493, [Bytes([242, 195, 61, 243, 253, 83, 48, 120, 89, 168, 176, 167, 27, 231, 203, 105, 129, 159, 133, 196, 149, 178, 212, 61, 147, 8]), Bytes([121, 26, 202, 42, 214, 164, 29, 215, 24, 55, 57, 90, 30, 226, 5, 155, 51, 187, 84, 51, 73, 214, 246, 152, 53, 233, 111, 179, 151, 54, 188, 164, 72, 17, 55, 221, 183]), Bytes([82, 208, 81, 26, 131, 41, 237, 37, 232, 32, 197, 229, 84, 37, 15, 29, 56, 227, 100, 46, 7, 217, 39, 189, 187, 175, 191, 31, 54, 199, 219]), Bytes([5, 147, 3, 242, 139, 200, 16, 190, 224, 198, 251, 71, 91, 209, 123, 30, 12, 148, 231, 171, 144, 241, 128, 20, 133, 6, 48]), Integer(-16674154303761446734)]), Bytes([20, 244, 82, 105, 235, 25, 226, 247, 129, 240, 230, 48, 237, 54, 191, 180, 45])]))), (Certifying(Genesis), Redeemer(Integer(-6322583901471666111))), (Rewarding(Hash(Script(ValidatorHash(ScriptHash(5a2229d81a04f63baf4be9ce6823eec3f236c98e2f96c2a8f41c7adc))))), Redeemer(Constr(2108123717, [Bytes([48, 143, 62, 144, 22, 28, 118, 97, 5, 243, 108, 134, 212, 235, 67, 31, 91, 156, 207, 64, 227, 71, 29, 152, 79, 46, 155, 69, 96, 133, 136, 90, 108, 212, 102, 152, 80, 253, 230, 208, 247, 38, 230, 128, 173, 79, 132, 251, 104]), Integer(-8068460302907919505), Bytes([230, 22, 48, 43, 56, 31, 65, 114, 46, 61, 233, 217, 124, 158, 221, 38, 8, 156, 148, 9, 210, 198, 197, 224, 133, 20, 221, 192, 28]), Bytes([200, 255, 188, 74, 6, 165, 182, 28, 113, 173, 107, 255, 120, 129, 167, 2, 19, 155, 246, 49, 226, 105, 38, 110, 217, 136, 231, 16, 69, 214]), Integer(14568000902052266110)]))), (Spending(TransactionInput { transaction_id: TransactionHash(e3c73cee29ccc3a93f4908faacd2039c80e6e11f4af461609357150e1ccdc9f7), index: 1997757407 }), Redeemer(Map([(Integer(-12617781173585543840), Integer(707927533030626591)), (Bytes([87, 37, 253, 91, 240, 70, 15, 48, 131, 76, 16, 79, 136, 70, 70, 78, 172, 177, 143, 150, 204, 99, 121, 161, 162, 154]), Bytes([152, 43, 219, 158, 55, 149, 84, 234, 246, 9, 94, 13, 170, 138, 189, 57, 16, 37, 238, 118, 106, 30, 143, 67, 67, 4, 248, 251, 68, 243, 156, 97, 67, 111, 96, 51, 90, 0, 159, 255, 37, 228, 89, 6, 253, 99, 190, 181, 96, 128, 180, 20, 248, 23, 21, 179, 52, 154, 126, 179, 194, 77, 90, 64, 73, 138, 210, 232, 215, 183, 4, 18, 181, 213, 58])), (Bytes([79, 154, 247, 87, 37, 204, 80, 46, 89, 234, 172, 52, 5, 191, 52, 130, 85, 170, 76, 22, 242, 207, 207, 30, 142, 90, 100, 15, 55, 165, 53, 205, 251, 71, 175, 222, 244, 80, 34, 62, 132, 223, 123, 198, 192, 68, 196, 141, 190, 198, 87, 229, 189, 51, 141, 171, 12, 53, 91, 198, 37, 25, 246, 92, 152, 89, 128, 43, 234, 45, 128, 68, 207, 46]), Integer(-14322734530933966339)), (Integer(-3861535558087861398), Bytes([111, 41, 2, 76, 196, 41, 156])), (Bytes([85, 81, 119, 35, 33, 228, 212, 131, 254, 255, 32, 126, 133, 24, 188, 74, 128, 66, 21, 125, 180, 215, 36, 14, 79, 226, 249, 63, 75, 180, 149, 208, 146, 42, 243, 2, 144, 135, 62, 126, 127, 197, 227, 169, 79, 219, 149, 139, 213, 60, 122, 208]), Bytes([118, 214, 241, 123, 244, 200, 9, 151, 218, 221, 87, 178, 16, 107, 48, 16, 192, 199, 131, 111, 9, 182, 13, 37, 202, 47, 135, 184, 246, 146, 245, 12, 215, 67, 167, 172, 223, 212, 149, 99, 144, 182, 16, 178, 188, 146, 235, 109, 215, 116, 233, 23, 82, 149]))]))), (Spending(TransactionInput { transaction_id: TransactionHash(62c42e4202f656c5bc421000ca55519453b3baf0cdd7939350b4714a505b6e63), index: 2111527653 }), Redeemer(Integer(16458574750339611711))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(cfc4818d9f1d2b8846520e2483eac0a3c1e73c74626f767efee3eb30)))), Redeemer(Constr(2140196213, [Integer(15708456767238457497), Bytes([122, 118, 45, 12, 134, 125, 206, 188, 13, 26, 125, 183, 190, 94, 85, 69, 90, 224, 199, 233, 45, 227, 21, 185, 2, 145, 49, 184, 113]), Integer(10944798376073413757), Integer(-5781556765119698737), Integer(-5775803905611332833)]))), (Certifying(DelegDelegate(Pointer(ChainPointer { slot_number: Slot(1535946222), transaction_index: TransactionIndex(973501788), certificate_index: CertificateIndex(1721835424) }), PaymentPubKeyHash(Ed25519PubKeyHash(8da7434927217fad2dbc685e7dad4061ec2446602a443024505e085a)))), Redeemer(Integer(-105968194133868962)))]), datums: AssocMap([(DatumHash(3f13f0f11489a611f86854e1798b705dd42e223dcd41cf122b05b747088df20a), Datum(Map([(Bytes([118, 161, 39, 170, 34, 79, 212, 83, 167, 238, 67, 67, 185, 243, 138, 101, 174, 188, 204, 187, 12, 126, 60, 238, 79, 239, 170, 171, 228, 2, 248, 6, 30, 98, 242, 74, 47, 48, 224, 207, 194, 177, 8, 43, 97, 98, 176, 12, 149, 193, 103, 18]), Integer(1977499462978565508)), (Integer(10862498357460938208), Bytes([])), (Bytes([67, 12, 8, 166, 225, 88, 2, 238, 247, 93, 98, 86, 56, 50, 64, 102, 127, 141, 197, 139, 108, 146, 176, 236, 141, 156, 200, 55, 183, 106, 24, 97, 33, 55, 134, 129, 99, 150, 169, 142, 128, 135, 106, 162, 69, 26, 240, 100, 110, 218, 87, 86, 167, 120, 120, 44, 10, 229, 36, 95, 24, 174, 110, 117, 93, 134, 234, 60, 107, 157, 243, 227, 238, 57, 78, 254, 100]), Bytes([118, 181, 227, 178, 88, 220, 250, 9])), (Bytes([49, 106, 11, 48, 139, 75, 97, 236, 204, 210, 22, 64, 193, 204, 10, 142, 78, 223, 187, 250, 174, 115, 174, 255, 237, 96, 134, 215, 167, 181, 181, 46, 208, 35, 18, 220, 218, 202, 234, 200, 40, 69, 114, 132, 251, 216, 101, 15, 243, 21, 175, 13, 14, 225, 55, 191, 74, 187, 218]), Bytes([158, 73, 152, 185, 193, 123, 92, 130, 151, 32, 167, 168, 198, 205, 25, 174, 41, 76, 41, 187, 76, 26, 243, 192, 137, 127, 166, 40, 164, 253, 40, 21, 224, 55, 145, 89, 166, 140, 219, 94, 46, 213, 40, 183, 164, 44, 64, 211, 69, 108, 31, 162, 223, 59, 190, 37, 228, 74, 200, 146, 193, 210, 63, 12, 18, 21, 219, 188, 65, 211, 8, 150, 10, 202, 79, 62, 120, 79, 166, 175, 235, 221, 86, 233, 90, 56, 133])), (Bytes([167, 85, 73, 175, 24, 104, 70, 32, 188, 82, 35, 33, 38, 46, 206, 145, 16, 109, 229, 184, 122, 246, 16, 104, 137, 149, 13, 161, 11, 81, 119, 34, 174, 95, 234, 93, 187, 208, 174, 42, 15, 116, 27, 30, 23, 195, 184, 134, 138, 141, 153, 84, 122, 173, 49, 31, 157, 228, 111, 132, 171, 29, 249, 213, 125, 51, 162, 171]), Bytes([173, 43, 61, 171, 40, 132, 160, 0, 51, 38, 60, 156, 84, 190, 38, 250, 42, 247, 134, 141, 15, 1, 196, 220, 95, 69, 182, 97, 217, 254, 96, 149, 68, 207, 173]))]))), (DatumHash(2d3b3784524ee6b3209de5f067eafbb855ab2fea6d84520bd4c498ad3bb4a9bf), Datum(List([Integer(8367189122487879926), Bytes([85, 73, 133, 238, 111, 220, 15, 18, 34, 163, 152, 66, 155, 1, 153, 190, 23, 83, 30, 150, 251, 76, 114, 20, 47, 119, 18, 159, 134, 192, 115, 230, 52, 234, 155, 13, 215, 6, 248, 17, 51, 29, 215, 86, 35, 160, 223, 109, 125, 211, 26, 104, 87, 162, 115, 72, 13, 229, 161, 209, 221, 69, 127, 153, 191, 239, 254, 213, 190, 148, 126, 34, 248, 117, 0, 79, 198, 252, 69, 21, 103, 203, 238, 38, 166, 112, 197, 236, 29]), Bytes([39, 11, 165, 215, 13, 7, 168, 38, 171, 158, 216, 76, 205, 219, 175, 173, 48, 249, 55, 120, 163, 252, 3, 212, 100, 14, 72, 36, 250, 217, 182, 224, 86, 144, 68, 194, 171, 125, 18, 95, 195, 61, 107, 252, 44, 39, 245, 35, 250, 44, 178, 100, 200, 35, 0, 48, 63, 66, 113, 222, 254, 104, 87, 211, 218, 133, 146, 5, 79, 181, 128, 131, 143, 239, 41, 184, 153, 133, 201, 49, 186]), Integer(-9962985770080429271), Integer(3300264540542865748)]))), (DatumHash(8ce152b89a27ba57337b595010a34f555046c8c6cd7e3afc906bc4c94a518acd), Datum(Constr(936155300, [Bytes([179, 191, 241, 133, 205, 121, 248, 205, 87, 116, 230, 31, 187, 169, 193, 199, 132, 206, 141, 5, 158, 46, 152, 8]), Integer(-8673110579305453718), Integer(-12537810982799057929), Bytes([236, 213, 37, 205, 7, 12, 74, 160, 98, 55, 208, 158, 197, 160, 241, 14, 9, 245, 193, 187, 17, 154, 236, 190, 39, 221, 146, 248, 86, 217, 88, 64, 68, 89, 51, 163, 48, 73, 250]), Bytes([42, 75, 165, 156, 215, 125, 186, 112, 165, 63, 87, 175, 5, 5, 124, 160, 177, 17, 156, 186, 248, 216, 118, 192, 0, 170, 64, 192, 137, 107, 42, 219, 222, 71, 54, 233, 248, 169, 209, 18, 179, 146, 90, 25, 178, 214, 70, 44, 46, 106, 178, 251, 144, 150, 106, 136, 106, 167, 57, 94, 192, 75, 46, 72, 249, 114, 31, 157, 137, 96, 172, 168, 87, 22, 151, 33, 123, 232, 228, 180])]))), (DatumHash(c8f2f2962fa2008d80d74845ce6e1c9fa07c59a72a7855bbc8327038173d7a14), Datum(Integer(-11014695058603834993))), (DatumHash(feacbf167e7362c034b6094309acfc199eef89c762627afbc3e26c17077498a3), Datum(List([Bytes([114, 25, 55, 213, 115, 15, 223, 38, 109, 128, 137, 138, 28, 217, 153, 135, 174, 69, 209, 57, 123, 255, 187, 27, 170, 28, 30, 141, 116, 75, 200, 255, 29, 219, 73, 40, 84, 123, 56, 231, 12, 208, 17, 101, 51]), Bytes([227, 109, 163, 146, 239, 116, 37, 217, 246, 179, 7, 40, 159, 217, 8, 3, 179, 245, 239, 159, 171, 125, 172, 127, 182, 68, 122, 122, 139, 99, 139, 228, 221, 182, 166, 177, 122, 1, 124, 113, 195, 83, 148]), Bytes([131, 145, 78, 12, 160, 95, 28, 195, 41, 9, 33, 59, 95, 198, 214, 159, 126, 28, 49, 170, 237, 148, 108, 179]), Bytes([45, 124, 127, 231, 243, 103, 86, 59, 47, 155, 129, 97, 177, 66, 26, 11, 184, 40, 133, 137, 192, 84, 185, 181, 211, 85, 130, 6, 77, 126, 112, 73, 89, 51, 29, 13, 120, 196, 78, 3, 194, 122, 8, 196, 136, 165, 175, 203, 155, 142, 255, 31, 25, 227, 119, 233, 226, 126, 140, 150, 236, 212, 12, 232]), Bytes([236, 105, 73, 166, 64, 27, 13, 211, 82, 60, 159, 146, 183, 63, 198, 4, 87, 147, 135, 68, 72, 75, 39, 114, 56, 116, 41, 102, 79, 4, 176, 86, 100, 27, 188, 166, 198, 137, 145])]))), (DatumHash(fcd1cd0c9180a200774e56effadbc3f4ede5fd45dfacf13beae30604ceba4d02), Datum(Map([(Bytes([102, 71, 154, 227, 34, 164, 72, 15, 62, 209, 6, 126, 235, 53, 244, 194, 37, 198, 130, 182, 186, 180, 77, 97, 253, 124, 97, 31, 201, 11, 220, 27, 11, 145, 104, 76, 209, 12, 226, 243, 14, 113, 158, 184, 67]), Bytes([156, 198, 199, 223, 210, 171, 2, 198, 253, 32, 1, 207, 227, 120, 89, 171, 250, 233, 34, 36, 165, 30, 52, 49, 138, 121, 141, 24, 247, 28, 46, 216, 184, 111, 63, 0, 64, 118, 225, 208, 201, 50, 34, 89, 44, 28, 231, 72, 6, 94, 227, 27, 203, 204, 174, 235, 20, 94, 72, 239, 131])), (Integer(-2969090282184661921), Bytes([125, 19, 184, 92, 117, 251, 235, 8, 107, 208, 51, 169, 11, 253, 58, 113, 223, 233, 67, 94, 71, 44, 89, 97])), (Integer(17796746725610530894), Integer(8075163424182805764)), (Bytes([244, 107, 201, 18, 134, 48, 213, 105, 51, 128, 1, 151, 228, 127, 29, 157, 162, 18, 173, 238, 173, 14, 85, 187, 135, 114, 105, 183, 193, 255, 16, 187, 138, 102, 89, 61, 26, 18, 207, 51, 253, 62, 228, 194]), Integer(-14377981926416437422)), (Map([(Bytes([211, 1, 54, 201, 102, 224, 170, 36, 164, 75, 27, 57, 100, 213, 241, 22, 92, 100, 154, 82, 235, 155, 134, 145, 123, 16, 203, 188, 83, 54, 207, 143, 223, 239, 176, 88, 192, 255, 39, 71, 220, 70, 97, 233, 155, 157, 231, 205, 135, 124, 169, 240, 196, 106, 1, 158, 139, 164, 241, 199, 232]), Bytes([97, 117, 12, 196, 123, 121, 85, 214, 54, 1, 0, 226, 26, 217, 1, 111, 149, 2, 54, 65, 205, 48, 254, 235, 250, 195, 18, 127, 224, 102, 88, 162, 103, 248, 130, 233, 9, 239, 166, 90, 42, 82, 13, 220, 111, 61, 140, 118, 242, 118, 235, 113, 159, 60, 116, 140, 136, 40, 61, 250, 217, 9, 89, 136, 191, 17])), (Bytes([85, 213, 155, 19, 60, 53, 46, 3, 226, 168, 46, 67, 46, 129, 230, 122, 209, 62, 9, 124, 98, 175, 31, 63, 167, 107, 39, 103, 167, 216, 54, 247, 244, 26, 25, 89, 13, 22, 207, 97, 234, 33, 25, 59, 74, 206, 115, 30, 66, 219, 189, 121, 73]), Integer(-16621810592565322148)), (Bytes([33, 111, 35, 64, 60, 84, 220, 71, 149, 201, 14, 243, 229, 138, 62, 126, 130, 117, 206, 111, 7, 231, 44, 115, 31, 94, 14, 128, 231, 248, 187, 117, 176, 73, 181, 201, 139, 82, 36, 234, 45, 233, 175, 232, 44, 71, 251, 204, 186, 193, 240, 76, 124, 138, 53, 146, 228, 222, 145, 160, 61, 215, 1]), Integer(-5616026625525347953)), (Integer(-15368326499810788275), Integer(-5411407110371635891)), (Bytes([121, 199, 241, 3, 239, 178, 8, 176, 18, 209, 250, 183, 82, 144, 190, 49, 227, 7, 247, 31, 20, 187, 222, 178, 232, 92, 199, 105, 89, 82, 71, 231, 10, 191, 193, 5, 124, 147, 117, 7, 194, 186, 164, 160, 84, 157, 33, 34, 126, 183, 81, 82, 109]), Integer(5342965962032016216))]), Bytes([13, 23, 139, 158, 175, 64, 255, 73, 159, 124, 122]))]))), (DatumHash(5c5d715d9e3551a9021f822ffd68fc7187a56a796700ec476c7c334e68e65663), Datum(Constr(663131710, [Bytes([214, 101, 129, 57, 237, 61, 223, 147, 236, 225, 27, 252, 144, 165, 96, 38, 69, 64, 226, 43, 226, 234, 102, 200, 44, 93, 233, 91, 151, 226, 72, 127, 164, 161, 28, 251, 104, 202]), Bytes([186, 16, 175, 75, 233, 80, 124, 167, 75, 26, 94, 158, 34, 18, 139, 0, 205, 180, 123, 173, 78, 240, 2, 2, 53, 138, 78, 29, 233, 191, 78, 180, 122]), Integer(12098763251034896583), Bytes([242, 108, 143, 197, 95, 204, 253, 41, 30, 104, 70, 45, 148, 146, 47]), Integer(-18208626424618199086)]))), (DatumHash(0810a61c23167fc11763c0f2cc1c19eb692de08057660dda497ae1324884b03c), Datum(Bytes([187, 176, 217, 74, 224, 238, 227, 18, 12, 163, 119, 220, 90, 66, 86, 87, 111, 21, 188, 160, 247, 201, 51, 130, 216, 45, 71, 40, 12, 85, 23, 82, 226, 157, 103, 187, 254, 242, 214, 83, 76, 121, 67, 246, 65, 215, 160, 242, 165, 225, 232, 246, 86, 26, 185, 194, 21, 95, 125, 84, 155, 11, 137, 232, 51, 115, 207, 22, 217, 121, 240, 91, 0, 100]))), (DatumHash(1077d50c8c9d00b88dab41f27c086fe33cfac17a2659955a2483ea6b037cdc41), Datum(Integer(-11442988182361136122))), (DatumHash(e6d3df05dceb3d55d52dff3d32771cbc5fc3576bac7a9d29f7e7306652d26232), Datum(List([Integer(4619328115424865498), Bytes([114, 27, 219, 211, 103, 182, 175, 216, 124, 11, 156, 134, 35, 249, 243, 233, 125, 92, 89, 196, 75, 209, 196, 168, 123, 219, 153, 135, 11, 90, 205, 73, 182, 249, 220, 75, 105, 72, 146, 98, 38, 46, 231, 8, 52, 128, 129, 209, 250, 80, 7, 255, 251, 99, 216, 75, 2, 75, 156]), Bytes([147, 62, 177, 149, 214, 198, 177, 195, 142, 52, 235, 147, 142, 79, 135, 241, 190, 38, 39, 254, 34, 194, 190, 224, 167, 203, 110, 168, 79, 162, 170, 53, 173, 238, 248, 222, 95, 206, 216, 39, 211, 236, 169]), Bytes([50, 44, 234, 175, 76, 236, 214, 179, 84, 61, 123, 107, 55, 225, 37, 14, 145, 87, 60, 187, 9, 119, 184, 126, 49, 160, 76, 160, 62, 141, 86, 51, 254, 104, 97, 8, 179, 169, 129, 145, 165, 24, 1, 73, 167, 204, 34, 30, 183, 178, 139, 232, 177, 63, 22, 13, 40, 249]), Integer(6130350804586057685)])))]), id: TransactionHash(d6d5074a70133bbb4552745bf3b5acd65b3e47656322b7fefb29ef8627607b47) }, purpose: Minting(Ada) } diff --git a/plutus-ledger-api/tests/serde.rs b/plutus-ledger-api/tests/serde.rs new file mode 100644 index 0000000..8ddf8e3 --- /dev/null +++ b/plutus-ledger-api/tests/serde.rs @@ -0,0 +1,161 @@ +#[cfg(test)] +#[cfg(feature = "serde")] +mod serde_roundtrip_tests { + fn from_to_json(val: &T) -> Result + where + T: serde::Serialize + for<'a> serde::Deserialize<'a> + PartialEq, + { + serde_json::from_str(&serde_json::to_string(&val)?) + } + + mod v1 { + use super::from_to_json; + use plutus_ledger_api::generators::correct::{primitive::arb_integer, v1::*}; + use proptest::prelude::*; + + proptest! { + #[test] + fn test_asset_class(val in arb_asset_class()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_value(val in arb_value()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_plutus_data(val in arb_plutus_data()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_plutus_interval(val in arb_plutus_interval_posix_time()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_address(val in arb_address()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_transaction_input(val in arb_transaction_input()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_transaction_output(val in arb_transaction_output()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_tx_in_info(val in arb_tx_in_info()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_redeemeer(val in arb_redeemer()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_redeemeer_hash(val in arb_redeemer_hash()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_bigint_assoc_map(val in arb_assoc_map(arb_integer(), arb_integer())) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_d_cert(val in arb_d_cert()) { + assert_eq!(val, from_to_json(&val)?) + } + } + + proptest! { + #[test] + fn test_script_purpose(val in arb_script_purpose()) { + assert_eq!(val, from_to_json(&val)?) + } + } + + proptest! { + #[test] + fn test_transaction_info(val in arb_transaction_info()) { + assert_eq!(val, from_to_json(&val)?) + } + } + + proptest! { + #[test] + fn test_script_context(val in arb_script_context()) { + assert_eq!(val, from_to_json(&val)?) + } + } + } + mod v2 { + use super::from_to_json; + use plutus_ledger_api::generators::correct::v2::*; + use proptest::prelude::*; + + proptest! { + #[test] + fn test_transaction_output(val in arb_transaction_output()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_tx_in_info(val in arb_tx_in_info()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_output_datum(val in arb_output_datum()) { + assert_eq!(val, from_to_json(&val)?); + } + } + + proptest! { + #[test] + fn test_transaction_info(val in arb_transaction_info()) { + assert_eq!(val, from_to_json(&val)?) + } + } + + proptest! { + #[test] + fn test_script_context(val in arb_script_context()) { + assert_eq!(val, from_to_json(&val)?) + } + } + } +} From fcbf5209ae884398d5ea117de79e1683fc5e724c Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 8 Aug 2024 09:32:46 +0200 Subject: [PATCH 04/38] Add Display implementations --- plutus-ledger-api/Cargo.lock | 334 +++++++++++++- plutus-ledger-api/Cargo.toml | 2 + plutus-ledger-api/src/utils/aux.rs | 52 +++ plutus-ledger-api/src/utils/csl_to_pla.rs | 442 ++++++++++++++++++ plutus-ledger-api/src/utils/mod.rs | 40 +- plutus-ledger-api/src/utils/pla_to_csl.rs | 516 ++++++++++++++++++++++ plutus-ledger-api/src/v1/address.rs | 20 +- plutus-ledger-api/src/v1/crypto.rs | 6 + plutus-ledger-api/src/v1/transaction.rs | 16 +- plutus-ledger-api/src/v1/value.rs | 75 +++- 10 files changed, 1443 insertions(+), 60 deletions(-) create mode 100644 plutus-ledger-api/src/utils/aux.rs create mode 100644 plutus-ledger-api/src/utils/csl_to_pla.rs create mode 100644 plutus-ledger-api/src/utils/pla_to_csl.rs diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 06d8f7f..f0147b8 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -29,6 +29,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "bech32" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" + [[package]] name = "bit-set" version = "0.5.3" @@ -44,18 +50,70 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "cardano-serialization-lib" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3fab2c10aa73dae6ea90ed459ef07ed7acb09270ea90d9a37fa00420b9c25c" +dependencies = [ + "bech32", + "cbor_event", + "cfg-if", + "clear_on_drop", + "cryptoxide", + "digest", + "ed25519-bip32", + "getrandom", + "hex", + "itertools", + "js-sys", + "linked-hash-map", + "noop_proc_macro", + "num-bigint", + "num-integer", + "rand", + "rand_os", + "schemars", + "serde", + "serde-wasm-bindgen", + "serde_json", + "sha2", + "wasm-bindgen", +] + +[[package]] +name = "cbor_event" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "089a0261d1bc59e54e8e11860031efd88593f0e61b921172c474f1f38c2f2d3c" + [[package]] name = "cc" version = "1.0.99" @@ -82,12 +140,45 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "clear_on_drop" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" +dependencies = [ + "cc", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "cryptoxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" + [[package]] name = "data-encoding" version = "2.6.0" @@ -100,12 +191,42 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "dissimilar" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ed25519-bip32" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb588f93c0d91b2f668849fd6d030cddb0b2e31f105963be189da5acdf492a21" +dependencies = [ + "cryptoxide", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "equivalent" version = "1.0.1" @@ -134,6 +255,22 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -141,8 +278,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -172,6 +311,12 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -211,6 +356,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -219,9 +373,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -295,6 +449,12 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "num-bigint" version = "0.4.5" @@ -331,10 +491,18 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "plutus-ledger-api" version = "1.0.0" dependencies = [ + "anyhow", + "cardano-serialization-lib", "chrono", "data-encoding", "goldie", @@ -383,7 +551,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags", + "bitflags 2.5.0", "lazy_static", "num-traits", "rand", @@ -418,7 +586,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -428,9 +596,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", ] +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -440,13 +623,37 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "wasm-bindgen", + "winapi", +] + [[package]] name = "rand_xorshift" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", ] [[package]] @@ -461,7 +668,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -486,6 +693,30 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "serde" version = "1.0.203" @@ -495,6 +726,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.203" @@ -506,6 +748,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.128" @@ -527,6 +780,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "syn" version = "2.0.67" @@ -634,6 +900,12 @@ dependencies = [ "toml", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unarray" version = "0.1.4" @@ -663,6 +935,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wait-timeout" version = "0.2.0" @@ -680,9 +958,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -690,9 +968,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -705,9 +983,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -715,9 +993,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -728,9 +1006,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" @@ -741,6 +1035,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index c77964c..cf58f3a 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -21,6 +21,8 @@ linked-hash-map = "~0.5.6" num-traits = "~0.2.17" impl_ops = "0.1.1" chrono = { version = "0.4.34", optional = true } +cardano-serialization-lib = "11.5.0" +anyhow = "1.0.86" [features] default = [] diff --git a/plutus-ledger-api/src/utils/aux.rs b/plutus-ledger-api/src/utils/aux.rs new file mode 100644 index 0000000..e640842 --- /dev/null +++ b/plutus-ledger-api/src/utils/aux.rs @@ -0,0 +1,52 @@ +use std::{ + collections::BTreeMap, + iter::{empty, once}, +}; + +/// Create a container C from one element. +pub fn singleton(value: T) -> C +where + C: FromIterator, +{ + once(value).collect() +} + +/// Create an empty container. +pub fn none() -> C +where + C: FromIterator, +{ + empty::().collect() +} + +/// Union two BTreeMaps, call f to resolve conflicts if duplicate keys are encountered. +pub fn union_btree_maps_with V>( + f: F, + l: BTreeMap, + r: BTreeMap, +) -> BTreeMap { + r.into_iter().fold(l.clone(), |mut acc, (k, vr)| { + let v = if let Some((_, vl)) = acc.remove_entry(&k) { + f(vl, vr) + } else { + vr + }; + acc.insert(k, v); + acc + }) +} + +pub fn union_b_tree_maps_with V>( + f: F, + maps: [&BTreeMap; N], +) -> BTreeMap { + maps.into_iter().fold(BTreeMap::new(), |acc, m| { + m.iter().fold(acc, |mut acc, (k, v)| { + acc.entry(k.clone()) + .and_modify(|va: &mut V| *va = f(va, v)) + .or_insert(v.clone()); + + acc + }) + }) +} diff --git a/plutus-ledger-api/src/utils/csl_to_pla.rs b/plutus-ledger-api/src/utils/csl_to_pla.rs new file mode 100644 index 0000000..3244c25 --- /dev/null +++ b/plutus-ledger-api/src/utils/csl_to_pla.rs @@ -0,0 +1,442 @@ +use std::{collections::BTreeMap, ops::Neg, str::FromStr}; + +use cardano_serialization_lib as csl; +use num_bigint::{BigInt, ParseBigIntError}; + +use super::aux::union_b_tree_maps_with; + +use crate::{ + plutus_data::PlutusData, + v2::{ + address::{ + Address, CertificateIndex, ChainPointer, Credential, Slot, StakingCredential, + TransactionIndex, + }, + crypto::{Ed25519PubKeyHash, LedgerBytes}, + datum::{Datum, DatumHash, OutputDatum}, + script::{MintingPolicyHash, ScriptHash, ValidatorHash}, + transaction::{TransactionHash, TransactionInput, TransactionOutput}, + value::{CurrencySymbol, TokenName, Value}, + }, +}; + +#[derive(Debug, Clone, thiserror::Error)] +pub enum TryFromCSLError { + #[error("Unable to parse BigInt: {0}")] + InvalidBigInt(ParseBigIntError), + + #[error("Unable to represent CSL value in PLA: {0}")] + ImpossibleConversion(String), +} + +/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart +pub trait FromCSL { + fn from_csl(value: &T) -> Self + where + Self: Sized; +} + +pub trait ToPLA { + fn to_pla(&self) -> T; +} + +impl ToPLA for T +where + U: FromCSL, +{ + fn to_pla(&self) -> U { + FromCSL::from_csl(self) + } +} + +/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart +pub trait TryFromCSL { + fn try_from_csl(value: &T) -> Result + where + Self: Sized; +} + +pub trait TryToPLA { + fn try_to_pla(&self) -> Result; +} + +impl TryToPLA for T +where + U: TryFromCSL, +{ + fn try_to_pla(&self) -> Result { + TryFromCSL::try_from_csl(self) + } +} + +impl FromCSL for TokenName { + fn from_csl(value: &csl::AssetName) -> Self { + TokenName(LedgerBytes(value.name())) + } +} + +impl FromCSL for MintingPolicyHash { + fn from_csl(value: &csl::PolicyID) -> Self { + MintingPolicyHash(ScriptHash(LedgerBytes(value.to_bytes()))) + } +} + +impl FromCSL for Value { + fn from_csl(value: &csl::utils::Value) -> Self { + let lovelaces = BigInt::from_csl(&value.coin()); + let mut pla_value = Value::ada_value(&lovelaces); + if let Some(multi_asset) = value.multiasset() { + pla_value = &pla_value + &Value::from_csl(&multi_asset) + } + pla_value + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &csl::utils::BigNum) -> Self { + let x: u64 = From::from(*value); + BigInt::from(x) + } +} + +impl FromCSL for BTreeMap { + fn from_csl(value: &csl::Assets) -> Self { + let keys = value.keys(); + (0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { + let asset_name = keys.get(idx); + if let Some(quantity) = value.get(&asset_name) { + acc.insert( + TokenName::from_csl(&asset_name), + BigInt::from_csl(&quantity), + ); + } + acc + }) + } +} + +impl FromCSL for Value { + fn from_csl(value: &csl::MultiAsset) -> Self { + let keys = value.keys(); + Value((0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { + let script_hash = keys.get(idx); + if let Some(assets) = value.get(&script_hash) { + let assets = BTreeMap::from_csl(&assets); + acc.insert( + CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&script_hash)), + assets, + ); + } + acc + })) + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &u32) -> Self { + BigInt::from(*value) + } +} + +impl TryFromCSL for BigInt { + fn try_from_csl(value: &csl::utils::BigInt) -> Result { + BigInt::from_str(&value.to_str()).map_err(TryFromCSLError::InvalidBigInt) + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &csl::utils::Int) -> Self { + if value.is_positive() { + BigInt::from_csl(&value.as_positive().unwrap()) + } else { + BigInt::from_csl(&value.as_negative().unwrap()).neg() + } + } +} + +impl FromCSL for TransactionHash { + fn from_csl(value: &csl::crypto::TransactionHash) -> Self { + TransactionHash(LedgerBytes(value.to_bytes())) + } +} + +impl FromCSL for TransactionInput { + fn from_csl(value: &csl::TransactionInput) -> Self { + TransactionInput { + transaction_id: TransactionHash::from_csl(&value.transaction_id()), + index: BigInt::from_csl(&value.index()), + } + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::TransactionInputs) -> Self { + (0..value.len()) + .map(|idx| TransactionInput::from_csl(&value.get(idx))) + .collect() + } +} + +impl FromCSL for Ed25519PubKeyHash { + fn from_csl(value: &csl::crypto::Ed25519KeyHash) -> Self { + Ed25519PubKeyHash(LedgerBytes(value.to_bytes())) + } +} + +impl FromCSL for ScriptHash { + fn from_csl(value: &csl::crypto::ScriptHash) -> Self { + ScriptHash(LedgerBytes(value.to_bytes())) + } +} + +impl FromCSL for ValidatorHash { + fn from_csl(value: &csl::crypto::ScriptHash) -> Self { + ValidatorHash(ScriptHash::from_csl(value)) + } +} + +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::address::StakeCredential) -> Self { + StakingCredential::Hash(Credential::from_csl(value)) + } +} + +impl FromCSL for Credential { + fn from_csl(value: &csl::address::StakeCredential) -> Self { + match value.kind() { + csl::address::StakeCredKind::Key => { + Credential::PubKey(Ed25519PubKeyHash::from_csl(&value.to_keyhash().unwrap())) + } + csl::address::StakeCredKind::Script => { + Credential::Script(ValidatorHash::from_csl(&value.to_scripthash().unwrap())) + } + } + } +} + +impl FromCSL for Slot { + fn from_csl(value: &csl::utils::BigNum) -> Self { + Slot(BigInt::from_csl(value)) + } +} + +impl FromCSL for TransactionIndex { + fn from_csl(value: &csl::utils::BigNum) -> Self { + TransactionIndex(BigInt::from_csl(value)) + } +} + +impl FromCSL for CertificateIndex { + fn from_csl(value: &csl::utils::BigNum) -> Self { + CertificateIndex(BigInt::from_csl(value)) + } +} + +impl FromCSL for ChainPointer { + fn from_csl(value: &csl::address::Pointer) -> Self { + ChainPointer { + slot_number: Slot::from_csl(&value.slot_bignum()), + transaction_index: TransactionIndex::from_csl(&value.tx_index_bignum()), + certificate_index: CertificateIndex::from_csl(&value.cert_index_bignum()), + } + } +} + +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::address::Pointer) -> Self { + StakingCredential::Pointer(ChainPointer::from_csl(value)) + } +} +impl TryFromCSL for Address { + fn try_from_csl(value: &csl::address::Address) -> Result { + if let Some(addr) = csl::address::BaseAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: Some(StakingCredential::from_csl(&addr.stake_cred())), + }) + } else if let Some(addr) = csl::address::PointerAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: Some(StakingCredential::from_csl(&addr.stake_pointer())), + }) + } else if let Some(addr) = csl::address::EnterpriseAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: None, + }) + } else { + Err(TryFromCSLError::ImpossibleConversion(format!( + "Unable to represent address {:?}", + value + ))) + } + } +} + +impl TryFromCSL for PlutusData { + fn try_from_csl(value: &csl::plutus::PlutusData) -> Result { + Ok(match value.kind() { + csl::plutus::PlutusDataKind::ConstrPlutusData => { + let constr_data = value.as_constr_plutus_data().unwrap(); + let tag = BigInt::from_csl(&constr_data.alternative()); + let args = constr_data.data().try_to_pla()?; + PlutusData::Constr(tag, args) + } + csl::plutus::PlutusDataKind::Map => { + PlutusData::Map(value.as_map().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::List => { + PlutusData::List(value.as_list().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::Integer => { + PlutusData::Integer(value.as_integer().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::Bytes => PlutusData::Bytes(value.as_bytes().unwrap()), + }) + } +} + +impl TryFromCSL for Vec { + fn try_from_csl(value: &csl::plutus::PlutusList) -> Result { + (0..value.len()) + .map(|idx| value.get(idx).try_to_pla()) + .collect() + } +} + +impl TryFromCSL for Vec<(PlutusData, PlutusData)> { + fn try_from_csl(c_map: &csl::plutus::PlutusMap) -> Result { + let keys = c_map.keys(); + (0..keys.len()) + .map(|idx| { + let key = keys.get(idx); + let value = c_map.get(&key).unwrap(); + Ok((key.try_to_pla()?, value.try_to_pla()?)) + }) + .collect() + } +} + +impl FromCSL for DatumHash { + fn from_csl(value: &csl::crypto::DataHash) -> Self { + DatumHash(LedgerBytes(value.to_bytes())) + } +} + +impl TryFromCSL for OutputDatum { + fn try_from_csl(value: &csl::OutputDatum) -> Result { + Ok(if let Some(d) = value.data() { + OutputDatum::InlineDatum(Datum(d.try_to_pla()?)) + } else if let Some(h) = value.data_hash() { + OutputDatum::DatumHash(DatumHash::from_csl(&h)) + } else { + OutputDatum::None + }) + } +} + +impl TryFromCSL for TransactionOutput { + fn try_from_csl(value: &csl::TransactionOutput) -> Result { + Ok(TransactionOutput { + address: value.address().try_to_pla()?, + datum: if value.has_data_hash() { + OutputDatum::DatumHash(DatumHash::from_csl(&value.data_hash().unwrap())) + } else if value.has_plutus_data() { + OutputDatum::InlineDatum(Datum(value.plutus_data().unwrap().try_to_pla()?)) + } else { + OutputDatum::None + }, + reference_script: if value.has_script_ref() { + let script_ref = value.script_ref().unwrap(); + let script_hash = if script_ref.is_native_script() { + script_ref.native_script().unwrap().hash() + } else { + script_ref.plutus_script().unwrap().hash() + }; + Some(ScriptHash::from_csl(&script_hash)) + } else { + None + }, + value: Value::from_csl(&value.amount()), + }) + } +} + +impl TryFromCSL for Vec { + fn try_from_csl(value: &csl::TransactionOutputs) -> Result { + (0..value.len()) + .map(|idx| TransactionOutput::try_from_csl(&value.get(idx))) + .collect() + } +} + +impl FromCSL for BTreeMap { + fn from_csl(m_ass: &csl::MintAssets) -> Self { + let keys = m_ass.keys(); + (0..keys.len()) + .map(|idx| { + let key = keys.get(idx); + let value = m_ass.get(&key).unwrap(); + (TokenName::from_csl(&key), BigInt::from_csl(&value)) + }) + .collect() + } +} + +impl FromCSL for BTreeMap { + fn from_csl(value: &csl::MintsAssets) -> Self { + let mut m_ass_vec = Vec::new(); + + // This is so stupid. `MintsAssets` doesn't have a `len` method for some reason. + for idx in 0.. { + if let Some(m_ass) = value.get(idx) { + m_ass_vec.push(m_ass); + } else { + break; + } + } + + m_ass_vec.into_iter().fold(BTreeMap::new(), |acc, m| { + let ass = BTreeMap::from_csl(&m); + union_b_tree_maps_with(|l, r| l + r, [&acc, &ass]) + }) + } +} + +impl FromCSL for Value { + fn from_csl(mint: &csl::Mint) -> Self { + let keys = mint.keys(); + Value( + (0..keys.len()) + .map(|idx| { + let sh = keys.get(idx); + let ass = mint.get_all(&sh).unwrap_or(csl::MintsAssets::new()); + ( + CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&sh)), + BTreeMap::from_csl(&ass), + ) + }) + .collect::>>(), + ) + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::RequiredSigners) -> Self { + (0..value.len()) + .map(|idx| Ed25519PubKeyHash::from_csl(&value.get(idx))) + .collect() + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::NativeScripts) -> Self { + (0..value.len()).map(|idx| value.get(idx)).collect() + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::plutus::PlutusScripts) -> Self { + (0..value.len()).map(|idx| value.get(idx)).collect() + } +} diff --git a/plutus-ledger-api/src/utils/mod.rs b/plutus-ledger-api/src/utils/mod.rs index b3ef267..eee5d19 100644 --- a/plutus-ledger-api/src/utils/mod.rs +++ b/plutus-ledger-api/src/utils/mod.rs @@ -1,37 +1,3 @@ -use std::{ - collections::BTreeMap, - iter::{empty, once}, -}; - -/// Create a container C from one element. -pub fn singleton(value: T) -> C -where - C: FromIterator, -{ - once(value).collect() -} - -/// Create an empty container. -pub fn none() -> C -where - C: FromIterator, -{ - empty::().collect() -} - -/// Union two BTreeMaps, call f to resolve conflicts if duplicate keys are encountered. -pub fn union_btree_maps_with V>( - f: F, - l: BTreeMap, - r: BTreeMap, -) -> BTreeMap { - r.into_iter().fold(l.clone(), |mut acc, (k, vr)| { - let v = if let Some((_, vl)) = acc.remove_entry(&k) { - f(vl, vr) - } else { - vr - }; - acc.insert(k, v); - acc - }) -} +pub mod aux; +pub mod csl_to_pla; +pub mod pla_to_csl; diff --git a/plutus-ledger-api/src/utils/pla_to_csl.rs b/plutus-ledger-api/src/utils/pla_to_csl.rs new file mode 100644 index 0000000..5755c85 --- /dev/null +++ b/plutus-ledger-api/src/utils/pla_to_csl.rs @@ -0,0 +1,516 @@ +use std::collections::BTreeMap; + +use cardano_serialization_lib as csl; +use num_bigint::{BigInt, TryFromBigIntError}; +use num_traits::sign::Signed; + +use crate::{ + plutus_data::PlutusData, + v2::{ + address::{ + Address, CertificateIndex, ChainPointer, Credential, Slot, StakingCredential, + TransactionIndex, + }, + assoc_map::AssocMap, + crypto::Ed25519PubKeyHash, + datum::{Datum, DatumHash, OutputDatum}, + redeemer::Redeemer, + script::{MintingPolicyHash, ScriptHash}, + transaction::{POSIXTimeRange, TransactionHash, TransactionInput, TransactionOutput}, + value::{CurrencySymbol, TokenName, Value}, + }, +}; + +#[derive(Debug, thiserror::Error)] +pub enum TryFromPLAError { + #[error("{0}")] + CSLDeserializeError(csl::error::DeserializeError), + + #[error("{0}")] + CSLJsError(csl::error::JsError), + + #[error("Unable to cast BigInt {0} into type {1}: value is out of bound")] + BigIntOutOfRange(BigInt, String), + + #[error("Unable to represent PLA value in CSL: ${0}")] + ImpossibleConversion(String), + + #[error("Invalid valid transaction time range: ${0:?}")] + InvalidTimeRange(POSIXTimeRange), + + #[error("Script is missing from context: {0:?}")] + MissingScript(ScriptHash), +} + +/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart +/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough +pub trait TryFromPLA { + fn try_from_pla(val: &T) -> Result + where + Self: Sized; +} + +/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart +/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough +/// +/// DO NOT IMPLEMENT THIS DIRECTLY. Implement `TryFromPLA` instead. +pub trait TryToCSL { + fn try_to_csl(&self) -> Result; +} + +impl TryToCSL for T +where + U: TryFromPLA, +{ + fn try_to_csl(&self) -> Result { + TryFromPLA::try_from_pla(self) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &u64) -> Result { + // BigNum(s) are u64 under the hood. + + Ok(csl::utils::BigNum::from(*val)) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &BigInt) -> Result { + // BigNum(s) are u64 under the hood. + let x: u64 = val + .to_owned() + .try_into() + .map_err(|err: TryFromBigIntError| { + TryFromPLAError::BigIntOutOfRange(err.into_original(), "u64".into()) + })?; + + x.try_to_csl() + } +} + +impl TryFromPLA for csl::utils::BigInt { + fn try_from_pla(val: &BigInt) -> Result { + Ok(val.to_owned().into()) + } +} + +impl TryFromPLA for csl::utils::Int { + fn try_from_pla(val: &BigInt) -> Result { + if val.is_negative() { + Ok(csl::utils::Int::new_negative(&(val.abs()).try_to_csl()?)) + } else { + Ok(csl::utils::Int::new(&val.try_to_csl()?)) + } + } +} + +impl TryFromPLA for csl::utils::Int { + fn try_from_pla(val: &i64) -> Result { + if val.is_negative() { + Ok(csl::utils::Int::new_negative(&csl::utils::to_bignum( + val.unsigned_abs(), + ))) + } else { + Ok(csl::utils::Int::new(&csl::utils::to_bignum(*val as u64))) + } + } +} + +impl TryFromPLA for csl::crypto::Ed25519KeyHash { + fn try_from_pla(val: &Ed25519PubKeyHash) -> Result { + csl::crypto::Ed25519KeyHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +impl TryFromPLA for csl::crypto::ScriptHash { + fn try_from_pla(val: &ScriptHash) -> Result { + csl::crypto::ScriptHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +impl TryFromPLA for csl::crypto::TransactionHash { + fn try_from_pla(val: &TransactionHash) -> Result { + csl::crypto::TransactionHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +impl TryFromPLA for u32 /* TransactionIndex */ { + fn try_from_pla(val: &BigInt) -> Result { + val.to_owned() + .try_into() + .map_err(|err: TryFromBigIntError| { + TryFromPLAError::BigIntOutOfRange(err.into_original(), "u32".into()) + }) + } +} + +impl TryFromPLA for csl::TransactionInput { + fn try_from_pla(val: &TransactionInput) -> Result { + Ok(csl::TransactionInput::new( + &val.transaction_id.try_to_csl()?, + val.index.try_to_csl()?, + )) + } +} + +impl TryFromPLA> for csl::TransactionInputs { + fn try_from_pla(val: &Vec) -> Result { + val.iter() + .try_fold(csl::TransactionInputs::new(), |mut acc, input| { + acc.add(&input.try_to_csl()?); + Ok(acc) + }) + } +} + +#[derive(Clone, Debug)] +pub struct TransactionOutputWithExtraInfo<'a> { + pub transaction_output: &'a TransactionOutput, + pub scripts: &'a BTreeMap, + pub network_id: u8, + pub data_cost: &'a csl::DataCost, +} + +impl TryFromPLA> for csl::TransactionOutput { + fn try_from_pla(val: &TransactionOutputWithExtraInfo<'_>) -> Result { + let mut output_builder = csl::output_builder::TransactionOutputBuilder::new().with_address( + &AddressWithExtraInfo { + address: &val.transaction_output.address, + network_tag: val.network_id, + } + .try_to_csl()?, + ); + + output_builder = match &val.transaction_output.datum { + OutputDatum::None => output_builder, + OutputDatum::InlineDatum(Datum(d)) => output_builder.with_plutus_data(&d.try_to_csl()?), + OutputDatum::DatumHash(dh) => output_builder.with_data_hash(&dh.try_to_csl()?), + }; + + let script_ref = val + .transaction_output + .reference_script + .clone() + .map(|script_hash| -> Result<_, TryFromPLAError> { + let script = val + .scripts + .get(&script_hash) + .ok_or(TryFromPLAError::MissingScript(script_hash))?; + Ok(csl::ScriptRef::new_plutus_script(script)) + }) + .transpose()?; + + if let Some(script_ref) = &script_ref { + output_builder = output_builder.with_script_ref(script_ref); + }; + + let value_without_min_utxo = val.transaction_output.value.try_to_csl()?; + + let mut calc = csl::utils::MinOutputAdaCalculator::new_empty(val.data_cost) + .map_err(TryFromPLAError::CSLJsError)?; + calc.set_amount(&value_without_min_utxo); + match &val.transaction_output.datum { + OutputDatum::None => {} + OutputDatum::InlineDatum(Datum(d)) => { + calc.set_plutus_data(&d.try_to_csl()?); + } + OutputDatum::DatumHash(dh) => { + calc.set_data_hash(&dh.try_to_csl()?); + } + }; + if let Some(script_ref) = script_ref { + calc.set_script_ref(&script_ref); + } + + let required_coin = calc.calculate_ada().map_err(TryFromPLAError::CSLJsError)?; + let coin = std::cmp::max(value_without_min_utxo.coin(), required_coin); + + let value = match value_without_min_utxo.multiasset() { + Some(multiasset) => csl::utils::Value::new_with_assets(&coin, &multiasset), + None => csl::utils::Value::new(&coin), + }; + + output_builder + .next() + .map_err(TryFromPLAError::CSLJsError)? + .with_value(&value) + .build() + .map_err(TryFromPLAError::CSLJsError) + } +} + +impl TryFromPLA for csl::PolicyID { + fn try_from_pla(val: &MintingPolicyHash) -> Result { + val.0.try_to_csl() + } +} + +impl TryFromPLA for csl::AssetName { + fn try_from_pla(val: &TokenName) -> Result { + csl::AssetName::new(val.0 .0.to_owned()).map_err(TryFromPLAError::CSLJsError) + } +} + +impl TryFromPLA> for csl::Assets { + fn try_from_pla(val: &BTreeMap) -> Result { + val.iter().try_fold(csl::Assets::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); + Ok(acc) + }) + } +} + +impl TryFromPLA> for csl::MintAssets { + fn try_from_pla(val: &BTreeMap) -> Result { + val.iter() + .try_fold(csl::MintAssets::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, v.try_to_csl()?); + Ok(acc) + }) + } +} + +impl TryFromPLA for csl::utils::Value { + fn try_from_pla(val: &Value) -> Result { + let coin: csl::utils::Coin = val + .0 + .get(&CurrencySymbol::Ada) + .and_then(|m| m.get(&TokenName::ada())) + .map_or(Ok(csl::utils::BigNum::zero()), TryToCSL::try_to_csl)?; + + let m_ass = val + .0 + .iter() + .filter_map(|(cs, tn_map)| match &cs { + CurrencySymbol::Ada => None, + CurrencySymbol::NativeToken(h) => Some((h, tn_map)), + }) + .try_fold(csl::MultiAsset::new(), |mut acc, (cs, ass)| { + acc.insert(&cs.try_to_csl()?, &ass.try_to_csl()?); + Ok(acc) + })?; + + let mut v = csl::utils::Value::new(&coin); + + v.set_multiasset(&m_ass); + + Ok(v) + } +} + +impl TryFromPLA for csl::plutus::PlutusData { + fn try_from_pla(val: &PlutusData) -> Result { + match val { + PlutusData::Constr(tag, args) => Ok(csl::plutus::PlutusData::new_constr_plutus_data( + &csl::plutus::ConstrPlutusData::new(&tag.try_to_csl()?, &args.try_to_csl()?), + )), + PlutusData::Map(l) => Ok(csl::plutus::PlutusData::new_map(&l.try_to_csl()?)), + PlutusData::List(l) => Ok(csl::plutus::PlutusData::new_list(&l.try_to_csl()?)), + PlutusData::Integer(i) => Ok(csl::plutus::PlutusData::new_integer(&i.try_to_csl()?)), + PlutusData::Bytes(b) => Ok(csl::plutus::PlutusData::new_bytes(b.to_owned())), + } + } +} + +impl TryFromPLA> for csl::plutus::PlutusList { + fn try_from_pla(val: &Vec) -> Result { + val.iter() + // traverse + .map(|x| x.try_to_csl()) + .collect::, TryFromPLAError>>() + .map(|x| x.into()) + } +} + +impl TryFromPLA> for csl::plutus::PlutusMap { + fn try_from_pla(val: &Vec<(PlutusData, PlutusData)>) -> Result { + val.iter() + .try_fold(csl::plutus::PlutusMap::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); + Ok(acc) + }) + } +} + +impl TryFromPLA for csl::crypto::DataHash { + fn try_from_pla(val: &DatumHash) -> Result { + csl::crypto::DataHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +impl TryFromPLA for csl::plutus::PlutusData { + fn try_from_pla(val: &Datum) -> Result { + val.0.try_to_csl() + } +} + +impl TryFromPLA for csl::address::Pointer { + fn try_from_pla(val: &ChainPointer) -> Result { + Ok(csl::address::Pointer::new_pointer( + &val.slot_number.try_to_csl()?, + &val.transaction_index.try_to_csl()?, + &val.certificate_index.try_to_csl()?, + )) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &Slot) -> Result { + val.0.try_to_csl() + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &TransactionIndex) -> Result { + val.0.try_to_csl() + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &CertificateIndex) -> Result { + val.0.try_to_csl() + } +} + +impl TryFromPLA for csl::address::StakeCredential { + fn try_from_pla(val: &Credential) -> Result { + match val { + Credential::PubKey(pkh) => Ok(csl::address::StakeCredential::from_keyhash( + &pkh.try_to_csl()?, + )), + Credential::Script(sh) => Ok(csl::address::StakeCredential::from_scripthash( + &sh.0.try_to_csl()?, + )), + } + } +} + +impl TryFromPLA for csl::address::StakeCredential { + fn try_from_pla(val: &StakingCredential) -> Result { + match val { + StakingCredential::Hash(c) => c.try_to_csl(), + StakingCredential::Pointer(_) => Err(TryFromPLAError::ImpossibleConversion( + "cannot represent chain pointer".into(), + )), + } + } +} + +#[derive(Clone, Debug)] +pub struct AddressWithExtraInfo<'a> { + pub address: &'a Address, + pub network_tag: u8, +} + +impl TryFromPLA> for csl::address::Address { + fn try_from_pla(val: &AddressWithExtraInfo<'_>) -> Result { + let payment = val.address.credential.try_to_csl()?; + + Ok(match val.address.staking_credential { + None => csl::address::EnterpriseAddress::new(val.network_tag, &payment).to_address(), + Some(ref sc) => match sc { + StakingCredential::Hash(c) => { + csl::address::BaseAddress::new(val.network_tag, &payment, &c.try_to_csl()?) + .to_address() + } + StakingCredential::Pointer(ptr) => { + csl::address::PointerAddress::new(val.network_tag, &payment, &ptr.try_to_csl()?) + .to_address() + } + }, + }) + } +} + +impl std::fmt::Display for AddressWithExtraInfo<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let bech32_addr: Option = self + .try_to_csl() + .ok() + .and_then(|csl_addr: csl::address::Address| csl_addr.to_bech32(None).ok()); + match bech32_addr { + Some(addr) => write!(f, "{}", addr), + None => write!(f, "INVALID ADDRESS {:?}", self), + } + } +} + +#[derive(Clone, Debug)] +struct RewardAddressWithExtraInfo<'a> { + pub staking_credential: &'a StakingCredential, + pub network_tag: u8, +} + +impl TryFromPLA> for csl::address::RewardAddress { + fn try_from_pla(val: &RewardAddressWithExtraInfo<'_>) -> Result { + Ok(csl::address::RewardAddress::new( + val.network_tag, + &val.staking_credential.try_to_csl()?, + )) + } +} + +#[derive(Clone, Debug)] +struct WithdrawalsWithExtraInfo<'a> { + withdrawals: &'a AssocMap, + network_tag: u8, +} + +impl TryFromPLA> for csl::Withdrawals { + fn try_from_pla(val: &WithdrawalsWithExtraInfo<'_>) -> Result { + val.withdrawals + .0 + .iter() + .try_fold(csl::Withdrawals::new(), |mut acc, (s, q)| { + acc.insert( + &RewardAddressWithExtraInfo { + staking_credential: s, + network_tag: val.network_tag, + } + .try_to_csl()?, + &q.try_to_csl()?, + ); + Ok(acc) + }) + } +} + +#[derive(Clone, Debug)] +struct RedeemerWithExtraInfo<'a> { + redeemer: &'a Redeemer, + tag: &'a csl::plutus::RedeemerTag, + index: u64, +} + +impl TryFromPLA> for csl::plutus::Redeemer { + fn try_from_pla<'a>( + val: &RedeemerWithExtraInfo<'_>, + ) -> Result { + let Redeemer(plutus_data) = val.redeemer; + Ok(csl::plutus::Redeemer::new( + val.tag, + &val.index.try_to_csl()?, + &plutus_data.try_to_csl()?, + &csl::plutus::ExUnits::new(&csl::utils::to_bignum(0), &csl::utils::to_bignum(0)), + )) + } +} + +impl TryFromPLA for Option { + fn try_from_pla( + pla_output_datum: &OutputDatum, + ) -> Result, TryFromPLAError> { + Ok(match pla_output_datum { + OutputDatum::None => None, + OutputDatum::InlineDatum(Datum(d)) => { + Some(csl::OutputDatum::new_data(&d.try_to_csl()?)) + } + OutputDatum::DatumHash(dh) => Some(csl::OutputDatum::new_data_hash(&dh.try_to_csl()?)), + }) + } +} diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index 41d2245..648ac07 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -1,7 +1,13 @@ //! Types related to Cardano addresses +use std::str::FromStr; + +use anyhow::anyhow; +use cardano_serialization_lib as csl; + use crate::plutus_data::{ verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, }; +use crate::utils::csl_to_pla::TryToPLA; use crate::v1::crypto::Ed25519PubKeyHash; use crate::v1::script::ValidatorHash; #[cfg(feature = "lbf")] @@ -39,7 +45,7 @@ impl IsPlutusData for Address { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(Address { credential: Credential::from_plutus_data(&fields[0])?, staking_credential: >::from_plutus_data( @@ -61,6 +67,18 @@ impl IsPlutusData for Address { } } +impl FromStr for Address { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result { + let csl_addr = csl::address::Address::from_bech32(s) + .map_err(|err| anyhow!("Couldn't parse bech32 address: {}", err))?; + csl_addr + .try_to_pla() + .map_err(|err| anyhow!("Couldn't convert address: {}", err)) + } +} + /// A public key hash or validator hash credential (used as a payment or a staking credential) #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index ca3d743..6b8ec77 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -88,6 +88,12 @@ impl std::fmt::Debug for LedgerBytes { } } +impl std::fmt::Display for LedgerBytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", HEXLOWER.encode(&self.0)) + } +} + impl IsPlutusData for LedgerBytes { fn to_plutus_data(&self) -> PlutusData { PlutusData::Bytes(self.0.clone()) diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 1a90448..e8d7e3b 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -1,4 +1,6 @@ //! Types related to Cardano transactions. +use std::fmt; + use super::{ address::{Address, StakingCredential}, crypto::{LedgerBytes, PaymentPubKeyHash}, @@ -10,7 +12,7 @@ use crate::plutus_data::{ parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, }; -use crate::utils::{none, singleton}; +use crate::utils::aux::{none, singleton}; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; use num_bigint::BigInt; @@ -29,6 +31,12 @@ pub struct TransactionInput { pub index: BigInt, } +impl fmt::Display for TransactionInput { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}#{}", self.transaction_id.0, self.index) + } +} + impl IsPlutusData for TransactionInput { fn to_plutus_data(&self) -> PlutusData { PlutusData::Constr( @@ -73,6 +81,12 @@ impl IsPlutusData for TransactionInput { #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionHash(pub LedgerBytes); +impl fmt::Display for TransactionHash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + impl IsPlutusData for TransactionHash { fn to_plutus_data(&self) -> PlutusData { PlutusData::Constr(BigInt::from(0), vec![self.0.to_plutus_data()]) diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 249e6ff..07ae47a 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -2,7 +2,7 @@ use crate::plutus_data::{ verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, }; -use crate::utils::{singleton, union_btree_maps_with}; +use crate::utils::aux::{singleton, union_btree_maps_with}; use crate::v1::crypto::LedgerBytes; use crate::v1::script::{MintingPolicyHash, ScriptHash}; #[cfg(feature = "lbf")] @@ -13,13 +13,13 @@ use num_traits::Zero; use serde::{Deserialize, Serialize}; #[cfg(feature = "lbf")] use serde_json; -use std::ops; use std::string::String; use std::{ collections::BTreeMap, iter::Sum, ops::{Add, Mul, Neg, Not, Sub}, }; +use std::{fmt, ops}; /// Identifier of a currency, which could be either Ada (or tAda), or a native token represented by /// it's minting policy hash. A currency may be associated with multiple `AssetClass`es. @@ -30,6 +30,25 @@ pub enum CurrencySymbol { NativeToken(MintingPolicyHash), } +impl fmt::Display for CurrencySymbol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let asset_class_str = match self { + CurrencySymbol::Ada => { + if f.alternate() { + "lovelace".to_string() + } else { + "".to_string() + } + } + CurrencySymbol::NativeToken(symbol) => { + format!("{}", symbol.0 .0) + } + }; + + write!(f, "{}", asset_class_str) + } +} + impl IsPlutusData for CurrencySymbol { fn to_plutus_data(&self) -> PlutusData { match self { @@ -263,6 +282,27 @@ impl Value { } } +impl fmt::Display for Value { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let value_str = self + .0 + .iter() + .flat_map(|(currency_symbol, assets)| { + assets.iter().map(move |(token_name, amount)| { + if token_name.is_empty() { + format!("{} {}", currency_symbol, amount) + } else { + format!("{}.{} {}", currency_symbol, token_name, amount) + } + }) + }) + .collect::>() + .join("+"); + + write!(f, "{}", value_str) + } +} + impl Zero for Value { fn zero() -> Self { Default::default() @@ -385,9 +425,11 @@ impl TokenName { pub fn ada() -> TokenName { TokenName(LedgerBytes(Vec::with_capacity(0))) } -} -impl TokenName { + pub fn is_empty(&self) -> bool { + self.0 .0.is_empty() + } + pub fn from_bytes(bytes: Vec) -> Self { TokenName(LedgerBytes(bytes)) } @@ -411,6 +453,21 @@ impl IsPlutusData for TokenName { } } +impl fmt::Display for TokenName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.alternate() { + let utf8_str = std::str::from_utf8(&self.0 .0); + + match utf8_str { + Ok(str) => write!(f, "{}", str), + Err(_) => write!(f, "0x{}", self.0), + } + } else { + write!(f, "{}", self.0) + } + } +} + /// AssetClass is uniquely identifying a specific asset #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -420,6 +477,16 @@ pub struct AssetClass { pub token_name: TokenName, } +impl fmt::Display for AssetClass { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.token_name.is_empty() { + write!(f, "{}", self.currency_symbol) + } else { + write!(f, "{}.{}", self.currency_symbol, self.token_name) + } + } +} + impl IsPlutusData for AssetClass { fn to_plutus_data(&self) -> PlutusData { PlutusData::Constr( From bf30fbc4353d181fcc6556aab1c84187ec7e2d85 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Fri, 4 Oct 2024 12:13:28 +0200 Subject: [PATCH 05/38] Reorganise modules --- plutus-ledger-api/src/csl/csl_to_pla.rs | 94 ++++ plutus-ledger-api/src/csl/mod.rs | 2 + plutus-ledger-api/src/csl/pla_to_csl.rs | 109 +++++ plutus-ledger-api/src/lib.rs | 1 + plutus-ledger-api/src/plutus_data.rs | 82 ++++ plutus-ledger-api/src/utils/csl_to_pla.rs | 442 ------------------ plutus-ledger-api/src/utils/mod.rs | 2 - plutus-ledger-api/src/utils/pla_to_csl.rs | 516 ---------------------- plutus-ledger-api/src/v1/address.rs | 225 +++++++++- plutus-ledger-api/src/v1/assoc_map.rs | 4 + plutus-ledger-api/src/v1/crypto.rs | 47 +- plutus-ledger-api/src/v1/datum.rs | 32 ++ plutus-ledger-api/src/v1/interval.rs | 20 + plutus-ledger-api/src/v1/redeemer.rs | 38 +- plutus-ledger-api/src/v1/script.rs | 53 ++- plutus-ledger-api/src/v1/transaction.rs | 116 ++++- plutus-ledger-api/src/v1/value.rs | 198 ++++++++- plutus-ledger-api/src/v2/datum.rs | 45 +- plutus-ledger-api/src/v2/transaction.rs | 173 +++++++- 19 files changed, 1202 insertions(+), 997 deletions(-) create mode 100644 plutus-ledger-api/src/csl/csl_to_pla.rs create mode 100644 plutus-ledger-api/src/csl/mod.rs create mode 100644 plutus-ledger-api/src/csl/pla_to_csl.rs delete mode 100644 plutus-ledger-api/src/utils/csl_to_pla.rs delete mode 100644 plutus-ledger-api/src/utils/pla_to_csl.rs diff --git a/plutus-ledger-api/src/csl/csl_to_pla.rs b/plutus-ledger-api/src/csl/csl_to_pla.rs new file mode 100644 index 0000000..a87bee5 --- /dev/null +++ b/plutus-ledger-api/src/csl/csl_to_pla.rs @@ -0,0 +1,94 @@ +use std::{ops::Neg, str::FromStr}; + +use cardano_serialization_lib as csl; +use num_bigint::{BigInt, ParseBigIntError}; + +#[derive(Debug, Clone, thiserror::Error)] +pub enum TryFromCSLError { + #[error("Unable to parse BigInt: {0}")] + InvalidBigInt(ParseBigIntError), + + #[error("Unable to represent CSL value in PLA: {0}")] + ImpossibleConversion(String), +} + +/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart +pub trait FromCSL { + fn from_csl(value: &T) -> Self + where + Self: Sized; +} + +pub trait ToPLA { + fn to_pla(&self) -> T; +} + +impl ToPLA for T +where + U: FromCSL, +{ + fn to_pla(&self) -> U { + FromCSL::from_csl(self) + } +} + +/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart +pub trait TryFromCSL { + fn try_from_csl(value: &T) -> Result + where + Self: Sized; +} + +pub trait TryToPLA { + fn try_to_pla(&self) -> Result; +} + +impl TryToPLA for T +where + U: TryFromCSL, +{ + fn try_to_pla(&self) -> Result { + TryFromCSL::try_from_csl(self) + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &csl::utils::BigNum) -> Self { + let x: u64 = From::from(*value); + BigInt::from(x) + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &u32) -> Self { + BigInt::from(*value) + } +} + +impl TryFromCSL for BigInt { + fn try_from_csl(value: &csl::utils::BigInt) -> Result { + BigInt::from_str(&value.to_str()).map_err(TryFromCSLError::InvalidBigInt) + } +} + +impl FromCSL for BigInt { + fn from_csl(value: &csl::utils::Int) -> Self { + if value.is_positive() { + BigInt::from_csl(&value.as_positive().unwrap()) + } else { + BigInt::from_csl(&value.as_negative().unwrap()).neg() + } + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::NativeScripts) -> Self { + (0..value.len()).map(|idx| value.get(idx)).collect() + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::plutus::PlutusScripts) -> Self { + (0..value.len()).map(|idx| value.get(idx)).collect() + } +} diff --git a/plutus-ledger-api/src/csl/mod.rs b/plutus-ledger-api/src/csl/mod.rs new file mode 100644 index 0000000..8af54b5 --- /dev/null +++ b/plutus-ledger-api/src/csl/mod.rs @@ -0,0 +1,2 @@ +pub mod csl_to_pla; +pub mod pla_to_csl; diff --git a/plutus-ledger-api/src/csl/pla_to_csl.rs b/plutus-ledger-api/src/csl/pla_to_csl.rs new file mode 100644 index 0000000..31c1a82 --- /dev/null +++ b/plutus-ledger-api/src/csl/pla_to_csl.rs @@ -0,0 +1,109 @@ +use cardano_serialization_lib as csl; +use num_bigint::{BigInt, TryFromBigIntError}; +use num_traits::sign::Signed; + +#[derive(Debug, thiserror::Error)] +pub enum TryFromPLAError { + #[error("{0}")] + CSLDeserializeError(csl::error::DeserializeError), + + #[error("{0}")] + CSLJsError(csl::error::JsError), + + #[error("Unable to cast BigInt {0} into type {1}: value is out of bound")] + BigIntOutOfRange(BigInt, String), + + #[error("Unable to represent PLA value in CSL: ${0}")] + ImpossibleConversion(String), + + #[error("Invalid valid transaction time range: ${0:?}")] + InvalidTimeRange(crate::v2::transaction::POSIXTimeRange), + + #[error("Script is missing from context: {0:?}")] + MissingScript(crate::v2::script::ScriptHash), +} + +/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart +/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough +pub trait TryFromPLA { + fn try_from_pla(val: &T) -> Result + where + Self: Sized; +} + +/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart +/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough +/// +/// DO NOT IMPLEMENT THIS DIRECTLY. Implement `TryFromPLA` instead. +pub trait TryToCSL { + fn try_to_csl(&self) -> Result; +} + +impl TryToCSL for T +where + U: TryFromPLA, +{ + fn try_to_csl(&self) -> Result { + TryFromPLA::try_from_pla(self) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &u64) -> Result { + // BigNum(s) are u64 under the hood. + + Ok(csl::utils::BigNum::from(*val)) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &BigInt) -> Result { + // BigNum(s) are u64 under the hood. + let x: u64 = val + .to_owned() + .try_into() + .map_err(|err: TryFromBigIntError| { + TryFromPLAError::BigIntOutOfRange(err.into_original(), "u64".into()) + })?; + + x.try_to_csl() + } +} + +impl TryFromPLA for csl::utils::BigInt { + fn try_from_pla(val: &BigInt) -> Result { + Ok(val.to_owned().into()) + } +} + +impl TryFromPLA for csl::utils::Int { + fn try_from_pla(val: &BigInt) -> Result { + if val.is_negative() { + Ok(csl::utils::Int::new_negative(&(val.abs()).try_to_csl()?)) + } else { + Ok(csl::utils::Int::new(&val.try_to_csl()?)) + } + } +} + +impl TryFromPLA for csl::utils::Int { + fn try_from_pla(val: &i64) -> Result { + if val.is_negative() { + Ok(csl::utils::Int::new_negative(&csl::utils::to_bignum( + val.unsigned_abs(), + ))) + } else { + Ok(csl::utils::Int::new(&csl::utils::to_bignum(*val as u64))) + } + } +} + +impl TryFromPLA for u32 /* TransactionIndex */ { + fn try_from_pla(val: &BigInt) -> Result { + val.to_owned() + .try_into() + .map_err(|err: TryFromBigIntError| { + TryFromPLAError::BigIntOutOfRange(err.into_original(), "u32".into()) + }) + } +} diff --git a/plutus-ledger-api/src/lib.rs b/plutus-ledger-api/src/lib.rs index 8232f0b..ac37079 100644 --- a/plutus-ledger-api/src/lib.rs +++ b/plutus-ledger-api/src/lib.rs @@ -8,6 +8,7 @@ pub mod v1; pub mod v2; #[cfg(feature = "lbf")] pub use lbr_prelude::json; +pub mod csl; pub mod utils; #[macro_use] diff --git a/plutus-ledger-api/src/plutus_data.rs b/plutus-ledger-api/src/plutus_data.rs index 4607217..0d624af 100644 --- a/plutus-ledger-api/src/plutus_data.rs +++ b/plutus-ledger-api/src/plutus_data.rs @@ -1,4 +1,5 @@ //! Plutus Data related types and traits +use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use data_encoding::HEXLOWER; #[cfg(feature = "lbf")] @@ -13,6 +14,9 @@ use std::collections::{BTreeMap, BTreeSet}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; + /// Data representation of on-chain data such as Datums and Redeemers #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -554,6 +558,84 @@ where } } +impl TryFromCSL for PlutusData { + fn try_from_csl(value: &csl::plutus::PlutusData) -> Result { + Ok(match value.kind() { + csl::plutus::PlutusDataKind::ConstrPlutusData => { + let constr_data = value.as_constr_plutus_data().unwrap(); + let tag = BigInt::from_csl(&constr_data.alternative()); + let args = constr_data.data().try_to_pla()?; + PlutusData::Constr(tag, args) + } + csl::plutus::PlutusDataKind::Map => { + PlutusData::Map(value.as_map().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::List => { + PlutusData::List(value.as_list().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::Integer => { + PlutusData::Integer(value.as_integer().unwrap().try_to_pla()?) + } + csl::plutus::PlutusDataKind::Bytes => PlutusData::Bytes(value.as_bytes().unwrap()), + }) + } +} + +impl TryFromCSL for Vec { + fn try_from_csl(value: &csl::plutus::PlutusList) -> Result { + (0..value.len()) + .map(|idx| value.get(idx).try_to_pla()) + .collect() + } +} + +impl TryFromCSL for Vec<(PlutusData, PlutusData)> { + fn try_from_csl(c_map: &csl::plutus::PlutusMap) -> Result { + let keys = c_map.keys(); + (0..keys.len()) + .map(|idx| { + let key = keys.get(idx); + let value = c_map.get(&key).unwrap(); + Ok((key.try_to_pla()?, value.try_to_pla()?)) + }) + .collect() + } +} + +impl TryFromPLA for csl::plutus::PlutusData { + fn try_from_pla(val: &PlutusData) -> Result { + match val { + PlutusData::Constr(tag, args) => Ok(csl::plutus::PlutusData::new_constr_plutus_data( + &csl::plutus::ConstrPlutusData::new(&tag.try_to_csl()?, &args.try_to_csl()?), + )), + PlutusData::Map(l) => Ok(csl::plutus::PlutusData::new_map(&l.try_to_csl()?)), + PlutusData::List(l) => Ok(csl::plutus::PlutusData::new_list(&l.try_to_csl()?)), + PlutusData::Integer(i) => Ok(csl::plutus::PlutusData::new_integer(&i.try_to_csl()?)), + PlutusData::Bytes(b) => Ok(csl::plutus::PlutusData::new_bytes(b.to_owned())), + } + } +} + +impl TryFromPLA> for csl::plutus::PlutusList { + fn try_from_pla(val: &Vec) -> Result { + val.iter() + // traverse + .map(|x| x.try_to_csl()) + .collect::, TryFromPLAError>>() + .map(|x| x.into()) + } +} + +impl TryFromPLA> for csl::plutus::PlutusMap { + fn try_from_pla(val: &Vec<(PlutusData, PlutusData)>) -> Result { + val.iter() + .try_fold(csl::plutus::PlutusMap::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); + Ok(acc) + }) + } +} + /// Verify the number of fields contained in a PlutusData::Constr pub fn verify_constr_fields( fields: &Vec, diff --git a/plutus-ledger-api/src/utils/csl_to_pla.rs b/plutus-ledger-api/src/utils/csl_to_pla.rs deleted file mode 100644 index 3244c25..0000000 --- a/plutus-ledger-api/src/utils/csl_to_pla.rs +++ /dev/null @@ -1,442 +0,0 @@ -use std::{collections::BTreeMap, ops::Neg, str::FromStr}; - -use cardano_serialization_lib as csl; -use num_bigint::{BigInt, ParseBigIntError}; - -use super::aux::union_b_tree_maps_with; - -use crate::{ - plutus_data::PlutusData, - v2::{ - address::{ - Address, CertificateIndex, ChainPointer, Credential, Slot, StakingCredential, - TransactionIndex, - }, - crypto::{Ed25519PubKeyHash, LedgerBytes}, - datum::{Datum, DatumHash, OutputDatum}, - script::{MintingPolicyHash, ScriptHash, ValidatorHash}, - transaction::{TransactionHash, TransactionInput, TransactionOutput}, - value::{CurrencySymbol, TokenName, Value}, - }, -}; - -#[derive(Debug, Clone, thiserror::Error)] -pub enum TryFromCSLError { - #[error("Unable to parse BigInt: {0}")] - InvalidBigInt(ParseBigIntError), - - #[error("Unable to represent CSL value in PLA: {0}")] - ImpossibleConversion(String), -} - -/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart -pub trait FromCSL { - fn from_csl(value: &T) -> Self - where - Self: Sized; -} - -pub trait ToPLA { - fn to_pla(&self) -> T; -} - -impl ToPLA for T -where - U: FromCSL, -{ - fn to_pla(&self) -> U { - FromCSL::from_csl(self) - } -} - -/// Convert a cardano-serialization-lib type to its plutus-ledger-api counterpart -pub trait TryFromCSL { - fn try_from_csl(value: &T) -> Result - where - Self: Sized; -} - -pub trait TryToPLA { - fn try_to_pla(&self) -> Result; -} - -impl TryToPLA for T -where - U: TryFromCSL, -{ - fn try_to_pla(&self) -> Result { - TryFromCSL::try_from_csl(self) - } -} - -impl FromCSL for TokenName { - fn from_csl(value: &csl::AssetName) -> Self { - TokenName(LedgerBytes(value.name())) - } -} - -impl FromCSL for MintingPolicyHash { - fn from_csl(value: &csl::PolicyID) -> Self { - MintingPolicyHash(ScriptHash(LedgerBytes(value.to_bytes()))) - } -} - -impl FromCSL for Value { - fn from_csl(value: &csl::utils::Value) -> Self { - let lovelaces = BigInt::from_csl(&value.coin()); - let mut pla_value = Value::ada_value(&lovelaces); - if let Some(multi_asset) = value.multiasset() { - pla_value = &pla_value + &Value::from_csl(&multi_asset) - } - pla_value - } -} - -impl FromCSL for BigInt { - fn from_csl(value: &csl::utils::BigNum) -> Self { - let x: u64 = From::from(*value); - BigInt::from(x) - } -} - -impl FromCSL for BTreeMap { - fn from_csl(value: &csl::Assets) -> Self { - let keys = value.keys(); - (0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { - let asset_name = keys.get(idx); - if let Some(quantity) = value.get(&asset_name) { - acc.insert( - TokenName::from_csl(&asset_name), - BigInt::from_csl(&quantity), - ); - } - acc - }) - } -} - -impl FromCSL for Value { - fn from_csl(value: &csl::MultiAsset) -> Self { - let keys = value.keys(); - Value((0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { - let script_hash = keys.get(idx); - if let Some(assets) = value.get(&script_hash) { - let assets = BTreeMap::from_csl(&assets); - acc.insert( - CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&script_hash)), - assets, - ); - } - acc - })) - } -} - -impl FromCSL for BigInt { - fn from_csl(value: &u32) -> Self { - BigInt::from(*value) - } -} - -impl TryFromCSL for BigInt { - fn try_from_csl(value: &csl::utils::BigInt) -> Result { - BigInt::from_str(&value.to_str()).map_err(TryFromCSLError::InvalidBigInt) - } -} - -impl FromCSL for BigInt { - fn from_csl(value: &csl::utils::Int) -> Self { - if value.is_positive() { - BigInt::from_csl(&value.as_positive().unwrap()) - } else { - BigInt::from_csl(&value.as_negative().unwrap()).neg() - } - } -} - -impl FromCSL for TransactionHash { - fn from_csl(value: &csl::crypto::TransactionHash) -> Self { - TransactionHash(LedgerBytes(value.to_bytes())) - } -} - -impl FromCSL for TransactionInput { - fn from_csl(value: &csl::TransactionInput) -> Self { - TransactionInput { - transaction_id: TransactionHash::from_csl(&value.transaction_id()), - index: BigInt::from_csl(&value.index()), - } - } -} - -impl FromCSL for Vec { - fn from_csl(value: &csl::TransactionInputs) -> Self { - (0..value.len()) - .map(|idx| TransactionInput::from_csl(&value.get(idx))) - .collect() - } -} - -impl FromCSL for Ed25519PubKeyHash { - fn from_csl(value: &csl::crypto::Ed25519KeyHash) -> Self { - Ed25519PubKeyHash(LedgerBytes(value.to_bytes())) - } -} - -impl FromCSL for ScriptHash { - fn from_csl(value: &csl::crypto::ScriptHash) -> Self { - ScriptHash(LedgerBytes(value.to_bytes())) - } -} - -impl FromCSL for ValidatorHash { - fn from_csl(value: &csl::crypto::ScriptHash) -> Self { - ValidatorHash(ScriptHash::from_csl(value)) - } -} - -impl FromCSL for StakingCredential { - fn from_csl(value: &csl::address::StakeCredential) -> Self { - StakingCredential::Hash(Credential::from_csl(value)) - } -} - -impl FromCSL for Credential { - fn from_csl(value: &csl::address::StakeCredential) -> Self { - match value.kind() { - csl::address::StakeCredKind::Key => { - Credential::PubKey(Ed25519PubKeyHash::from_csl(&value.to_keyhash().unwrap())) - } - csl::address::StakeCredKind::Script => { - Credential::Script(ValidatorHash::from_csl(&value.to_scripthash().unwrap())) - } - } - } -} - -impl FromCSL for Slot { - fn from_csl(value: &csl::utils::BigNum) -> Self { - Slot(BigInt::from_csl(value)) - } -} - -impl FromCSL for TransactionIndex { - fn from_csl(value: &csl::utils::BigNum) -> Self { - TransactionIndex(BigInt::from_csl(value)) - } -} - -impl FromCSL for CertificateIndex { - fn from_csl(value: &csl::utils::BigNum) -> Self { - CertificateIndex(BigInt::from_csl(value)) - } -} - -impl FromCSL for ChainPointer { - fn from_csl(value: &csl::address::Pointer) -> Self { - ChainPointer { - slot_number: Slot::from_csl(&value.slot_bignum()), - transaction_index: TransactionIndex::from_csl(&value.tx_index_bignum()), - certificate_index: CertificateIndex::from_csl(&value.cert_index_bignum()), - } - } -} - -impl FromCSL for StakingCredential { - fn from_csl(value: &csl::address::Pointer) -> Self { - StakingCredential::Pointer(ChainPointer::from_csl(value)) - } -} -impl TryFromCSL for Address { - fn try_from_csl(value: &csl::address::Address) -> Result { - if let Some(addr) = csl::address::BaseAddress::from_address(value) { - Ok(Address { - credential: Credential::from_csl(&addr.payment_cred()), - staking_credential: Some(StakingCredential::from_csl(&addr.stake_cred())), - }) - } else if let Some(addr) = csl::address::PointerAddress::from_address(value) { - Ok(Address { - credential: Credential::from_csl(&addr.payment_cred()), - staking_credential: Some(StakingCredential::from_csl(&addr.stake_pointer())), - }) - } else if let Some(addr) = csl::address::EnterpriseAddress::from_address(value) { - Ok(Address { - credential: Credential::from_csl(&addr.payment_cred()), - staking_credential: None, - }) - } else { - Err(TryFromCSLError::ImpossibleConversion(format!( - "Unable to represent address {:?}", - value - ))) - } - } -} - -impl TryFromCSL for PlutusData { - fn try_from_csl(value: &csl::plutus::PlutusData) -> Result { - Ok(match value.kind() { - csl::plutus::PlutusDataKind::ConstrPlutusData => { - let constr_data = value.as_constr_plutus_data().unwrap(); - let tag = BigInt::from_csl(&constr_data.alternative()); - let args = constr_data.data().try_to_pla()?; - PlutusData::Constr(tag, args) - } - csl::plutus::PlutusDataKind::Map => { - PlutusData::Map(value.as_map().unwrap().try_to_pla()?) - } - csl::plutus::PlutusDataKind::List => { - PlutusData::List(value.as_list().unwrap().try_to_pla()?) - } - csl::plutus::PlutusDataKind::Integer => { - PlutusData::Integer(value.as_integer().unwrap().try_to_pla()?) - } - csl::plutus::PlutusDataKind::Bytes => PlutusData::Bytes(value.as_bytes().unwrap()), - }) - } -} - -impl TryFromCSL for Vec { - fn try_from_csl(value: &csl::plutus::PlutusList) -> Result { - (0..value.len()) - .map(|idx| value.get(idx).try_to_pla()) - .collect() - } -} - -impl TryFromCSL for Vec<(PlutusData, PlutusData)> { - fn try_from_csl(c_map: &csl::plutus::PlutusMap) -> Result { - let keys = c_map.keys(); - (0..keys.len()) - .map(|idx| { - let key = keys.get(idx); - let value = c_map.get(&key).unwrap(); - Ok((key.try_to_pla()?, value.try_to_pla()?)) - }) - .collect() - } -} - -impl FromCSL for DatumHash { - fn from_csl(value: &csl::crypto::DataHash) -> Self { - DatumHash(LedgerBytes(value.to_bytes())) - } -} - -impl TryFromCSL for OutputDatum { - fn try_from_csl(value: &csl::OutputDatum) -> Result { - Ok(if let Some(d) = value.data() { - OutputDatum::InlineDatum(Datum(d.try_to_pla()?)) - } else if let Some(h) = value.data_hash() { - OutputDatum::DatumHash(DatumHash::from_csl(&h)) - } else { - OutputDatum::None - }) - } -} - -impl TryFromCSL for TransactionOutput { - fn try_from_csl(value: &csl::TransactionOutput) -> Result { - Ok(TransactionOutput { - address: value.address().try_to_pla()?, - datum: if value.has_data_hash() { - OutputDatum::DatumHash(DatumHash::from_csl(&value.data_hash().unwrap())) - } else if value.has_plutus_data() { - OutputDatum::InlineDatum(Datum(value.plutus_data().unwrap().try_to_pla()?)) - } else { - OutputDatum::None - }, - reference_script: if value.has_script_ref() { - let script_ref = value.script_ref().unwrap(); - let script_hash = if script_ref.is_native_script() { - script_ref.native_script().unwrap().hash() - } else { - script_ref.plutus_script().unwrap().hash() - }; - Some(ScriptHash::from_csl(&script_hash)) - } else { - None - }, - value: Value::from_csl(&value.amount()), - }) - } -} - -impl TryFromCSL for Vec { - fn try_from_csl(value: &csl::TransactionOutputs) -> Result { - (0..value.len()) - .map(|idx| TransactionOutput::try_from_csl(&value.get(idx))) - .collect() - } -} - -impl FromCSL for BTreeMap { - fn from_csl(m_ass: &csl::MintAssets) -> Self { - let keys = m_ass.keys(); - (0..keys.len()) - .map(|idx| { - let key = keys.get(idx); - let value = m_ass.get(&key).unwrap(); - (TokenName::from_csl(&key), BigInt::from_csl(&value)) - }) - .collect() - } -} - -impl FromCSL for BTreeMap { - fn from_csl(value: &csl::MintsAssets) -> Self { - let mut m_ass_vec = Vec::new(); - - // This is so stupid. `MintsAssets` doesn't have a `len` method for some reason. - for idx in 0.. { - if let Some(m_ass) = value.get(idx) { - m_ass_vec.push(m_ass); - } else { - break; - } - } - - m_ass_vec.into_iter().fold(BTreeMap::new(), |acc, m| { - let ass = BTreeMap::from_csl(&m); - union_b_tree_maps_with(|l, r| l + r, [&acc, &ass]) - }) - } -} - -impl FromCSL for Value { - fn from_csl(mint: &csl::Mint) -> Self { - let keys = mint.keys(); - Value( - (0..keys.len()) - .map(|idx| { - let sh = keys.get(idx); - let ass = mint.get_all(&sh).unwrap_or(csl::MintsAssets::new()); - ( - CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&sh)), - BTreeMap::from_csl(&ass), - ) - }) - .collect::>>(), - ) - } -} - -impl FromCSL for Vec { - fn from_csl(value: &csl::RequiredSigners) -> Self { - (0..value.len()) - .map(|idx| Ed25519PubKeyHash::from_csl(&value.get(idx))) - .collect() - } -} - -impl FromCSL for Vec { - fn from_csl(value: &csl::NativeScripts) -> Self { - (0..value.len()).map(|idx| value.get(idx)).collect() - } -} - -impl FromCSL for Vec { - fn from_csl(value: &csl::plutus::PlutusScripts) -> Self { - (0..value.len()).map(|idx| value.get(idx)).collect() - } -} diff --git a/plutus-ledger-api/src/utils/mod.rs b/plutus-ledger-api/src/utils/mod.rs index eee5d19..a8a7dcd 100644 --- a/plutus-ledger-api/src/utils/mod.rs +++ b/plutus-ledger-api/src/utils/mod.rs @@ -1,3 +1 @@ pub mod aux; -pub mod csl_to_pla; -pub mod pla_to_csl; diff --git a/plutus-ledger-api/src/utils/pla_to_csl.rs b/plutus-ledger-api/src/utils/pla_to_csl.rs deleted file mode 100644 index 5755c85..0000000 --- a/plutus-ledger-api/src/utils/pla_to_csl.rs +++ /dev/null @@ -1,516 +0,0 @@ -use std::collections::BTreeMap; - -use cardano_serialization_lib as csl; -use num_bigint::{BigInt, TryFromBigIntError}; -use num_traits::sign::Signed; - -use crate::{ - plutus_data::PlutusData, - v2::{ - address::{ - Address, CertificateIndex, ChainPointer, Credential, Slot, StakingCredential, - TransactionIndex, - }, - assoc_map::AssocMap, - crypto::Ed25519PubKeyHash, - datum::{Datum, DatumHash, OutputDatum}, - redeemer::Redeemer, - script::{MintingPolicyHash, ScriptHash}, - transaction::{POSIXTimeRange, TransactionHash, TransactionInput, TransactionOutput}, - value::{CurrencySymbol, TokenName, Value}, - }, -}; - -#[derive(Debug, thiserror::Error)] -pub enum TryFromPLAError { - #[error("{0}")] - CSLDeserializeError(csl::error::DeserializeError), - - #[error("{0}")] - CSLJsError(csl::error::JsError), - - #[error("Unable to cast BigInt {0} into type {1}: value is out of bound")] - BigIntOutOfRange(BigInt, String), - - #[error("Unable to represent PLA value in CSL: ${0}")] - ImpossibleConversion(String), - - #[error("Invalid valid transaction time range: ${0:?}")] - InvalidTimeRange(POSIXTimeRange), - - #[error("Script is missing from context: {0:?}")] - MissingScript(ScriptHash), -} - -/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart -/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough -pub trait TryFromPLA { - fn try_from_pla(val: &T) -> Result - where - Self: Sized; -} - -/// Convert a plutus-ledger-api type to its cardano-serialization-lib counterpart -/// `try_to_csl_with` accepts extra data where the PLA data itself is not enough -/// -/// DO NOT IMPLEMENT THIS DIRECTLY. Implement `TryFromPLA` instead. -pub trait TryToCSL { - fn try_to_csl(&self) -> Result; -} - -impl TryToCSL for T -where - U: TryFromPLA, -{ - fn try_to_csl(&self) -> Result { - TryFromPLA::try_from_pla(self) - } -} - -impl TryFromPLA for csl::utils::BigNum { - fn try_from_pla(val: &u64) -> Result { - // BigNum(s) are u64 under the hood. - - Ok(csl::utils::BigNum::from(*val)) - } -} - -impl TryFromPLA for csl::utils::BigNum { - fn try_from_pla(val: &BigInt) -> Result { - // BigNum(s) are u64 under the hood. - let x: u64 = val - .to_owned() - .try_into() - .map_err(|err: TryFromBigIntError| { - TryFromPLAError::BigIntOutOfRange(err.into_original(), "u64".into()) - })?; - - x.try_to_csl() - } -} - -impl TryFromPLA for csl::utils::BigInt { - fn try_from_pla(val: &BigInt) -> Result { - Ok(val.to_owned().into()) - } -} - -impl TryFromPLA for csl::utils::Int { - fn try_from_pla(val: &BigInt) -> Result { - if val.is_negative() { - Ok(csl::utils::Int::new_negative(&(val.abs()).try_to_csl()?)) - } else { - Ok(csl::utils::Int::new(&val.try_to_csl()?)) - } - } -} - -impl TryFromPLA for csl::utils::Int { - fn try_from_pla(val: &i64) -> Result { - if val.is_negative() { - Ok(csl::utils::Int::new_negative(&csl::utils::to_bignum( - val.unsigned_abs(), - ))) - } else { - Ok(csl::utils::Int::new(&csl::utils::to_bignum(*val as u64))) - } - } -} - -impl TryFromPLA for csl::crypto::Ed25519KeyHash { - fn try_from_pla(val: &Ed25519PubKeyHash) -> Result { - csl::crypto::Ed25519KeyHash::from_bytes(val.0 .0.to_owned()) - .map_err(TryFromPLAError::CSLDeserializeError) - } -} - -impl TryFromPLA for csl::crypto::ScriptHash { - fn try_from_pla(val: &ScriptHash) -> Result { - csl::crypto::ScriptHash::from_bytes(val.0 .0.to_owned()) - .map_err(TryFromPLAError::CSLDeserializeError) - } -} - -impl TryFromPLA for csl::crypto::TransactionHash { - fn try_from_pla(val: &TransactionHash) -> Result { - csl::crypto::TransactionHash::from_bytes(val.0 .0.to_owned()) - .map_err(TryFromPLAError::CSLDeserializeError) - } -} - -impl TryFromPLA for u32 /* TransactionIndex */ { - fn try_from_pla(val: &BigInt) -> Result { - val.to_owned() - .try_into() - .map_err(|err: TryFromBigIntError| { - TryFromPLAError::BigIntOutOfRange(err.into_original(), "u32".into()) - }) - } -} - -impl TryFromPLA for csl::TransactionInput { - fn try_from_pla(val: &TransactionInput) -> Result { - Ok(csl::TransactionInput::new( - &val.transaction_id.try_to_csl()?, - val.index.try_to_csl()?, - )) - } -} - -impl TryFromPLA> for csl::TransactionInputs { - fn try_from_pla(val: &Vec) -> Result { - val.iter() - .try_fold(csl::TransactionInputs::new(), |mut acc, input| { - acc.add(&input.try_to_csl()?); - Ok(acc) - }) - } -} - -#[derive(Clone, Debug)] -pub struct TransactionOutputWithExtraInfo<'a> { - pub transaction_output: &'a TransactionOutput, - pub scripts: &'a BTreeMap, - pub network_id: u8, - pub data_cost: &'a csl::DataCost, -} - -impl TryFromPLA> for csl::TransactionOutput { - fn try_from_pla(val: &TransactionOutputWithExtraInfo<'_>) -> Result { - let mut output_builder = csl::output_builder::TransactionOutputBuilder::new().with_address( - &AddressWithExtraInfo { - address: &val.transaction_output.address, - network_tag: val.network_id, - } - .try_to_csl()?, - ); - - output_builder = match &val.transaction_output.datum { - OutputDatum::None => output_builder, - OutputDatum::InlineDatum(Datum(d)) => output_builder.with_plutus_data(&d.try_to_csl()?), - OutputDatum::DatumHash(dh) => output_builder.with_data_hash(&dh.try_to_csl()?), - }; - - let script_ref = val - .transaction_output - .reference_script - .clone() - .map(|script_hash| -> Result<_, TryFromPLAError> { - let script = val - .scripts - .get(&script_hash) - .ok_or(TryFromPLAError::MissingScript(script_hash))?; - Ok(csl::ScriptRef::new_plutus_script(script)) - }) - .transpose()?; - - if let Some(script_ref) = &script_ref { - output_builder = output_builder.with_script_ref(script_ref); - }; - - let value_without_min_utxo = val.transaction_output.value.try_to_csl()?; - - let mut calc = csl::utils::MinOutputAdaCalculator::new_empty(val.data_cost) - .map_err(TryFromPLAError::CSLJsError)?; - calc.set_amount(&value_without_min_utxo); - match &val.transaction_output.datum { - OutputDatum::None => {} - OutputDatum::InlineDatum(Datum(d)) => { - calc.set_plutus_data(&d.try_to_csl()?); - } - OutputDatum::DatumHash(dh) => { - calc.set_data_hash(&dh.try_to_csl()?); - } - }; - if let Some(script_ref) = script_ref { - calc.set_script_ref(&script_ref); - } - - let required_coin = calc.calculate_ada().map_err(TryFromPLAError::CSLJsError)?; - let coin = std::cmp::max(value_without_min_utxo.coin(), required_coin); - - let value = match value_without_min_utxo.multiasset() { - Some(multiasset) => csl::utils::Value::new_with_assets(&coin, &multiasset), - None => csl::utils::Value::new(&coin), - }; - - output_builder - .next() - .map_err(TryFromPLAError::CSLJsError)? - .with_value(&value) - .build() - .map_err(TryFromPLAError::CSLJsError) - } -} - -impl TryFromPLA for csl::PolicyID { - fn try_from_pla(val: &MintingPolicyHash) -> Result { - val.0.try_to_csl() - } -} - -impl TryFromPLA for csl::AssetName { - fn try_from_pla(val: &TokenName) -> Result { - csl::AssetName::new(val.0 .0.to_owned()).map_err(TryFromPLAError::CSLJsError) - } -} - -impl TryFromPLA> for csl::Assets { - fn try_from_pla(val: &BTreeMap) -> Result { - val.iter().try_fold(csl::Assets::new(), |mut acc, (k, v)| { - acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); - Ok(acc) - }) - } -} - -impl TryFromPLA> for csl::MintAssets { - fn try_from_pla(val: &BTreeMap) -> Result { - val.iter() - .try_fold(csl::MintAssets::new(), |mut acc, (k, v)| { - acc.insert(&k.try_to_csl()?, v.try_to_csl()?); - Ok(acc) - }) - } -} - -impl TryFromPLA for csl::utils::Value { - fn try_from_pla(val: &Value) -> Result { - let coin: csl::utils::Coin = val - .0 - .get(&CurrencySymbol::Ada) - .and_then(|m| m.get(&TokenName::ada())) - .map_or(Ok(csl::utils::BigNum::zero()), TryToCSL::try_to_csl)?; - - let m_ass = val - .0 - .iter() - .filter_map(|(cs, tn_map)| match &cs { - CurrencySymbol::Ada => None, - CurrencySymbol::NativeToken(h) => Some((h, tn_map)), - }) - .try_fold(csl::MultiAsset::new(), |mut acc, (cs, ass)| { - acc.insert(&cs.try_to_csl()?, &ass.try_to_csl()?); - Ok(acc) - })?; - - let mut v = csl::utils::Value::new(&coin); - - v.set_multiasset(&m_ass); - - Ok(v) - } -} - -impl TryFromPLA for csl::plutus::PlutusData { - fn try_from_pla(val: &PlutusData) -> Result { - match val { - PlutusData::Constr(tag, args) => Ok(csl::plutus::PlutusData::new_constr_plutus_data( - &csl::plutus::ConstrPlutusData::new(&tag.try_to_csl()?, &args.try_to_csl()?), - )), - PlutusData::Map(l) => Ok(csl::plutus::PlutusData::new_map(&l.try_to_csl()?)), - PlutusData::List(l) => Ok(csl::plutus::PlutusData::new_list(&l.try_to_csl()?)), - PlutusData::Integer(i) => Ok(csl::plutus::PlutusData::new_integer(&i.try_to_csl()?)), - PlutusData::Bytes(b) => Ok(csl::plutus::PlutusData::new_bytes(b.to_owned())), - } - } -} - -impl TryFromPLA> for csl::plutus::PlutusList { - fn try_from_pla(val: &Vec) -> Result { - val.iter() - // traverse - .map(|x| x.try_to_csl()) - .collect::, TryFromPLAError>>() - .map(|x| x.into()) - } -} - -impl TryFromPLA> for csl::plutus::PlutusMap { - fn try_from_pla(val: &Vec<(PlutusData, PlutusData)>) -> Result { - val.iter() - .try_fold(csl::plutus::PlutusMap::new(), |mut acc, (k, v)| { - acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); - Ok(acc) - }) - } -} - -impl TryFromPLA for csl::crypto::DataHash { - fn try_from_pla(val: &DatumHash) -> Result { - csl::crypto::DataHash::from_bytes(val.0 .0.to_owned()) - .map_err(TryFromPLAError::CSLDeserializeError) - } -} - -impl TryFromPLA for csl::plutus::PlutusData { - fn try_from_pla(val: &Datum) -> Result { - val.0.try_to_csl() - } -} - -impl TryFromPLA for csl::address::Pointer { - fn try_from_pla(val: &ChainPointer) -> Result { - Ok(csl::address::Pointer::new_pointer( - &val.slot_number.try_to_csl()?, - &val.transaction_index.try_to_csl()?, - &val.certificate_index.try_to_csl()?, - )) - } -} - -impl TryFromPLA for csl::utils::BigNum { - fn try_from_pla(val: &Slot) -> Result { - val.0.try_to_csl() - } -} - -impl TryFromPLA for csl::utils::BigNum { - fn try_from_pla(val: &TransactionIndex) -> Result { - val.0.try_to_csl() - } -} - -impl TryFromPLA for csl::utils::BigNum { - fn try_from_pla(val: &CertificateIndex) -> Result { - val.0.try_to_csl() - } -} - -impl TryFromPLA for csl::address::StakeCredential { - fn try_from_pla(val: &Credential) -> Result { - match val { - Credential::PubKey(pkh) => Ok(csl::address::StakeCredential::from_keyhash( - &pkh.try_to_csl()?, - )), - Credential::Script(sh) => Ok(csl::address::StakeCredential::from_scripthash( - &sh.0.try_to_csl()?, - )), - } - } -} - -impl TryFromPLA for csl::address::StakeCredential { - fn try_from_pla(val: &StakingCredential) -> Result { - match val { - StakingCredential::Hash(c) => c.try_to_csl(), - StakingCredential::Pointer(_) => Err(TryFromPLAError::ImpossibleConversion( - "cannot represent chain pointer".into(), - )), - } - } -} - -#[derive(Clone, Debug)] -pub struct AddressWithExtraInfo<'a> { - pub address: &'a Address, - pub network_tag: u8, -} - -impl TryFromPLA> for csl::address::Address { - fn try_from_pla(val: &AddressWithExtraInfo<'_>) -> Result { - let payment = val.address.credential.try_to_csl()?; - - Ok(match val.address.staking_credential { - None => csl::address::EnterpriseAddress::new(val.network_tag, &payment).to_address(), - Some(ref sc) => match sc { - StakingCredential::Hash(c) => { - csl::address::BaseAddress::new(val.network_tag, &payment, &c.try_to_csl()?) - .to_address() - } - StakingCredential::Pointer(ptr) => { - csl::address::PointerAddress::new(val.network_tag, &payment, &ptr.try_to_csl()?) - .to_address() - } - }, - }) - } -} - -impl std::fmt::Display for AddressWithExtraInfo<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let bech32_addr: Option = self - .try_to_csl() - .ok() - .and_then(|csl_addr: csl::address::Address| csl_addr.to_bech32(None).ok()); - match bech32_addr { - Some(addr) => write!(f, "{}", addr), - None => write!(f, "INVALID ADDRESS {:?}", self), - } - } -} - -#[derive(Clone, Debug)] -struct RewardAddressWithExtraInfo<'a> { - pub staking_credential: &'a StakingCredential, - pub network_tag: u8, -} - -impl TryFromPLA> for csl::address::RewardAddress { - fn try_from_pla(val: &RewardAddressWithExtraInfo<'_>) -> Result { - Ok(csl::address::RewardAddress::new( - val.network_tag, - &val.staking_credential.try_to_csl()?, - )) - } -} - -#[derive(Clone, Debug)] -struct WithdrawalsWithExtraInfo<'a> { - withdrawals: &'a AssocMap, - network_tag: u8, -} - -impl TryFromPLA> for csl::Withdrawals { - fn try_from_pla(val: &WithdrawalsWithExtraInfo<'_>) -> Result { - val.withdrawals - .0 - .iter() - .try_fold(csl::Withdrawals::new(), |mut acc, (s, q)| { - acc.insert( - &RewardAddressWithExtraInfo { - staking_credential: s, - network_tag: val.network_tag, - } - .try_to_csl()?, - &q.try_to_csl()?, - ); - Ok(acc) - }) - } -} - -#[derive(Clone, Debug)] -struct RedeemerWithExtraInfo<'a> { - redeemer: &'a Redeemer, - tag: &'a csl::plutus::RedeemerTag, - index: u64, -} - -impl TryFromPLA> for csl::plutus::Redeemer { - fn try_from_pla<'a>( - val: &RedeemerWithExtraInfo<'_>, - ) -> Result { - let Redeemer(plutus_data) = val.redeemer; - Ok(csl::plutus::Redeemer::new( - val.tag, - &val.index.try_to_csl()?, - &plutus_data.try_to_csl()?, - &csl::plutus::ExUnits::new(&csl::utils::to_bignum(0), &csl::utils::to_bignum(0)), - )) - } -} - -impl TryFromPLA for Option { - fn try_from_pla( - pla_output_datum: &OutputDatum, - ) -> Result, TryFromPLAError> { - Ok(match pla_output_datum { - OutputDatum::None => None, - OutputDatum::InlineDatum(Datum(d)) => { - Some(csl::OutputDatum::new_data(&d.try_to_csl()?)) - } - OutputDatum::DatumHash(dh) => Some(csl::OutputDatum::new_data_hash(&dh.try_to_csl()?)), - }) - } -} diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index 648ac07..7f2c0c6 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -4,16 +4,21 @@ use std::str::FromStr; use anyhow::anyhow; use cardano_serialization_lib as csl; +use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{ verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, }; -use crate::utils::csl_to_pla::TryToPLA; use crate::v1::crypto::Ed25519PubKeyHash; use crate::v1::script::ValidatorHash; #[cfg(feature = "lbf")] use lbr_prelude::json::{self, Error, Json}; use num_bigint::BigInt; +///////////// +// Address // +///////////// + #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -30,6 +35,15 @@ pub struct Address { pub staking_credential: Option, } +impl Address { + pub fn with_extra_info(&self, network_tag: u8) -> AddressWithExtraInfo { + AddressWithExtraInfo { + address: self, + network_tag, + } + } +} + impl IsPlutusData for Address { fn to_plutus_data(&self) -> PlutusData { PlutusData::Constr( @@ -79,6 +93,75 @@ impl FromStr for Address { } } +impl TryFromCSL for Address { + fn try_from_csl(value: &csl::address::Address) -> Result { + if let Some(addr) = csl::address::BaseAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: Some(StakingCredential::from_csl(&addr.stake_cred())), + }) + } else if let Some(addr) = csl::address::PointerAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: Some(StakingCredential::from_csl(&addr.stake_pointer())), + }) + } else if let Some(addr) = csl::address::EnterpriseAddress::from_address(value) { + Ok(Address { + credential: Credential::from_csl(&addr.payment_cred()), + staking_credential: None, + }) + } else { + Err(TryFromCSLError::ImpossibleConversion(format!( + "Unable to represent address {:?}", + value + ))) + } + } +} + +#[derive(Clone, Debug)] +pub struct AddressWithExtraInfo<'a> { + pub address: &'a Address, + pub network_tag: u8, +} + +impl TryFromPLA> for csl::address::Address { + fn try_from_pla(val: &AddressWithExtraInfo<'_>) -> Result { + let payment = val.address.credential.try_to_csl()?; + + Ok(match val.address.staking_credential { + None => csl::address::EnterpriseAddress::new(val.network_tag, &payment).to_address(), + Some(ref sc) => match sc { + StakingCredential::Hash(c) => { + csl::address::BaseAddress::new(val.network_tag, &payment, &c.try_to_csl()?) + .to_address() + } + StakingCredential::Pointer(ptr) => { + csl::address::PointerAddress::new(val.network_tag, &payment, &ptr.try_to_csl()?) + .to_address() + } + }, + }) + } +} + +impl std::fmt::Display for AddressWithExtraInfo<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let bech32_addr: Option = self + .try_to_csl() + .ok() + .and_then(|csl_addr: csl::address::Address| csl_addr.to_bech32(None).ok()); + match bech32_addr { + Some(addr) => write!(f, "{}", addr), + None => write!(f, "INVALID ADDRESS {:?}", self), + } + } +} + +//////////////// +// Credential // +//////////////// + /// A public key hash or validator hash credential (used as a payment or a staking credential) #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -173,6 +256,36 @@ impl Json for Credential { } } +impl FromCSL for Credential { + fn from_csl(value: &csl::address::StakeCredential) -> Self { + match value.kind() { + csl::address::StakeCredKind::Key => { + Credential::PubKey(Ed25519PubKeyHash::from_csl(&value.to_keyhash().unwrap())) + } + csl::address::StakeCredKind::Script => { + Credential::Script(ValidatorHash::from_csl(&value.to_scripthash().unwrap())) + } + } + } +} + +impl TryFromPLA for csl::address::StakeCredential { + fn try_from_pla(val: &Credential) -> Result { + match val { + Credential::PubKey(pkh) => Ok(csl::address::StakeCredential::from_keyhash( + &pkh.try_to_csl()?, + )), + Credential::Script(sh) => Ok(csl::address::StakeCredential::from_scripthash( + &sh.0.try_to_csl()?, + )), + } + } +} + +/////////////////////// +// StakingCredential // +/////////////////////// + /// Credential (public key hash or pointer) used for staking #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -278,6 +391,48 @@ impl Json for StakingCredential { } } +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::address::StakeCredential) -> Self { + StakingCredential::Hash(Credential::from_csl(value)) + } +} + +impl TryFromPLA for csl::address::StakeCredential { + fn try_from_pla(val: &StakingCredential) -> Result { + match val { + StakingCredential::Hash(c) => c.try_to_csl(), + StakingCredential::Pointer(_) => Err(TryFromPLAError::ImpossibleConversion( + "cannot represent chain pointer".into(), + )), + } + } +} + +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::address::Pointer) -> Self { + StakingCredential::Pointer(ChainPointer::from_csl(value)) + } +} + +#[derive(Clone, Debug)] +pub struct RewardAddressWithExtraInfo<'a> { + pub staking_credential: &'a StakingCredential, + pub network_tag: u8, +} + +impl TryFromPLA> for csl::address::RewardAddress { + fn try_from_pla(val: &RewardAddressWithExtraInfo<'_>) -> Result { + Ok(csl::address::RewardAddress::new( + val.network_tag, + &val.staking_credential.try_to_csl()?, + )) + } +} + +////////////////// +// ChainPointer // +////////////////// + /// In an address, a chain pointer refers to a point of the chain containing a stake key /// registration certificate. A point is identified by 3 coordinates: /// - An absolute slot number @@ -292,6 +447,30 @@ pub struct ChainPointer { pub certificate_index: CertificateIndex, } +impl FromCSL for ChainPointer { + fn from_csl(value: &csl::address::Pointer) -> Self { + ChainPointer { + slot_number: Slot::from_csl(&value.slot_bignum()), + transaction_index: TransactionIndex::from_csl(&value.tx_index_bignum()), + certificate_index: CertificateIndex::from_csl(&value.cert_index_bignum()), + } + } +} + +impl TryFromPLA for csl::address::Pointer { + fn try_from_pla(val: &ChainPointer) -> Result { + Ok(csl::address::Pointer::new_pointer( + &val.slot_number.try_to_csl()?, + &val.transaction_index.try_to_csl()?, + &val.certificate_index.try_to_csl()?, + )) + } +} + +////////// +// Slot // +////////// + /// Number of slots elapsed since genesis #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -308,6 +487,22 @@ impl IsPlutusData for Slot { } } +impl FromCSL for Slot { + fn from_csl(value: &csl::utils::BigNum) -> Self { + Slot(BigInt::from_csl(value)) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &Slot) -> Result { + val.0.try_to_csl() + } +} + +////////////////////// +// CertificateIndex // +////////////////////// + /// Position of the certificate in a certain transaction #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -324,6 +519,22 @@ impl IsPlutusData for CertificateIndex { } } +impl FromCSL for CertificateIndex { + fn from_csl(value: &csl::utils::BigNum) -> Self { + CertificateIndex(BigInt::from_csl(value)) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &CertificateIndex) -> Result { + val.0.try_to_csl() + } +} + +////////////////////// +// TransactionIndex // +////////////////////// + /// Position of a transaction in a given slot /// This is not identical to the index of a `TransactionInput` #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -340,3 +551,15 @@ impl IsPlutusData for TransactionIndex { IsPlutusData::from_plutus_data(data).map(Self) } } + +impl FromCSL for TransactionIndex { + fn from_csl(value: &csl::utils::BigNum) -> Self { + TransactionIndex(BigInt::from_csl(value)) + } +} + +impl TryFromPLA for csl::utils::BigNum { + fn try_from_pla(val: &TransactionIndex) -> Result { + val.0.try_to_csl() + } +} diff --git a/plutus-ledger-api/src/v1/assoc_map.rs b/plutus-ledger-api/src/v1/assoc_map.rs index 346933c..54fed54 100644 --- a/plutus-ledger-api/src/v1/assoc_map.rs +++ b/plutus-ledger-api/src/v1/assoc_map.rs @@ -8,6 +8,10 @@ use serde::{Deserialize, Serialize}; use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}; +////////////// +// AssocMap // +////////////// + #[derive(Debug, PartialEq, Eq, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct AssocMap(pub Vec<(K, V)>); diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index 6b8ec77..5cb8376 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -1,11 +1,23 @@ //! Types for cryptographic primitives, and other lower level building blocks -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}; +use cardano_serialization_lib as csl; use data_encoding::HEXLOWER; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::{ + csl::{ + csl_to_pla::FromCSL, + pla_to_csl::{TryFromPLA, TryFromPLAError}, + }, + plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}, +}; + +/////////////////////// +// Ed25519PubKeyHash // +/////////////////////// + /// ED25519 public key hash /// This is the standard cryptography in Cardano, commonly referred to as `PubKeyHash` in Plutus /// and other libraries @@ -31,6 +43,31 @@ impl IsPlutusData for Ed25519PubKeyHash { } } +impl FromCSL for Ed25519PubKeyHash { + fn from_csl(value: &csl::crypto::Ed25519KeyHash) -> Self { + Ed25519PubKeyHash(LedgerBytes(value.to_bytes())) + } +} + +impl TryFromPLA for csl::crypto::Ed25519KeyHash { + fn try_from_pla(val: &Ed25519PubKeyHash) -> Result { + csl::crypto::Ed25519KeyHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::RequiredSigners) -> Self { + (0..value.len()) + .map(|idx| Ed25519PubKeyHash::from_csl(&value.get(idx))) + .collect() + } +} + +/////////////////////// +// PaymentPubKeyHash // +/////////////////////// + /// Standard public key hash used to verify a transaction witness #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -54,6 +91,10 @@ impl IsPlutusData for PaymentPubKeyHash { } } +///////////////////// +// StakePubKeyHash // +///////////////////// + /// Standard public key hash used to verify a staking #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -77,6 +118,10 @@ impl IsPlutusData for StakePubKeyHash { } } +///////////////// +// LedgerBytes // +///////////////// + /// A bytestring in the Cardano ledger context #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/plutus-ledger-api/src/v1/datum.rs b/plutus-ledger-api/src/v1/datum.rs index bc3806f..712dea5 100644 --- a/plutus-ledger-api/src/v1/datum.rs +++ b/plutus-ledger-api/src/v1/datum.rs @@ -1,4 +1,9 @@ //! Types related to Plutus Datums + +use cardano_serialization_lib as csl; + +use crate::csl::csl_to_pla::FromCSL; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; use crate::v1::crypto::LedgerBytes; #[cfg(feature = "lbf")] @@ -7,6 +12,10 @@ use lbr_prelude::json::Json; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +/////////////// +// DatumHash // +/////////////// + /// blake2b-256 hash of a datum #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "lbf", derive(Json))] @@ -23,6 +32,23 @@ impl IsPlutusData for DatumHash { } } +impl FromCSL for DatumHash { + fn from_csl(value: &csl::crypto::DataHash) -> Self { + DatumHash(LedgerBytes(value.to_bytes())) + } +} + +impl TryFromPLA for csl::crypto::DataHash { + fn try_from_pla(val: &DatumHash) -> Result { + csl::crypto::DataHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +/////////// +// Datum // +/////////// + /// Piece of information associated with a UTxO encoded into a PlutusData type. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "lbf", derive(Json))] @@ -38,3 +64,9 @@ impl IsPlutusData for Datum { IsPlutusData::from_plutus_data(data).map(Self) } } + +impl TryFromPLA for csl::plutus::PlutusData { + fn try_from_pla(val: &Datum) -> Result { + val.0.try_to_csl() + } +} diff --git a/plutus-ledger-api/src/v1/interval.rs b/plutus-ledger-api/src/v1/interval.rs index 4f5bbd6..313e7e5 100644 --- a/plutus-ledger-api/src/v1/interval.rs +++ b/plutus-ledger-api/src/v1/interval.rs @@ -10,6 +10,10 @@ use num_bigint::BigInt; use serde::{Deserialize, Serialize}; use std::cmp; +////////////// +// Interval // +////////////// + /// An abstraction over `PlutusInterval`, allowing valid values only #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -223,6 +227,10 @@ where } } +//////////////////// +// PlutusInterval // +//////////////////// + /// An interval of `T`s. /// /// The interval may be either closed or open at either end, meaning @@ -283,6 +291,10 @@ where } } +//////////////// +// UpperBound // +//////////////// + #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -329,6 +341,10 @@ where } } +//////////////// +// LowerBound // +//////////////// + #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -375,6 +391,10 @@ where } } +////////////// +// Extended // +////////////// + /// A set extended with a positive and negative infinity. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "lbf", derive(Json))] diff --git a/plutus-ledger-api/src/v1/redeemer.rs b/plutus-ledger-api/src/v1/redeemer.rs index e5b9198..35850c3 100644 --- a/plutus-ledger-api/src/v1/redeemer.rs +++ b/plutus-ledger-api/src/v1/redeemer.rs @@ -1,11 +1,20 @@ //! Types related to Plutus Redeemers -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; -use crate::v1::crypto::LedgerBytes; + +use cardano_serialization_lib as csl; + #[cfg(feature = "lbf")] use lbr_prelude::json::Json; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::v1::crypto::LedgerBytes; + +////////////// +// Redeemer // +////////////// + /// Piece of information attached to a transaction when redeeming a value from a validator or a /// minting policy #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -23,6 +32,31 @@ impl IsPlutusData for Redeemer { } } +#[derive(Clone, Debug)] +struct RedeemerWithExtraInfo<'a> { + redeemer: &'a Redeemer, + tag: &'a csl::plutus::RedeemerTag, + index: u64, +} + +impl TryFromPLA> for csl::plutus::Redeemer { + fn try_from_pla<'a>( + val: &RedeemerWithExtraInfo<'_>, + ) -> Result { + let Redeemer(plutus_data) = val.redeemer; + Ok(csl::plutus::Redeemer::new( + val.tag, + &val.index.try_to_csl()?, + &plutus_data.try_to_csl()?, + &csl::plutus::ExUnits::new(&csl::utils::to_bignum(0), &csl::utils::to_bignum(0)), + )) + } +} + +////////////////// +// RedeemerHash // +////////////////// + /// blake2b-256 hash of a datum #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "lbf", derive(Json))] diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index 4b5b612..b95c655 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -1,11 +1,21 @@ //! Types related to Plutus scripts -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; -use crate::v1::crypto::LedgerBytes; + +use cardano_serialization_lib as csl; + #[cfg(feature = "lbf")] use lbr_prelude::json::Json; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::csl::csl_to_pla::FromCSL; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::v1::crypto::LedgerBytes; + +/////////////////// +// ValidatorHash // +/////////////////// + /// Identifier of a validator script #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -22,6 +32,16 @@ impl IsPlutusData for ValidatorHash { } } +impl FromCSL for ValidatorHash { + fn from_csl(value: &csl::crypto::ScriptHash) -> Self { + ValidatorHash(ScriptHash::from_csl(value)) + } +} + +/////////////////////// +// MintingPolicyHash // +/////////////////////// + /// Hash of a minting policy script #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -38,6 +58,22 @@ impl IsPlutusData for MintingPolicyHash { } } +impl FromCSL for MintingPolicyHash { + fn from_csl(value: &csl::PolicyID) -> Self { + MintingPolicyHash(ScriptHash(LedgerBytes(value.to_bytes()))) + } +} + +impl TryFromPLA for csl::PolicyID { + fn try_from_pla(val: &MintingPolicyHash) -> Result { + val.0.try_to_csl() + } +} + +//////////////// +// ScriptHash // +//////////////// + /// Hash of a Plutus script #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -53,3 +89,16 @@ impl IsPlutusData for ScriptHash { IsPlutusData::from_plutus_data(data).map(Self) } } + +impl FromCSL for ScriptHash { + fn from_csl(value: &csl::crypto::ScriptHash) -> Self { + ScriptHash(LedgerBytes(value.to_bytes())) + } +} + +impl TryFromPLA for csl::crypto::ScriptHash { + fn try_from_pla(val: &ScriptHash) -> Result { + csl::crypto::ScriptHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index e8d7e3b..65069e1 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -1,6 +1,13 @@ //! Types related to Cardano transactions. use std::fmt; +use cardano_serialization_lib as csl; +#[cfg(feature = "lbf")] +use lbr_prelude::json::Json; +use num_bigint::BigInt; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + use super::{ address::{Address, StakingCredential}, crypto::{LedgerBytes, PaymentPubKeyHash}, @@ -8,16 +15,22 @@ use super::{ interval::PlutusInterval, value::{CurrencySymbol, Value}, }; -use crate::plutus_data::{ - parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, verify_constr_fields, - IsPlutusData, PlutusData, PlutusDataError, PlutusType, + +use crate::{ + csl::pla_to_csl::{TryFromPLAError, TryToCSL}, + plutus_data::{ + parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, verify_constr_fields, + IsPlutusData, PlutusData, PlutusDataError, PlutusType, + }, }; -use crate::utils::aux::{none, singleton}; -#[cfg(feature = "lbf")] -use lbr_prelude::json::Json; -use num_bigint::BigInt; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use crate::{ + csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}, + utils::aux::{none, singleton}, +}; + +////////////////////// +// TransactionInput // +////////////////////// /// An input of a transaction /// @@ -72,6 +85,46 @@ impl IsPlutusData for TransactionInput { } } +impl FromCSL for TransactionInput { + fn from_csl(value: &csl::TransactionInput) -> Self { + TransactionInput { + transaction_id: TransactionHash::from_csl(&value.transaction_id()), + index: BigInt::from_csl(&value.index()), + } + } +} + +impl TryFromPLA for csl::TransactionInput { + fn try_from_pla(val: &TransactionInput) -> Result { + Ok(csl::TransactionInput::new( + &val.transaction_id.try_to_csl()?, + val.index.try_to_csl()?, + )) + } +} + +impl FromCSL for Vec { + fn from_csl(value: &csl::TransactionInputs) -> Self { + (0..value.len()) + .map(|idx| TransactionInput::from_csl(&value.get(idx))) + .collect() + } +} + +impl TryFromPLA> for csl::TransactionInputs { + fn try_from_pla(val: &Vec) -> Result { + val.iter() + .try_fold(csl::TransactionInputs::new(), |mut acc, input| { + acc.add(&input.try_to_csl()?); + Ok(acc) + }) + } +} + +///////////////////// +// TransactionHash // +///////////////////// + /// 32-bytes blake2b256 hash of a transaction body. /// /// Also known as Transaction ID or `TxID`. @@ -113,6 +166,23 @@ impl IsPlutusData for TransactionHash { } } +impl FromCSL for TransactionHash { + fn from_csl(value: &csl::crypto::TransactionHash) -> Self { + TransactionHash(LedgerBytes(value.to_bytes())) + } +} + +impl TryFromPLA for csl::crypto::TransactionHash { + fn try_from_pla(val: &TransactionHash) -> Result { + csl::crypto::TransactionHash::from_bytes(val.0 .0.to_owned()) + .map_err(TryFromPLAError::CSLDeserializeError) + } +} + +/////////////////////// +// TransactionOutput // +/////////////////////// + /// An output of a transaction /// /// This must include the target address, the hash of the datum attached, and the amount of output @@ -163,6 +233,10 @@ impl IsPlutusData for TransactionOutput { } } +/////////////// +// POSIXTime // +/////////////// + /// POSIX time is measured as the number of milliseconds since 1970-01-01T00:00:00Z #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -208,8 +282,16 @@ impl TryFrom for chrono::DateTime { } } +//////////////////// +// POSIXTimeRange // +//////////////////// + pub type POSIXTimeRange = PlutusInterval; +////////////// +// TxInInfo // +////////////// + /// An input of a pending transaction. #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -260,6 +342,10 @@ impl From<(TransactionInput, TransactionOutput)> for TxInInfo { } } +/////////// +// DCert // +/////////// + /// Partial representation of digests of certificates on the ledger. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -355,6 +441,10 @@ impl IsPlutusData for DCert { } } +/////////////////// +// ScriptPurpose // +/////////////////// + /// The purpose of the script that's currently running. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -395,6 +485,10 @@ impl IsPlutusData for ScriptPurpose { } } +///////////////////// +// TransactionInfo // +///////////////////// + /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus #[derive(Debug, PartialEq, Eq, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -451,6 +545,10 @@ impl IsPlutusData for TransactionInfo { } } +/////////////////// +// ScriptContext // +/////////////////// + /// The context that is presented to the currently-executing script. #[derive(Debug, PartialEq, Eq, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 07ae47a..238b6d8 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -1,10 +1,14 @@ //! Types related to Cardano values, such as Ada and native tokens. -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, + +use std::string::String; +use std::{ + collections::BTreeMap, + iter::Sum, + ops::{Add, Mul, Neg, Not, Sub}, }; -use crate::utils::aux::{singleton, union_btree_maps_with}; -use crate::v1::crypto::LedgerBytes; -use crate::v1::script::{MintingPolicyHash, ScriptHash}; +use std::{fmt, ops}; + +use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json, JsonType}; use num_bigint::BigInt; @@ -13,13 +17,19 @@ use num_traits::Zero; use serde::{Deserialize, Serialize}; #[cfg(feature = "lbf")] use serde_json; -use std::string::String; -use std::{ - collections::BTreeMap, - iter::Sum, - ops::{Add, Mul, Neg, Not, Sub}, + +use crate::csl::csl_to_pla::FromCSL; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::plutus_data::{ + verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, }; -use std::{fmt, ops}; +use crate::utils::aux::{singleton, union_b_tree_maps_with, union_btree_maps_with}; +use crate::v1::crypto::LedgerBytes; +use crate::v1::script::{MintingPolicyHash, ScriptHash}; + +//////////////////// +// CurrencySymbol // +//////////////////// /// Identifier of a currency, which could be either Ada (or tAda), or a native token represented by /// it's minting policy hash. A currency may be associated with multiple `AssetClass`es. @@ -95,6 +105,10 @@ impl Json for CurrencySymbol { } } +/////////// +// Value // +/////////// + /// A value that can contain multiple asset classes #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "lbf", derive(Json))] @@ -415,6 +429,152 @@ impl IsPlutusData for Value { } } +impl FromCSL for BTreeMap { + fn from_csl(value: &csl::Assets) -> Self { + let keys = value.keys(); + (0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { + let asset_name = keys.get(idx); + if let Some(quantity) = value.get(&asset_name) { + acc.insert( + TokenName::from_csl(&asset_name), + BigInt::from_csl(&quantity), + ); + } + acc + }) + } +} + +impl TryFromPLA> for csl::Assets { + fn try_from_pla(val: &BTreeMap) -> Result { + val.iter().try_fold(csl::Assets::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); + Ok(acc) + }) + } +} + +impl FromCSL for Value { + fn from_csl(value: &csl::MultiAsset) -> Self { + let keys = value.keys(); + Value((0..keys.len()).fold(BTreeMap::new(), |mut acc, idx| { + let script_hash = keys.get(idx); + if let Some(assets) = value.get(&script_hash) { + let assets = BTreeMap::from_csl(&assets); + acc.insert( + CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&script_hash)), + assets, + ); + } + acc + })) + } +} + +impl FromCSL for Value { + fn from_csl(value: &csl::utils::Value) -> Self { + let lovelaces = BigInt::from_csl(&value.coin()); + let mut pla_value = Value::ada_value(&lovelaces); + if let Some(multi_asset) = value.multiasset() { + pla_value = &pla_value + &Value::from_csl(&multi_asset) + } + pla_value + } +} + +impl TryFromPLA for csl::utils::Value { + fn try_from_pla(val: &Value) -> Result { + let coin: csl::utils::Coin = val + .0 + .get(&CurrencySymbol::Ada) + .and_then(|m| m.get(&TokenName::ada())) + .map_or(Ok(csl::utils::BigNum::zero()), TryToCSL::try_to_csl)?; + + let m_ass = val + .0 + .iter() + .filter_map(|(cs, tn_map)| match &cs { + CurrencySymbol::Ada => None, + CurrencySymbol::NativeToken(h) => Some((h, tn_map)), + }) + .try_fold(csl::MultiAsset::new(), |mut acc, (cs, ass)| { + acc.insert(&cs.try_to_csl()?, &ass.try_to_csl()?); + Ok(acc) + })?; + + let mut v = csl::utils::Value::new(&coin); + + v.set_multiasset(&m_ass); + + Ok(v) + } +} + +impl FromCSL for BTreeMap { + fn from_csl(m_ass: &csl::MintAssets) -> Self { + let keys = m_ass.keys(); + (0..keys.len()) + .map(|idx| { + let key = keys.get(idx); + let value = m_ass.get(&key).unwrap(); + (TokenName::from_csl(&key), BigInt::from_csl(&value)) + }) + .collect() + } +} + +impl FromCSL for BTreeMap { + fn from_csl(value: &csl::MintsAssets) -> Self { + let mut m_ass_vec = Vec::new(); + + // This is so stupid. `MintsAssets` doesn't have a `len` method for some reason. + for idx in 0.. { + if let Some(m_ass) = value.get(idx) { + m_ass_vec.push(m_ass); + } else { + break; + } + } + + m_ass_vec.into_iter().fold(BTreeMap::new(), |acc, m| { + let ass = BTreeMap::from_csl(&m); + union_b_tree_maps_with(|l, r| l + r, [&acc, &ass]) + }) + } +} + +impl TryFromPLA> for csl::MintAssets { + fn try_from_pla(val: &BTreeMap) -> Result { + val.iter() + .try_fold(csl::MintAssets::new(), |mut acc, (k, v)| { + acc.insert(&k.try_to_csl()?, v.try_to_csl()?); + Ok(acc) + }) + } +} + +impl FromCSL for Value { + fn from_csl(mint: &csl::Mint) -> Self { + let keys = mint.keys(); + Value( + (0..keys.len()) + .map(|idx| { + let sh = keys.get(idx); + let ass = mint.get_all(&sh).unwrap_or(csl::MintsAssets::new()); + ( + CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&sh)), + BTreeMap::from_csl(&ass), + ) + }) + .collect::>>(), + ) + } +} + +/////////////// +// TokenName // +/////////////// + /// Name of a token. This can be any arbitrary bytearray #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -468,6 +628,22 @@ impl fmt::Display for TokenName { } } +impl FromCSL for TokenName { + fn from_csl(value: &csl::AssetName) -> Self { + TokenName(LedgerBytes(value.name())) + } +} + +impl TryFromPLA for csl::AssetName { + fn try_from_pla(val: &TokenName) -> Result { + csl::AssetName::new(val.0 .0.to_owned()).map_err(TryFromPLAError::CSLJsError) + } +} + +//////////////// +// AssetClass // +//////////////// + /// AssetClass is uniquely identifying a specific asset #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/plutus-ledger-api/src/v2/datum.rs b/plutus-ledger-api/src/v2/datum.rs index 41af4d3..8b375d1 100644 --- a/plutus-ledger-api/src/v2/datum.rs +++ b/plutus-ledger-api/src/v2/datum.rs @@ -1,8 +1,6 @@ //! Types related to Plutus Datums -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, -}; -pub use crate::v1::datum::{Datum, DatumHash}; + +use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::{self, Error, Json}; use num_bigint::BigInt; @@ -10,6 +8,19 @@ use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +pub use crate::v1::datum::{Datum, DatumHash}; +use crate::{ + csl::{ + csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}, + pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}, + }, + plutus_data::{verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType}, +}; + +///////////////// +// OutputDatum // +///////////////// + /// Optional datum of a transaction /// /// In case an inline datum is used, the data is embedded inside the transaction body, so it can be @@ -125,3 +136,29 @@ impl Json for OutputDatum { ) } } + +impl TryFromCSL for OutputDatum { + fn try_from_csl(value: &csl::OutputDatum) -> Result { + Ok(if let Some(d) = value.data() { + OutputDatum::InlineDatum(Datum(d.try_to_pla()?)) + } else if let Some(h) = value.data_hash() { + OutputDatum::DatumHash(DatumHash::from_csl(&h)) + } else { + OutputDatum::None + }) + } +} + +impl TryFromPLA for Option { + fn try_from_pla( + pla_output_datum: &OutputDatum, + ) -> Result, TryFromPLAError> { + Ok(match pla_output_datum { + OutputDatum::None => None, + OutputDatum::InlineDatum(Datum(d)) => { + Some(csl::OutputDatum::new_data(&d.try_to_csl()?)) + } + OutputDatum::DatumHash(dh) => Some(csl::OutputDatum::new_data_hash(&dh.try_to_csl()?)), + }) + } +} diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index 6dc3d43..dea6a3e 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -1,4 +1,16 @@ //! Types related to Cardano transactions. + +use std::collections::BTreeMap; + +use cardano_serialization_lib as csl; +#[cfg(feature = "lbf")] +use lbr_prelude::json::Json; +use num_bigint::BigInt; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{parse_constr_with_tag, parse_fixed_len_constr_fields}; use crate::plutus_data::{ verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, @@ -8,15 +20,10 @@ pub use crate::v1::transaction::POSIXTimeConversionError; pub use crate::v1::transaction::{ DCert, POSIXTime, POSIXTimeRange, ScriptPurpose, TransactionHash, TransactionInput, }; -#[cfg(feature = "lbf")] -use lbr_prelude::json::Json; -use num_bigint::BigInt; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use super::address::AddressWithExtraInfo; use super::{ - address::{Address, StakingCredential}, + address::{Address, RewardAddressWithExtraInfo, StakingCredential}, assoc_map::AssocMap, crypto::PaymentPubKeyHash, datum::{Datum, DatumHash, OutputDatum}, @@ -25,6 +32,10 @@ use super::{ value::Value, }; +/////////////////////// +// TransactionOutput // +/////////////////////// + /// An output of a transaction /// /// This must include the target address, an optional datum, an optional reference script, and the @@ -78,6 +89,121 @@ impl IsPlutusData for TransactionOutput { } } +impl TryFromCSL for TransactionOutput { + fn try_from_csl(value: &csl::TransactionOutput) -> Result { + Ok(TransactionOutput { + address: value.address().try_to_pla()?, + datum: if value.has_data_hash() { + OutputDatum::DatumHash(DatumHash::from_csl(&value.data_hash().unwrap())) + } else if value.has_plutus_data() { + OutputDatum::InlineDatum(Datum(value.plutus_data().unwrap().try_to_pla()?)) + } else { + OutputDatum::None + }, + reference_script: if value.has_script_ref() { + let script_ref = value.script_ref().unwrap(); + let script_hash = if script_ref.is_native_script() { + script_ref.native_script().unwrap().hash() + } else { + script_ref.plutus_script().unwrap().hash() + }; + Some(ScriptHash::from_csl(&script_hash)) + } else { + None + }, + value: Value::from_csl(&value.amount()), + }) + } +} + +impl TryFromCSL for Vec { + fn try_from_csl(value: &csl::TransactionOutputs) -> Result { + (0..value.len()) + .map(|idx| TransactionOutput::try_from_csl(&value.get(idx))) + .collect() + } +} + +#[derive(Clone, Debug)] +pub struct TransactionOutputWithExtraInfo<'a> { + pub transaction_output: &'a TransactionOutput, + pub scripts: &'a BTreeMap, + pub network_id: u8, + pub data_cost: &'a csl::DataCost, +} + +impl TryFromPLA> for csl::TransactionOutput { + fn try_from_pla(val: &TransactionOutputWithExtraInfo<'_>) -> Result { + let mut output_builder = csl::output_builder::TransactionOutputBuilder::new().with_address( + &AddressWithExtraInfo { + address: &val.transaction_output.address, + network_tag: val.network_id, + } + .try_to_csl()?, + ); + + output_builder = match &val.transaction_output.datum { + OutputDatum::None => output_builder, + OutputDatum::InlineDatum(Datum(d)) => output_builder.with_plutus_data(&d.try_to_csl()?), + OutputDatum::DatumHash(dh) => output_builder.with_data_hash(&dh.try_to_csl()?), + }; + + let script_ref = val + .transaction_output + .reference_script + .clone() + .map(|script_hash| -> Result<_, TryFromPLAError> { + let script = val + .scripts + .get(&script_hash) + .ok_or(TryFromPLAError::MissingScript(script_hash))?; + Ok(csl::ScriptRef::new_plutus_script(script)) + }) + .transpose()?; + + if let Some(script_ref) = &script_ref { + output_builder = output_builder.with_script_ref(script_ref); + }; + + let value_without_min_utxo = val.transaction_output.value.try_to_csl()?; + + let mut calc = csl::utils::MinOutputAdaCalculator::new_empty(val.data_cost) + .map_err(TryFromPLAError::CSLJsError)?; + calc.set_amount(&value_without_min_utxo); + match &val.transaction_output.datum { + OutputDatum::None => {} + OutputDatum::InlineDatum(Datum(d)) => { + calc.set_plutus_data(&d.try_to_csl()?); + } + OutputDatum::DatumHash(dh) => { + calc.set_data_hash(&dh.try_to_csl()?); + } + }; + if let Some(script_ref) = script_ref { + calc.set_script_ref(&script_ref); + } + + let required_coin = calc.calculate_ada().map_err(TryFromPLAError::CSLJsError)?; + let coin = std::cmp::max(value_without_min_utxo.coin(), required_coin); + + let value = match value_without_min_utxo.multiasset() { + Some(multiasset) => csl::utils::Value::new_with_assets(&coin, &multiasset), + None => csl::utils::Value::new(&coin), + }; + + output_builder + .next() + .map_err(TryFromPLAError::CSLJsError)? + .with_value(&value) + .build() + .map_err(TryFromPLAError::CSLJsError) + } +} + +////////////// +// TxInInfo // +////////////// + /// An input of a pending transaction. #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -128,6 +254,10 @@ impl IsPlutusData for TxInInfo { } } +///////////////////// +// TransactionInfo // +///////////////////// + /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus #[derive(Debug, PartialEq, Eq, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -190,6 +320,35 @@ impl IsPlutusData for TransactionInfo { } } +#[derive(Clone, Debug)] +pub struct WithdrawalsWithExtraInfo<'a> { + withdrawals: &'a AssocMap, + network_tag: u8, +} + +impl TryFromPLA> for csl::Withdrawals { + fn try_from_pla(val: &WithdrawalsWithExtraInfo<'_>) -> Result { + val.withdrawals + .0 + .iter() + .try_fold(csl::Withdrawals::new(), |mut acc, (s, q)| { + acc.insert( + &RewardAddressWithExtraInfo { + staking_credential: s, + network_tag: val.network_tag, + } + .try_to_csl()?, + &q.try_to_csl()?, + ); + Ok(acc) + }) + } +} + +/////////////////// +// ScriptContext // +/////////////////// + /// The context that is presented to the currently-executing script. #[derive(Debug, PartialEq, Eq, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] From c60e631ff331e65d90ccc1a2e2d9fbfb5747b028 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Fri, 4 Oct 2024 12:24:21 +0200 Subject: [PATCH 06/38] Apply clippy suggestions --- .../src/generators/correct/primitive.rs | 2 +- plutus-ledger-api/src/plutus_data.rs | 44 +++++++++---------- plutus-ledger-api/src/v1/address.rs | 18 ++++---- plutus-ledger-api/src/v1/assoc_map.rs | 16 +++---- plutus-ledger-api/src/v1/interval.rs | 12 ++--- plutus-ledger-api/src/v1/transaction.rs | 14 +++--- plutus-ledger-api/src/v1/value.rs | 13 +++--- plutus-ledger-api/src/v2/datum.rs | 14 +++--- plutus-ledger-api/src/v2/transaction.rs | 4 +- 9 files changed, 65 insertions(+), 72 deletions(-) diff --git a/plutus-ledger-api/src/generators/correct/primitive.rs b/plutus-ledger-api/src/generators/correct/primitive.rs index 8260313..6e6e6c7 100644 --- a/plutus-ledger-api/src/generators/correct/primitive.rs +++ b/plutus-ledger-api/src/generators/correct/primitive.rs @@ -51,7 +51,7 @@ pub fn arb_natural(n: usize) -> impl Strategy { /// Helper function to generate a well typed arbitrary natural number /// Generating `n` vectors of random u32 values, which gives a max bound of u32::MAX ^ n fn arb_biguint(n: usize) -> impl Strategy { - vec(any::(), n).prop_map(|value| BigUint::new(value)) + vec(any::(), n).prop_map(BigUint::new) } /// Strategy to generate an arbitrary character diff --git a/plutus-ledger-api/src/plutus_data.rs b/plutus-ledger-api/src/plutus_data.rs index 0d624af..8be6ac2 100644 --- a/plutus-ledger-api/src/plutus_data.rs +++ b/plutus-ledger-api/src/plutus_data.rs @@ -175,10 +175,10 @@ pub fn case_plutus_data<'a, T>( pd: &'a PlutusData, ) -> T { match pd { - PlutusData::Constr(tag, args) => ctor_case(&tag)(&args), - PlutusData::List(args) => list_case(&args), - PlutusData::Integer(i) => int_case(&i), - other => other_case(&other), + PlutusData::Constr(tag, args) => ctor_case(tag)(args), + PlutusData::List(args) => list_case(args), + PlutusData::Integer(i) => int_case(i), + other => other_case(other), } } @@ -252,11 +252,11 @@ impl IsPlutusData for bool { match plutus_data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(false) } Ok(1) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(true) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { @@ -346,11 +346,11 @@ where match plutus_data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Some(T::from_plutus_data(&fields[0])?)) } Ok(1) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(None) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { @@ -383,11 +383,11 @@ where match plutus_data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Err(E::from_plutus_data(&fields[0])?)) } Ok(1) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Ok(T::from_plutus_data(&fields[0])?)) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { @@ -447,7 +447,7 @@ where fn from_plutus_data(plutus_data: &PlutusData) -> Result { match plutus_data { PlutusData::List(vec) => vec - .into_iter() + .iter() .map(|val| T::from_plutus_data(val)) .collect::>(), _ => Err(PlutusDataError::UnexpectedPlutusType { @@ -475,7 +475,7 @@ where fn from_plutus_data(plutus_data: &PlutusData) -> Result { match plutus_data { PlutusData::Map(dict) => dict - .into_iter() + .iter() .map(|(key, val)| Ok((K::from_plutus_data(key)?, V::from_plutus_data(val)?))) .collect::>(), _ => Err(PlutusDataError::UnexpectedPlutusType { @@ -495,7 +495,7 @@ impl IsPlutusData for () { match plutus_data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(()) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { @@ -538,7 +538,7 @@ where match plutus_data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(( A::from_plutus_data(&fields[0])?, B::from_plutus_data(&fields[1])?, @@ -653,9 +653,9 @@ pub fn verify_constr_fields( /// Given a vector of PlutusData, parse it as an array whose length is known at /// compile time. -pub fn parse_fixed_len_constr_fields<'a, const LEN: usize>( - v: &'a [PlutusData], -) -> Result<&'a [PlutusData; LEN], PlutusDataError> { +pub fn parse_fixed_len_constr_fields( + v: &[PlutusData], +) -> Result<&[PlutusData; LEN], PlutusDataError> { v.try_into() .map_err(|_| PlutusDataError::UnexpectedListLength { got: v.len(), @@ -665,9 +665,7 @@ pub fn parse_fixed_len_constr_fields<'a, const LEN: usize>( /// Given a PlutusData, parse it as PlutusData::Constr and its tag as u32. Return /// the u32 tag and fields. -pub fn parse_constr<'a>( - data: &'a PlutusData, -) -> Result<(u32, &'a Vec), PlutusDataError> { +pub fn parse_constr(data: &PlutusData) -> Result<(u32, &Vec), PlutusDataError> { match data { PlutusData::Constr(tag, fields) => u32::try_from(tag) .map_err(|err| PlutusDataError::UnexpectedPlutusInvariant { @@ -683,10 +681,10 @@ pub fn parse_constr<'a>( } /// Given a PlutusData, parse it as PlutusData::Constr and verify its tag. -pub fn parse_constr_with_tag<'a>( - data: &'a PlutusData, +pub fn parse_constr_with_tag( + data: &PlutusData, expected_tag: u32, -) -> Result<&'a Vec, PlutusDataError> { +) -> Result<&Vec, PlutusDataError> { let (tag, fields) = parse_constr(data)?; if tag != expected_tag { diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index 7f2c0c6..c25254e 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -186,13 +186,13 @@ impl IsPlutusData for Credential { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Credential::PubKey(Ed25519PubKeyHash::from_plutus_data( &fields[0], )?)) } Ok(1) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Credential::Script(ValidatorHash::from_plutus_data( &fields[0], )?)) @@ -216,10 +216,10 @@ impl Json for Credential { fn to_json(&self) -> serde_json::Value { match self { Credential::PubKey(pkh) => { - json::json_constructor("PubKeyCredential", &vec![pkh.to_json()]) + json::json_constructor("PubKeyCredential", vec![pkh.to_json()]) } Credential::Script(val_hash) => { - json::json_constructor("ScriptCredential", &vec![val_hash.to_json()]) + json::json_constructor("ScriptCredential", vec![val_hash.to_json()]) } } } @@ -319,13 +319,13 @@ impl IsPlutusData for StakingCredential { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(StakingCredential::Hash(Credential::from_plutus_data( &fields[0], )?)) } Ok(1) => { - verify_constr_fields(&fields, 3)?; + verify_constr_fields(fields, 3)?; Ok(StakingCredential::Pointer(ChainPointer { slot_number: Slot::from_plutus_data(&fields[0])?, transaction_index: TransactionIndex::from_plutus_data(&fields[1])?, @@ -351,10 +351,10 @@ impl Json for StakingCredential { fn to_json(&self) -> serde_json::Value { match self { StakingCredential::Hash(pkh) => { - json::json_constructor("StakingHash", &vec![pkh.to_json()]) + json::json_constructor("StakingHash", vec![pkh.to_json()]) } StakingCredential::Pointer(val_hash) => { - json::json_constructor("StakingPtr", &vec![val_hash.to_json()]) + json::json_constructor("StakingPtr", vec![val_hash.to_json()]) } } } @@ -377,7 +377,7 @@ impl Json for StakingCredential { ( "StakingPtr", Box::new(|ctor_fields| match &ctor_fields[..] { - [val_hash] => Ok(StakingCredential::Pointer(Json::from_json(&val_hash)?)), + [val_hash] => Ok(StakingCredential::Pointer(Json::from_json(val_hash)?)), _ => Err(Error::UnexpectedArrayLength { wanted: 1, got: ctor_fields.len(), diff --git a/plutus-ledger-api/src/v1/assoc_map.rs b/plutus-ledger-api/src/v1/assoc_map.rs index 54fed54..15760dd 100644 --- a/plutus-ledger-api/src/v1/assoc_map.rs +++ b/plutus-ledger-api/src/v1/assoc_map.rs @@ -12,7 +12,7 @@ use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}; // AssocMap // ////////////// -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct AssocMap(pub Vec<(K, V)>); @@ -30,9 +30,7 @@ impl AssocMap { where K: PartialEq, { - let vec = &mut self.0; - - let old_value = vec.into_iter().find(|(k, _v)| k == &key); + let old_value = self.0.iter_mut().find(|(k, _v)| k == &key); match old_value { None => { self.0.push((key, value)); @@ -72,8 +70,8 @@ impl AssocMap { impl IsPlutusData for AssocMap { fn to_plutus_data(&self) -> PlutusData { PlutusData::Map( - (&self.0) - .into_iter() + self.0 + .iter() .map(|(k, v)| (k.to_plutus_data(), v.to_plutus_data())) .collect(), ) @@ -82,7 +80,7 @@ impl IsPlutusData for AssocMap { fn from_plutus_data(plutus_data: &PlutusData) -> Result { match plutus_data { PlutusData::Map(pairs) => pairs - .into_iter() + .iter() .map(|(k, v)| Ok((K::from_plutus_data(k)?, V::from_plutus_data(v)?))) .collect::, PlutusDataError>>() .map(Self), @@ -128,8 +126,8 @@ impl From> for AssocMap { impl Json for AssocMap { fn to_json(&self) -> serde_json::Value { json_array( - (&self.0) - .into_iter() + self.0 + .iter() .map(|(k, v)| json_array(vec![k.to_json(), v.to_json()])) .collect(), ) diff --git a/plutus-ledger-api/src/v1/interval.rs b/plutus-ledger-api/src/v1/interval.rs index 313e7e5..399e64a 100644 --- a/plutus-ledger-api/src/v1/interval.rs +++ b/plutus-ledger-api/src/v1/interval.rs @@ -271,7 +271,7 @@ where match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(PlutusInterval { from: >::from_plutus_data(&fields[0])?, to: >::from_plutus_data(&fields[1])?, @@ -321,7 +321,7 @@ where match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(UpperBound { bound: >::from_plutus_data(&fields[0])?, closed: bool::from_plutus_data(&fields[1])?, @@ -371,7 +371,7 @@ where match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(LowerBound { bound: >::from_plutus_data(&fields[0])?, closed: bool::from_plutus_data(&fields[1])?, @@ -468,17 +468,17 @@ where match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(Extended::NegInf) } Ok(1) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(Extended::Finite(IsPlutusData::from_plutus_data( &fields[0], )?)) } Ok(2) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(Extended::PosInf) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 65069e1..ef2506c 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -65,7 +65,7 @@ impl IsPlutusData for TransactionInput { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(TransactionInput { transaction_id: TransactionHash::from_plutus_data(&fields[0])?, index: BigInt::from_plutus_data(&fields[1])?, @@ -149,7 +149,7 @@ impl IsPlutusData for TransactionHash { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(TransactionHash(IsPlutusData::from_plutus_data(&fields[0])?)) } _ => Err(PlutusDataError::UnexpectedPlutusInvariant { @@ -212,7 +212,7 @@ impl IsPlutusData for TransactionOutput { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 3)?; + verify_constr_fields(fields, 3)?; Ok(TransactionOutput { address: Address::from_plutus_data(&fields[0])?, value: Value::from_plutus_data(&fields[1])?, @@ -275,10 +275,10 @@ impl TryFrom for chrono::DateTime { fn try_from(posix_time: POSIXTime) -> Result, Self::Error> { let POSIXTime(millis) = posix_time; - Ok(chrono::DateTime::from_timestamp_millis( + chrono::DateTime::from_timestamp_millis( ::try_from(millis).map_err(POSIXTimeConversionError::TryFromBigIntError)?, ) - .ok_or(POSIXTimeConversionError::OutOfBoundsError)?) + .ok_or(POSIXTimeConversionError::OutOfBoundsError) } } @@ -316,7 +316,7 @@ impl IsPlutusData for TxInInfo { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(TxInInfo { reference: TransactionInput::from_plutus_data(&fields[0])?, output: TransactionOutput::from_plutus_data(&fields[1])?, @@ -479,7 +479,7 @@ impl IsPlutusData for ScriptPurpose { 3 => IsPlutusData::from_plutus_data(field).map(Self::Certifying), bad_tag => Err(PlutusDataError::UnexpectedPlutusInvariant { got: bad_tag.to_string(), - wanted: format!("Constr tag to be 0, 1, 2 or 3"), + wanted: "Constr tag to be 0, 1, 2 or 3".to_string(), }), } } diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 238b6d8..e007ef9 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -160,7 +160,7 @@ mod value_serde { } } - impl<'de, 'a> Deserialize<'de> for Assets { + impl<'de> Deserialize<'de> for Assets { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -391,15 +391,12 @@ impl Mul<&BigInt> for &Value { fn mul(self, rhs: &BigInt) -> Self::Output { Value( - (&self.0) - .into_iter() + self.0 + .iter() .map(|(cs, tn_map)| { ( cs.clone(), - tn_map - .into_iter() - .map(|(tn, q)| (tn.clone(), q * rhs)) - .collect(), + tn_map.iter().map(|(tn, q)| (tn.clone(), q * rhs)).collect(), ) }) .collect(), @@ -678,7 +675,7 @@ impl IsPlutusData for AssetClass { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(AssetClass { currency_symbol: CurrencySymbol::from_plutus_data(&fields[0])?, token_name: TokenName::from_plutus_data(&fields[1])?, diff --git a/plutus-ledger-api/src/v2/datum.rs b/plutus-ledger-api/src/v2/datum.rs index 8b375d1..a870811 100644 --- a/plutus-ledger-api/src/v2/datum.rs +++ b/plutus-ledger-api/src/v2/datum.rs @@ -51,17 +51,17 @@ impl IsPlutusData for OutputDatum { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 0)?; + verify_constr_fields(fields, 0)?; Ok(OutputDatum::None) } Ok(1) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(OutputDatum::DatumHash(DatumHash::from_plutus_data( &fields[0], )?)) } Ok(2) => { - verify_constr_fields(&fields, 1)?; + verify_constr_fields(fields, 1)?; Ok(OutputDatum::InlineDatum(Datum::from_plutus_data( &fields[0], )?)) @@ -84,12 +84,12 @@ impl IsPlutusData for OutputDatum { impl Json for OutputDatum { fn to_json(&self) -> serde_json::Value { match self { - OutputDatum::None => json::json_constructor("NoOutputDatum", &Vec::with_capacity(0)), + OutputDatum::None => json::json_constructor("NoOutputDatum", Vec::with_capacity(0)), OutputDatum::DatumHash(dat_hash) => { - json::json_constructor("OutputDatumHash", &vec![dat_hash.to_json()]) + json::json_constructor("OutputDatumHash", vec![dat_hash.to_json()]) } OutputDatum::InlineDatum(datum) => { - json::json_constructor("OutputDatum", &vec![datum.to_json()]) + json::json_constructor("OutputDatum", vec![datum.to_json()]) } } } @@ -112,7 +112,7 @@ impl Json for OutputDatum { ( "OutputDatumHash", Box::new(|ctor_fields| match &ctor_fields[..] { - [dat_hash] => Ok(OutputDatum::DatumHash(Json::from_json(&dat_hash)?)), + [dat_hash] => Ok(OutputDatum::DatumHash(Json::from_json(dat_hash)?)), _ => Err(Error::UnexpectedArrayLength { wanted: 1, got: ctor_fields.len(), diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index dea6a3e..096f0a6 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -67,7 +67,7 @@ impl IsPlutusData for TransactionOutput { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 4)?; + verify_constr_fields(fields, 4)?; Ok(TransactionOutput { address: Address::from_plutus_data(&fields[0])?, value: Value::from_plutus_data(&fields[1])?, @@ -234,7 +234,7 @@ impl IsPlutusData for TxInInfo { match data { PlutusData::Constr(flag, fields) => match u32::try_from(flag) { Ok(0) => { - verify_constr_fields(&fields, 2)?; + verify_constr_fields(fields, 2)?; Ok(TxInInfo { reference: TransactionInput::from_plutus_data(&fields[0])?, output: TransactionOutput::from_plutus_data(&fields[1])?, From 7864eb2bddfb07383b55d33bc700e523fe472f40 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Fri, 4 Oct 2024 12:46:42 +0200 Subject: [PATCH 07/38] Update csl --- plutus-ledger-api/Cargo.lock | 367 ++++++++++++++++-------- plutus-ledger-api/Cargo.toml | 2 +- plutus-ledger-api/src/csl/csl_to_pla.rs | 24 +- plutus-ledger-api/src/csl/pla_to_csl.rs | 24 +- plutus-ledger-api/src/plutus_data.rs | 75 ++--- plutus-ledger-api/src/v1/address.rs | 81 +++--- plutus-ledger-api/src/v1/crypto.rs | 8 +- plutus-ledger-api/src/v1/datum.rs | 11 +- plutus-ledger-api/src/v1/redeemer.rs | 18 +- plutus-ledger-api/src/v1/script.rs | 12 +- plutus-ledger-api/src/v1/transaction.rs | 8 +- plutus-ledger-api/src/v1/value.rs | 17 +- plutus-ledger-api/src/v2/transaction.rs | 14 +- 13 files changed, 395 insertions(+), 266 deletions(-) diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index f0147b8..30548b3 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -19,15 +31,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bech32" @@ -58,9 +70,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -77,11 +89,17 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cardano-serialization-lib" -version = "11.5.0" +version = "12.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3fab2c10aa73dae6ea90ed459ef07ed7acb09270ea90d9a37fa00420b9c25c" +checksum = "abfd14f5a2250d86a3c673a70c49851c21207ee8537f9f11b3dba9cc67095ef7" dependencies = [ "bech32", "cbor_event", @@ -91,13 +109,16 @@ dependencies = [ "digest", "ed25519-bip32", "getrandom", + "hashlink", "hex", "itertools", "js-sys", - "linked-hash-map", "noop_proc_macro", + "num", "num-bigint", + "num-derive", "num-integer", + "num-traits", "rand", "rand_os", "schemars", @@ -116,9 +137,12 @@ checksum = "089a0261d1bc59e54e8e11860031efd88593f0e61b921172c474f1f38c2f2d3c" [[package]] name = "cc" -version = "1.0.99" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -160,9 +184,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" @@ -240,14 +264,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fnv" @@ -302,7 +326,7 @@ dependencies = [ "serde", "serde_json", "upon", - "yansi 1.0.1", + "yansi", ] [[package]] @@ -310,6 +334,24 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] [[package]] name = "hex" @@ -348,12 +390,12 @@ checksum = "90f97a5f38dd3ccfbe7aa80f4a0c00930f21b922c74195be0201c51028f22dcf" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", ] [[package]] @@ -382,15 +424,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lbr-prelude" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2367a6b351bdc4e6df1989e5d2a276e8ae8e54d15dcbff6dfd21b5ff45096b" +checksum = "21471892874c4667636a067ed7a158b9691178988a4c5988585e1010e9b5817d" dependencies = [ "data-encoding", "lbr-prelude-derive", @@ -415,9 +457,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libm" @@ -439,9 +481,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" @@ -455,17 +497,51 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", "serde", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -475,6 +551,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -487,9 +585,12 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -518,20 +619,29 @@ dependencies = [ "true", ] +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", - "yansi 0.5.1", + "yansi", ] [[package]] @@ -545,13 +655,13 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.5.0", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", @@ -571,9 +681,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -658,21 +768,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -719,9 +829,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -739,9 +849,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -773,9 +883,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -793,11 +903,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "syn" -version = "2.0.67" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -806,14 +922,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -827,18 +944,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -847,9 +964,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -859,18 +976,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -887,9 +1004,9 @@ checksum = "548ec159e98411c04bee9b458df4ccd2da2a0a5e50c08cbd7e90b00b154c5a9a" [[package]] name = "trybuild" -version = "1.0.96" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3" +checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" dependencies = [ "dissimilar", "glob", @@ -914,15 +1031,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "upon" @@ -958,9 +1075,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -968,9 +1085,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -983,9 +1100,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -993,9 +1110,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -1006,9 +1123,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "winapi" @@ -1028,11 +1145,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1059,11 +1176,20 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1077,69 +1203,84 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] -name = "yansi" -version = "1.0.1" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index cf58f3a..2d1903c 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -21,7 +21,7 @@ linked-hash-map = "~0.5.6" num-traits = "~0.2.17" impl_ops = "0.1.1" chrono = { version = "0.4.34", optional = true } -cardano-serialization-lib = "11.5.0" +cardano-serialization-lib = "12.1.0" anyhow = "1.0.86" [features] diff --git a/plutus-ledger-api/src/csl/csl_to_pla.rs b/plutus-ledger-api/src/csl/csl_to_pla.rs index a87bee5..6641090 100644 --- a/plutus-ledger-api/src/csl/csl_to_pla.rs +++ b/plutus-ledger-api/src/csl/csl_to_pla.rs @@ -52,8 +52,8 @@ where } } -impl FromCSL for BigInt { - fn from_csl(value: &csl::utils::BigNum) -> Self { +impl FromCSL for BigInt { + fn from_csl(value: &csl::BigNum) -> Self { let x: u64 = From::from(*value); BigInt::from(x) } @@ -65,14 +65,14 @@ impl FromCSL for BigInt { } } -impl TryFromCSL for BigInt { - fn try_from_csl(value: &csl::utils::BigInt) -> Result { +impl TryFromCSL for BigInt { + fn try_from_csl(value: &csl::BigInt) -> Result { BigInt::from_str(&value.to_str()).map_err(TryFromCSLError::InvalidBigInt) } } -impl FromCSL for BigInt { - fn from_csl(value: &csl::utils::Int) -> Self { +impl FromCSL for BigInt { + fn from_csl(value: &csl::Int) -> Self { if value.is_positive() { BigInt::from_csl(&value.as_positive().unwrap()) } else { @@ -80,15 +80,3 @@ impl FromCSL for BigInt { } } } - -impl FromCSL for Vec { - fn from_csl(value: &csl::NativeScripts) -> Self { - (0..value.len()).map(|idx| value.get(idx)).collect() - } -} - -impl FromCSL for Vec { - fn from_csl(value: &csl::plutus::PlutusScripts) -> Self { - (0..value.len()).map(|idx| value.get(idx)).collect() - } -} diff --git a/plutus-ledger-api/src/csl/pla_to_csl.rs b/plutus-ledger-api/src/csl/pla_to_csl.rs index 31c1a82..1742f60 100644 --- a/plutus-ledger-api/src/csl/pla_to_csl.rs +++ b/plutus-ledger-api/src/csl/pla_to_csl.rs @@ -5,10 +5,10 @@ use num_traits::sign::Signed; #[derive(Debug, thiserror::Error)] pub enum TryFromPLAError { #[error("{0}")] - CSLDeserializeError(csl::error::DeserializeError), + CSLDeserializeError(csl::DeserializeError), #[error("{0}")] - CSLJsError(csl::error::JsError), + CSLJsError(csl::JsError), #[error("Unable to cast BigInt {0} into type {1}: value is out of bound")] BigIntOutOfRange(BigInt, String), @@ -48,15 +48,15 @@ where } } -impl TryFromPLA for csl::utils::BigNum { +impl TryFromPLA for csl::BigNum { fn try_from_pla(val: &u64) -> Result { // BigNum(s) are u64 under the hood. - Ok(csl::utils::BigNum::from(*val)) + Ok(csl::BigNum::from(*val)) } } -impl TryFromPLA for csl::utils::BigNum { +impl TryFromPLA for csl::BigNum { fn try_from_pla(val: &BigInt) -> Result { // BigNum(s) are u64 under the hood. let x: u64 = val @@ -70,30 +70,30 @@ impl TryFromPLA for csl::utils::BigNum { } } -impl TryFromPLA for csl::utils::BigInt { +impl TryFromPLA for csl::BigInt { fn try_from_pla(val: &BigInt) -> Result { Ok(val.to_owned().into()) } } -impl TryFromPLA for csl::utils::Int { +impl TryFromPLA for csl::Int { fn try_from_pla(val: &BigInt) -> Result { if val.is_negative() { - Ok(csl::utils::Int::new_negative(&(val.abs()).try_to_csl()?)) + Ok(csl::Int::new_negative(&(val.abs()).try_to_csl()?)) } else { - Ok(csl::utils::Int::new(&val.try_to_csl()?)) + Ok(csl::Int::new(&val.try_to_csl()?)) } } } -impl TryFromPLA for csl::utils::Int { +impl TryFromPLA for csl::Int { fn try_from_pla(val: &i64) -> Result { if val.is_negative() { - Ok(csl::utils::Int::new_negative(&csl::utils::to_bignum( + Ok(csl::Int::new_negative(&csl::BigNum::from( val.unsigned_abs(), ))) } else { - Ok(csl::utils::Int::new(&csl::utils::to_bignum(*val as u64))) + Ok(csl::Int::new(&csl::BigNum::from(*val as u64))) } } } diff --git a/plutus-ledger-api/src/plutus_data.rs b/plutus-ledger-api/src/plutus_data.rs index 8be6ac2..8329704 100644 --- a/plutus-ledger-api/src/plutus_data.rs +++ b/plutus-ledger-api/src/plutus_data.rs @@ -558,79 +558,86 @@ where } } -impl TryFromCSL for PlutusData { - fn try_from_csl(value: &csl::plutus::PlutusData) -> Result { +impl TryFromCSL for PlutusData { + fn try_from_csl(value: &csl::PlutusData) -> Result { Ok(match value.kind() { - csl::plutus::PlutusDataKind::ConstrPlutusData => { + csl::PlutusDataKind::ConstrPlutusData => { let constr_data = value.as_constr_plutus_data().unwrap(); let tag = BigInt::from_csl(&constr_data.alternative()); let args = constr_data.data().try_to_pla()?; PlutusData::Constr(tag, args) } - csl::plutus::PlutusDataKind::Map => { - PlutusData::Map(value.as_map().unwrap().try_to_pla()?) - } - csl::plutus::PlutusDataKind::List => { - PlutusData::List(value.as_list().unwrap().try_to_pla()?) - } - csl::plutus::PlutusDataKind::Integer => { + csl::PlutusDataKind::Map => PlutusData::Map(value.as_map().unwrap().try_to_pla()?), + csl::PlutusDataKind::List => PlutusData::List(value.as_list().unwrap().try_to_pla()?), + csl::PlutusDataKind::Integer => { PlutusData::Integer(value.as_integer().unwrap().try_to_pla()?) } - csl::plutus::PlutusDataKind::Bytes => PlutusData::Bytes(value.as_bytes().unwrap()), + csl::PlutusDataKind::Bytes => PlutusData::Bytes(value.as_bytes().unwrap()), }) } } -impl TryFromCSL for Vec { - fn try_from_csl(value: &csl::plutus::PlutusList) -> Result { +impl TryFromCSL for Vec { + fn try_from_csl(value: &csl::PlutusList) -> Result { (0..value.len()) .map(|idx| value.get(idx).try_to_pla()) .collect() } } -impl TryFromCSL for Vec<(PlutusData, PlutusData)> { - fn try_from_csl(c_map: &csl::plutus::PlutusMap) -> Result { +impl TryFromCSL for Vec<(PlutusData, PlutusData)> { + fn try_from_csl(c_map: &csl::PlutusMap) -> Result { let keys = c_map.keys(); - (0..keys.len()) - .map(|idx| { - let key = keys.get(idx); - let value = c_map.get(&key).unwrap(); - Ok((key.try_to_pla()?, value.try_to_pla()?)) - }) - .collect() + (0..keys.len()).try_fold(Vec::new(), |mut vector, idx| { + let key = keys.get(idx); + let values = c_map.get(&key).unwrap(); + + for value_idx in 0..values.len() { + vector.push(( + key.clone().try_to_pla()?, + values.get(value_idx).unwrap().try_to_pla()?, + )) + } + + Ok(vector) + }) } } -impl TryFromPLA for csl::plutus::PlutusData { +impl TryFromPLA for csl::PlutusData { fn try_from_pla(val: &PlutusData) -> Result { match val { - PlutusData::Constr(tag, args) => Ok(csl::plutus::PlutusData::new_constr_plutus_data( - &csl::plutus::ConstrPlutusData::new(&tag.try_to_csl()?, &args.try_to_csl()?), + PlutusData::Constr(tag, args) => Ok(csl::PlutusData::new_constr_plutus_data( + &csl::ConstrPlutusData::new(&tag.try_to_csl()?, &args.try_to_csl()?), )), - PlutusData::Map(l) => Ok(csl::plutus::PlutusData::new_map(&l.try_to_csl()?)), - PlutusData::List(l) => Ok(csl::plutus::PlutusData::new_list(&l.try_to_csl()?)), - PlutusData::Integer(i) => Ok(csl::plutus::PlutusData::new_integer(&i.try_to_csl()?)), - PlutusData::Bytes(b) => Ok(csl::plutus::PlutusData::new_bytes(b.to_owned())), + PlutusData::Map(l) => Ok(csl::PlutusData::new_map(&l.try_to_csl()?)), + PlutusData::List(l) => Ok(csl::PlutusData::new_list(&l.try_to_csl()?)), + PlutusData::Integer(i) => Ok(csl::PlutusData::new_integer(&i.try_to_csl()?)), + PlutusData::Bytes(b) => Ok(csl::PlutusData::new_bytes(b.to_owned())), } } } -impl TryFromPLA> for csl::plutus::PlutusList { +impl TryFromPLA> for csl::PlutusList { fn try_from_pla(val: &Vec) -> Result { val.iter() // traverse .map(|x| x.try_to_csl()) - .collect::, TryFromPLAError>>() + .collect::, TryFromPLAError>>() .map(|x| x.into()) } } -impl TryFromPLA> for csl::plutus::PlutusMap { +impl TryFromPLA> for csl::PlutusMap { fn try_from_pla(val: &Vec<(PlutusData, PlutusData)>) -> Result { val.iter() - .try_fold(csl::plutus::PlutusMap::new(), |mut acc, (k, v)| { - acc.insert(&k.try_to_csl()?, &v.try_to_csl()?); + .try_fold(csl::PlutusMap::new(), |mut acc, (k, v)| { + let mut values = match acc.get(&k.try_to_csl()?) { + Some(existing_values) => existing_values, + None => csl::PlutusMapValues::new(), + }; + values.add(&v.try_to_csl()?); + acc.insert(&k.try_to_csl()?, &values); Ok(acc) }) } diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index c25254e..b80677f 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -85,7 +85,7 @@ impl FromStr for Address { type Err = anyhow::Error; fn from_str(s: &str) -> std::result::Result { - let csl_addr = csl::address::Address::from_bech32(s) + let csl_addr = csl::Address::from_bech32(s) .map_err(|err| anyhow!("Couldn't parse bech32 address: {}", err))?; csl_addr .try_to_pla() @@ -93,19 +93,19 @@ impl FromStr for Address { } } -impl TryFromCSL for Address { - fn try_from_csl(value: &csl::address::Address) -> Result { - if let Some(addr) = csl::address::BaseAddress::from_address(value) { +impl TryFromCSL for Address { + fn try_from_csl(value: &csl::Address) -> Result { + if let Some(addr) = csl::BaseAddress::from_address(value) { Ok(Address { credential: Credential::from_csl(&addr.payment_cred()), staking_credential: Some(StakingCredential::from_csl(&addr.stake_cred())), }) - } else if let Some(addr) = csl::address::PointerAddress::from_address(value) { + } else if let Some(addr) = csl::PointerAddress::from_address(value) { Ok(Address { credential: Credential::from_csl(&addr.payment_cred()), staking_credential: Some(StakingCredential::from_csl(&addr.stake_pointer())), }) - } else if let Some(addr) = csl::address::EnterpriseAddress::from_address(value) { + } else if let Some(addr) = csl::EnterpriseAddress::from_address(value) { Ok(Address { credential: Credential::from_csl(&addr.payment_cred()), staking_credential: None, @@ -125,19 +125,18 @@ pub struct AddressWithExtraInfo<'a> { pub network_tag: u8, } -impl TryFromPLA> for csl::address::Address { +impl TryFromPLA> for csl::Address { fn try_from_pla(val: &AddressWithExtraInfo<'_>) -> Result { let payment = val.address.credential.try_to_csl()?; Ok(match val.address.staking_credential { - None => csl::address::EnterpriseAddress::new(val.network_tag, &payment).to_address(), + None => csl::EnterpriseAddress::new(val.network_tag, &payment).to_address(), Some(ref sc) => match sc { StakingCredential::Hash(c) => { - csl::address::BaseAddress::new(val.network_tag, &payment, &c.try_to_csl()?) - .to_address() + csl::BaseAddress::new(val.network_tag, &payment, &c.try_to_csl()?).to_address() } StakingCredential::Pointer(ptr) => { - csl::address::PointerAddress::new(val.network_tag, &payment, &ptr.try_to_csl()?) + csl::PointerAddress::new(val.network_tag, &payment, &ptr.try_to_csl()?) .to_address() } }, @@ -150,7 +149,7 @@ impl std::fmt::Display for AddressWithExtraInfo<'_> { let bech32_addr: Option = self .try_to_csl() .ok() - .and_then(|csl_addr: csl::address::Address| csl_addr.to_bech32(None).ok()); + .and_then(|csl_addr: csl::Address| csl_addr.to_bech32(None).ok()); match bech32_addr { Some(addr) => write!(f, "{}", addr), None => write!(f, "INVALID ADDRESS {:?}", self), @@ -256,28 +255,24 @@ impl Json for Credential { } } -impl FromCSL for Credential { - fn from_csl(value: &csl::address::StakeCredential) -> Self { +impl FromCSL for Credential { + fn from_csl(value: &csl::Credential) -> Self { match value.kind() { - csl::address::StakeCredKind::Key => { + csl::CredKind::Key => { Credential::PubKey(Ed25519PubKeyHash::from_csl(&value.to_keyhash().unwrap())) } - csl::address::StakeCredKind::Script => { + csl::CredKind::Script => { Credential::Script(ValidatorHash::from_csl(&value.to_scripthash().unwrap())) } } } } -impl TryFromPLA for csl::address::StakeCredential { +impl TryFromPLA for csl::Credential { fn try_from_pla(val: &Credential) -> Result { match val { - Credential::PubKey(pkh) => Ok(csl::address::StakeCredential::from_keyhash( - &pkh.try_to_csl()?, - )), - Credential::Script(sh) => Ok(csl::address::StakeCredential::from_scripthash( - &sh.0.try_to_csl()?, - )), + Credential::PubKey(pkh) => Ok(csl::Credential::from_keyhash(&pkh.try_to_csl()?)), + Credential::Script(sh) => Ok(csl::Credential::from_scripthash(&sh.0.try_to_csl()?)), } } } @@ -391,13 +386,13 @@ impl Json for StakingCredential { } } -impl FromCSL for StakingCredential { - fn from_csl(value: &csl::address::StakeCredential) -> Self { +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::Credential) -> Self { StakingCredential::Hash(Credential::from_csl(value)) } } -impl TryFromPLA for csl::address::StakeCredential { +impl TryFromPLA for csl::Credential { fn try_from_pla(val: &StakingCredential) -> Result { match val { StakingCredential::Hash(c) => c.try_to_csl(), @@ -408,8 +403,8 @@ impl TryFromPLA for csl::address::StakeCredential { } } -impl FromCSL for StakingCredential { - fn from_csl(value: &csl::address::Pointer) -> Self { +impl FromCSL for StakingCredential { + fn from_csl(value: &csl::Pointer) -> Self { StakingCredential::Pointer(ChainPointer::from_csl(value)) } } @@ -420,9 +415,9 @@ pub struct RewardAddressWithExtraInfo<'a> { pub network_tag: u8, } -impl TryFromPLA> for csl::address::RewardAddress { +impl TryFromPLA> for csl::RewardAddress { fn try_from_pla(val: &RewardAddressWithExtraInfo<'_>) -> Result { - Ok(csl::address::RewardAddress::new( + Ok(csl::RewardAddress::new( val.network_tag, &val.staking_credential.try_to_csl()?, )) @@ -447,8 +442,8 @@ pub struct ChainPointer { pub certificate_index: CertificateIndex, } -impl FromCSL for ChainPointer { - fn from_csl(value: &csl::address::Pointer) -> Self { +impl FromCSL for ChainPointer { + fn from_csl(value: &csl::Pointer) -> Self { ChainPointer { slot_number: Slot::from_csl(&value.slot_bignum()), transaction_index: TransactionIndex::from_csl(&value.tx_index_bignum()), @@ -457,9 +452,9 @@ impl FromCSL for ChainPointer { } } -impl TryFromPLA for csl::address::Pointer { +impl TryFromPLA for csl::Pointer { fn try_from_pla(val: &ChainPointer) -> Result { - Ok(csl::address::Pointer::new_pointer( + Ok(csl::Pointer::new_pointer( &val.slot_number.try_to_csl()?, &val.transaction_index.try_to_csl()?, &val.certificate_index.try_to_csl()?, @@ -487,13 +482,13 @@ impl IsPlutusData for Slot { } } -impl FromCSL for Slot { - fn from_csl(value: &csl::utils::BigNum) -> Self { +impl FromCSL for Slot { + fn from_csl(value: &csl::BigNum) -> Self { Slot(BigInt::from_csl(value)) } } -impl TryFromPLA for csl::utils::BigNum { +impl TryFromPLA for csl::BigNum { fn try_from_pla(val: &Slot) -> Result { val.0.try_to_csl() } @@ -519,13 +514,13 @@ impl IsPlutusData for CertificateIndex { } } -impl FromCSL for CertificateIndex { - fn from_csl(value: &csl::utils::BigNum) -> Self { +impl FromCSL for CertificateIndex { + fn from_csl(value: &csl::BigNum) -> Self { CertificateIndex(BigInt::from_csl(value)) } } -impl TryFromPLA for csl::utils::BigNum { +impl TryFromPLA for csl::BigNum { fn try_from_pla(val: &CertificateIndex) -> Result { val.0.try_to_csl() } @@ -552,13 +547,13 @@ impl IsPlutusData for TransactionIndex { } } -impl FromCSL for TransactionIndex { - fn from_csl(value: &csl::utils::BigNum) -> Self { +impl FromCSL for TransactionIndex { + fn from_csl(value: &csl::BigNum) -> Self { TransactionIndex(BigInt::from_csl(value)) } } -impl TryFromPLA for csl::utils::BigNum { +impl TryFromPLA for csl::BigNum { fn try_from_pla(val: &TransactionIndex) -> Result { val.0.try_to_csl() } diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index 5cb8376..4517dd6 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -43,15 +43,15 @@ impl IsPlutusData for Ed25519PubKeyHash { } } -impl FromCSL for Ed25519PubKeyHash { - fn from_csl(value: &csl::crypto::Ed25519KeyHash) -> Self { +impl FromCSL for Ed25519PubKeyHash { + fn from_csl(value: &csl::Ed25519KeyHash) -> Self { Ed25519PubKeyHash(LedgerBytes(value.to_bytes())) } } -impl TryFromPLA for csl::crypto::Ed25519KeyHash { +impl TryFromPLA for csl::Ed25519KeyHash { fn try_from_pla(val: &Ed25519PubKeyHash) -> Result { - csl::crypto::Ed25519KeyHash::from_bytes(val.0 .0.to_owned()) + csl::Ed25519KeyHash::from_bytes(val.0 .0.to_owned()) .map_err(TryFromPLAError::CSLDeserializeError) } } diff --git a/plutus-ledger-api/src/v1/datum.rs b/plutus-ledger-api/src/v1/datum.rs index 712dea5..eba5f64 100644 --- a/plutus-ledger-api/src/v1/datum.rs +++ b/plutus-ledger-api/src/v1/datum.rs @@ -32,16 +32,15 @@ impl IsPlutusData for DatumHash { } } -impl FromCSL for DatumHash { - fn from_csl(value: &csl::crypto::DataHash) -> Self { +impl FromCSL for DatumHash { + fn from_csl(value: &csl::DataHash) -> Self { DatumHash(LedgerBytes(value.to_bytes())) } } -impl TryFromPLA for csl::crypto::DataHash { +impl TryFromPLA for csl::DataHash { fn try_from_pla(val: &DatumHash) -> Result { - csl::crypto::DataHash::from_bytes(val.0 .0.to_owned()) - .map_err(TryFromPLAError::CSLDeserializeError) + csl::DataHash::from_bytes(val.0 .0.to_owned()).map_err(TryFromPLAError::CSLDeserializeError) } } @@ -65,7 +64,7 @@ impl IsPlutusData for Datum { } } -impl TryFromPLA for csl::plutus::PlutusData { +impl TryFromPLA for csl::PlutusData { fn try_from_pla(val: &Datum) -> Result { val.0.try_to_csl() } diff --git a/plutus-ledger-api/src/v1/redeemer.rs b/plutus-ledger-api/src/v1/redeemer.rs index 35850c3..95ffa9c 100644 --- a/plutus-ledger-api/src/v1/redeemer.rs +++ b/plutus-ledger-api/src/v1/redeemer.rs @@ -33,22 +33,20 @@ impl IsPlutusData for Redeemer { } #[derive(Clone, Debug)] -struct RedeemerWithExtraInfo<'a> { - redeemer: &'a Redeemer, - tag: &'a csl::plutus::RedeemerTag, - index: u64, +pub struct RedeemerWithExtraInfo<'a> { + pub redeemer: &'a Redeemer, + pub tag: &'a csl::RedeemerTag, + pub index: u64, } -impl TryFromPLA> for csl::plutus::Redeemer { - fn try_from_pla<'a>( - val: &RedeemerWithExtraInfo<'_>, - ) -> Result { +impl TryFromPLA> for csl::Redeemer { + fn try_from_pla<'a>(val: &RedeemerWithExtraInfo<'_>) -> Result { let Redeemer(plutus_data) = val.redeemer; - Ok(csl::plutus::Redeemer::new( + Ok(csl::Redeemer::new( val.tag, &val.index.try_to_csl()?, &plutus_data.try_to_csl()?, - &csl::plutus::ExUnits::new(&csl::utils::to_bignum(0), &csl::utils::to_bignum(0)), + &csl::ExUnits::new(&csl::BigNum::from(0u64), &csl::BigNum::from(0u64)), )) } } diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index b95c655..ddfcb89 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -32,8 +32,8 @@ impl IsPlutusData for ValidatorHash { } } -impl FromCSL for ValidatorHash { - fn from_csl(value: &csl::crypto::ScriptHash) -> Self { +impl FromCSL for ValidatorHash { + fn from_csl(value: &csl::ScriptHash) -> Self { ValidatorHash(ScriptHash::from_csl(value)) } } @@ -90,15 +90,15 @@ impl IsPlutusData for ScriptHash { } } -impl FromCSL for ScriptHash { - fn from_csl(value: &csl::crypto::ScriptHash) -> Self { +impl FromCSL for ScriptHash { + fn from_csl(value: &csl::ScriptHash) -> Self { ScriptHash(LedgerBytes(value.to_bytes())) } } -impl TryFromPLA for csl::crypto::ScriptHash { +impl TryFromPLA for csl::ScriptHash { fn try_from_pla(val: &ScriptHash) -> Result { - csl::crypto::ScriptHash::from_bytes(val.0 .0.to_owned()) + csl::ScriptHash::from_bytes(val.0 .0.to_owned()) .map_err(TryFromPLAError::CSLDeserializeError) } } diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index ef2506c..54fcff0 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -166,15 +166,15 @@ impl IsPlutusData for TransactionHash { } } -impl FromCSL for TransactionHash { - fn from_csl(value: &csl::crypto::TransactionHash) -> Self { +impl FromCSL for TransactionHash { + fn from_csl(value: &csl::TransactionHash) -> Self { TransactionHash(LedgerBytes(value.to_bytes())) } } -impl TryFromPLA for csl::crypto::TransactionHash { +impl TryFromPLA for csl::TransactionHash { fn try_from_pla(val: &TransactionHash) -> Result { - csl::crypto::TransactionHash::from_bytes(val.0 .0.to_owned()) + csl::TransactionHash::from_bytes(val.0 .0.to_owned()) .map_err(TryFromPLAError::CSLDeserializeError) } } diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index e007ef9..7c02681 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -468,8 +468,8 @@ impl FromCSL for Value { } } -impl FromCSL for Value { - fn from_csl(value: &csl::utils::Value) -> Self { +impl FromCSL for Value { + fn from_csl(value: &csl::Value) -> Self { let lovelaces = BigInt::from_csl(&value.coin()); let mut pla_value = Value::ada_value(&lovelaces); if let Some(multi_asset) = value.multiasset() { @@ -479,13 +479,13 @@ impl FromCSL for Value { } } -impl TryFromPLA for csl::utils::Value { +impl TryFromPLA for csl::Value { fn try_from_pla(val: &Value) -> Result { - let coin: csl::utils::Coin = val + let coin: csl::Coin = val .0 .get(&CurrencySymbol::Ada) .and_then(|m| m.get(&TokenName::ada())) - .map_or(Ok(csl::utils::BigNum::zero()), TryToCSL::try_to_csl)?; + .map_or(Ok(csl::BigNum::zero()), TryToCSL::try_to_csl)?; let m_ass = val .0 @@ -499,7 +499,7 @@ impl TryFromPLA for csl::utils::Value { Ok(acc) })?; - let mut v = csl::utils::Value::new(&coin); + let mut v = csl::Value::new(&coin); v.set_multiasset(&m_ass); @@ -544,7 +544,8 @@ impl TryFromPLA> for csl::MintAssets { fn try_from_pla(val: &BTreeMap) -> Result { val.iter() .try_fold(csl::MintAssets::new(), |mut acc, (k, v)| { - acc.insert(&k.try_to_csl()?, v.try_to_csl()?); + acc.insert(&k.try_to_csl()?, &v.try_to_csl()?) + .map_err(TryFromPLAError::CSLJsError)?; Ok(acc) }) } @@ -557,7 +558,7 @@ impl FromCSL for Value { (0..keys.len()) .map(|idx| { let sh = keys.get(idx); - let ass = mint.get_all(&sh).unwrap_or(csl::MintsAssets::new()); + let ass = mint.get(&sh).unwrap_or(csl::MintsAssets::new()); ( CurrencySymbol::NativeToken(MintingPolicyHash::from_csl(&sh)), BTreeMap::from_csl(&ass), diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index 096f0a6..9374256 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -127,14 +127,14 @@ impl TryFromCSL for Vec { #[derive(Clone, Debug)] pub struct TransactionOutputWithExtraInfo<'a> { pub transaction_output: &'a TransactionOutput, - pub scripts: &'a BTreeMap, + pub scripts: &'a BTreeMap, pub network_id: u8, pub data_cost: &'a csl::DataCost, } impl TryFromPLA> for csl::TransactionOutput { fn try_from_pla(val: &TransactionOutputWithExtraInfo<'_>) -> Result { - let mut output_builder = csl::output_builder::TransactionOutputBuilder::new().with_address( + let mut output_builder = csl::TransactionOutputBuilder::new().with_address( &AddressWithExtraInfo { address: &val.transaction_output.address, network_tag: val.network_id, @@ -167,7 +167,7 @@ impl TryFromPLA> for csl::TransactionOutput { let value_without_min_utxo = val.transaction_output.value.try_to_csl()?; - let mut calc = csl::utils::MinOutputAdaCalculator::new_empty(val.data_cost) + let mut calc = csl::MinOutputAdaCalculator::new_empty(val.data_cost) .map_err(TryFromPLAError::CSLJsError)?; calc.set_amount(&value_without_min_utxo); match &val.transaction_output.datum { @@ -187,8 +187,8 @@ impl TryFromPLA> for csl::TransactionOutput { let coin = std::cmp::max(value_without_min_utxo.coin(), required_coin); let value = match value_without_min_utxo.multiasset() { - Some(multiasset) => csl::utils::Value::new_with_assets(&coin, &multiasset), - None => csl::utils::Value::new(&coin), + Some(multiasset) => csl::Value::new_with_assets(&coin, &multiasset), + None => csl::Value::new(&coin), }; output_builder @@ -322,8 +322,8 @@ impl IsPlutusData for TransactionInfo { #[derive(Clone, Debug)] pub struct WithdrawalsWithExtraInfo<'a> { - withdrawals: &'a AssocMap, - network_tag: u8, + pub withdrawals: &'a AssocMap, + pub network_tag: u8, } impl TryFromPLA> for csl::Withdrawals { From 9274576971399327b6a69b8d0bf019bd67833131 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Fri, 4 Oct 2024 14:37:14 +0200 Subject: [PATCH 08/38] Changelog and version bump --- plutus-ledger-api/CHANGELOG.md | 11 +++++++++++ plutus-ledger-api/Cargo.lock | 2 +- plutus-ledger-api/Cargo.toml | 2 +- plutus-ledger-api/build.nix | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index e98308b..385b92b 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -12,6 +12,17 @@ Changelog](https://keepachangelog.com/en/1.1.0). ### Removed +## v2.0.0 + +### Added + +- Added cardano-serialization-lib conversion traits (`ToCSL` and `FromCSL`) + +### Changed + +- Fixed `serde` serialization of Plutus `Value`s +- Updated cardano-serialization-lib to Conway compatible 12.1.0 + ## v1.0.0 ### Added diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 30548b3..17e1f90 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -600,7 +600,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "plutus-ledger-api" -version = "1.0.0" +version = "2.0.0-beta.1" dependencies = [ "anyhow", "cardano-serialization-lib", diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index 2d1903c..66411b0 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plutus-ledger-api" -version = "1.0.0" +version = "2.0.0-beta.1" edition = "2021" license = "Apache-2.0" description = "Plutus Ledger types and utilities implemented in Rust" diff --git a/plutus-ledger-api/build.nix b/plutus-ledger-api/build.nix index d43c706..c4ad5db 100644 --- a/plutus-ledger-api/build.nix +++ b/plutus-ledger-api/build.nix @@ -4,7 +4,7 @@ rustFlake = inputs.flake-lang.lib.${system}.rustFlake { src = ./.; - version = "0"; + version = "2"; crateName = "plutus-ledger-api"; devShellHook = config.settings.shell.hook; cargoNextestExtraArgs = "--all-features"; From 87e07ef86e372e147de990e2cc014b3ac1c90453 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 14 Oct 2024 20:28:44 +0800 Subject: [PATCH 09/38] implement procedural derive macro for `IsPlutusData` --- .gitignore | 1 + flake.nix | 1 + is-plutus-data-derive/Cargo.lock | 68 +++ is-plutus-data-derive/Cargo.toml | 13 + is-plutus-data-derive/build.nix | 18 + is-plutus-data-derive/src/derive_impl.rs | 706 +++++++++++++++++++++++ is-plutus-data-derive/src/lib.rs | 13 + 7 files changed, 820 insertions(+) create mode 100644 is-plutus-data-derive/Cargo.lock create mode 100644 is-plutus-data-derive/Cargo.toml create mode 100644 is-plutus-data-derive/build.nix create mode 100644 is-plutus-data-derive/src/derive_impl.rs create mode 100644 is-plutus-data-derive/src/lib.rs diff --git a/.gitignore b/.gitignore index 1a1f6a6..0871c3a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ result .direnv .pre-commit-config.yaml .DS_Store +target diff --git a/flake.nix b/flake.nix index 4f5785b..8d68e4d 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,7 @@ ./hercules-ci.nix ./plutus-ledger-api/build.nix + ./is-plutus-data-derive/build.nix ]; debug = true; systems = [ "x86_64-linux" "x86_64-darwin" ]; diff --git a/is-plutus-data-derive/Cargo.lock b/is-plutus-data-derive/Cargo.lock new file mode 100644 index 0000000..00cbc00 --- /dev/null +++ b/is-plutus-data-derive/Cargo.lock @@ -0,0 +1,68 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "is-plutus-data-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "thiserror", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" diff --git a/is-plutus-data-derive/Cargo.toml b/is-plutus-data-derive/Cargo.toml new file mode 100644 index 0000000..acaf07f --- /dev/null +++ b/is-plutus-data-derive/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "is-plutus-data-derive" +version = "0.1.0" +edition = "2021" + +[dependencies] +proc-macro2 = "1.0.87" +quote = "1.0.37" +syn = { version = "2.0.79", features = ["full", "extra-traits"]} +thiserror = "1.0.64" + +[lib] +proc-macro = true diff --git a/is-plutus-data-derive/build.nix b/is-plutus-data-derive/build.nix new file mode 100644 index 0000000..ac6ecba --- /dev/null +++ b/is-plutus-data-derive/build.nix @@ -0,0 +1,18 @@ +{ inputs, ... }: { + perSystem = { config, system, ... }: + let + rustFlake = + inputs.flake-lang.lib.${system}.rustFlake { + src = ./.; + version = "0"; + crateName = "is-plutus-data-derive"; + devShellHook = config.settings.shell.hook; + cargoNextestExtraArgs = "--all-features"; + generateDocs = false; + }; + + in + { + inherit (rustFlake) packages checks devShells; + }; +} diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs new file mode 100644 index 0000000..d287406 --- /dev/null +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -0,0 +1,706 @@ +use std::str::FromStr; + +use quote::format_ident; +use syn::{ + parse::{Parse, ParseStream}, + parse_quote, + spanned::Spanned, + Arm, Attribute, Block, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, Fields, + FieldsNamed, FieldsUnnamed, Ident, Index, ItemImpl, Meta, Path, Result, Stmt, +}; + +pub(crate) fn get_is_plutus_data_instance(input: DeriveInput) -> Result { + let type_name = &input.ident; + + let strategy = get_derive_strategy(&input)?; + + let plutus_data_input_var: Ident = parse_quote!(plutus_data); + + let (encoder, decoder) = match strategy { + DeriveStrategy::Newtype => get_newtype_encoder_decoder(&input), + DeriveStrategy::List => get_list_encoder_decoder(&input, &plutus_data_input_var), + DeriveStrategy::Constr => get_constr_encoder_decoder(&input, &plutus_data_input_var), + }?; + + let mut generics = input.generics; + + // TODO(chfanghr): Do we care about type role? + generics.type_params_mut().for_each(|param| { + param + .bounds + .push(parse_quote!(plutus_ledger_api::plutus_Data::IsPlutusData)); + }); + + let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); + + Ok(parse_quote!( + impl #impl_generics plutus_ledger_api::plutus_data::IsPlutusData for #type_name #type_generics #where_clause { + fn to_plutus_data(&self) -> plutus_ledger_api::plutus_data::PlutusData { + #encoder + } + + fn from_plutus_data(plutus_data: &plutus_ledger_api::plutus_data::PlutusData) -> Result + where Self: Sized { + #decoder + } + } + )) +} + +#[derive(Debug)] +enum DeriveStrategy { + Newtype, + List, + Constr, +} + +#[derive(Debug, thiserror::Error)] +enum DeriveStrategyError { + #[error("Unknown strategy {0}. Should be one of Newtype, List and Constr.")] + UnknownStrategy(String), + #[error("Unable to parse strategy. Should be an Ident.")] + UnexpectedToken, + #[error("More than one strategies specified.")] + MoreThanOneSpecified, +} + +impl Default for DeriveStrategy { + fn default() -> Self { + Self::Constr + } +} + +impl FromStr for DeriveStrategy { + type Err = DeriveStrategyError; + + fn from_str(s: &str) -> std::result::Result { + match s { + "Newtype" => Ok(Self::Newtype), + "List" => Ok(Self::List), + "Constr" => Ok(Self::Constr), + _ => Err(DeriveStrategyError::UnknownStrategy(s.into())), + } + } +} +impl Parse for DeriveStrategy { + fn parse(input: ParseStream) -> Result { + let ident = input.call(Ident::parse)?; + Self::from_str(&ident.to_string()).map_err(|unknown_strategy| { + Error::new( + ident.span(), + format!("unknown strategy: {}", unknown_strategy), + ) + }) + } +} + +fn try_parse_derive_strategy(attr: &Attribute) -> Option> { + let value = match &attr.meta { + Meta::NameValue(name_value) => name_value + .path + .is_ident("plutus_data_derive_strategy") + .then_some(&name_value.value), + _ => None, + }?; + + Some(match &value { + Expr::Path(path) => (|| -> Result { + let ident = path.path.require_ident()?; + DeriveStrategy::from_str(&ident.to_string()) + .map_err(|err| Error::new(ident.span(), err)) + })(), + _ => Err(Error::new( + value.span(), + DeriveStrategyError::UnexpectedToken, + )), + }) +} + +fn get_derive_strategy(input: &DeriveInput) -> Result { + let mut derive_strategy_results: Vec<_> = input + .attrs + .iter() + .map(try_parse_derive_strategy) + .flatten() + .collect(); + + match derive_strategy_results.len() { + 0 => Ok(DeriveStrategy::default()), + 1 => derive_strategy_results.remove(0), + _ => Err(Error::new( + input.span(), + DeriveStrategyError::MoreThanOneSpecified, + )), + } +} + +#[derive(Debug, thiserror::Error)] +enum NewtypeStrategyError { + #[error("Only struct types are supported by newtype strategy")] + UnexpectedDataVariant, + #[error("Newtype derivation expects exactly one filed")] + NotSingleField, +} + +fn get_newtype_encoder_decoder(input: &DeriveInput) -> Result<(Block, Block)> { + let s = match &input.data { + Data::Struct(s) => Ok(s), + _ => Err(Error::new( + input.span(), + NewtypeStrategyError::UnexpectedDataVariant, + )), + }?; + + if s.fields.len() != 1 { + Err(Error::new( + input.span(), + NewtypeStrategyError::NotSingleField, + ))? + } + + let field = s.fields.iter().next().unwrap(); + + let encoder = match &field.ident { + None => parse_quote!({ self.0.to_plutus_data() }), + Some(ident) => parse_quote!({ + self.#ident.to_plutus_data() + }), + }; + + let decoder = match &field.ident { + Some(field_name) => { + parse_quote!({ + Ok(Self { + #field_name: plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)? + }) + }) + } + None => { + parse_quote!({ + Ok(Self( + plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)?, + )) + }) + } + }; + + Ok((encoder, decoder)) +} + +#[derive(Debug, thiserror::Error)] +enum ListStrategyError { + #[error("Only struct types are supported by list strategy")] + UnexpectedDataVariant, +} + +fn get_list_encoder_decoder( + input: &DeriveInput, + plutus_data_input_var: &Ident, +) -> Result<(Block, Block)> { + match &input.data { + Data::Struct(s) => match &s.fields { + Fields::Named(fields_named) => Ok(( + struct_with_named_fields_to_plutus_data_list(fields_named), + struct_with_named_fields_from_plutus_data_list(fields_named, plutus_data_input_var), + )), + Fields::Unnamed(fields_unnamed) => Ok(( + struct_with_unnamed_fields_to_plutus_data_list(fields_unnamed), + struct_with_unnamed_fields_from_plutus_data_list( + fields_unnamed, + plutus_data_input_var, + ), + )), + Fields::Unit => Ok(( + struct_with_no_field_to_plutus_data_list(), + struct_with_no_field_from_plutus_data_list(plutus_data_input_var), + )), + }, + _ => Err(Error::new( + input.span(), + ListStrategyError::UnexpectedDataVariant, + )), + } +} + +#[derive(Debug, thiserror::Error)] +enum ConstrStrategyError { + #[error("Union types are supported by constr strategy")] + UnexpectedDataVariant, +} + +fn get_constr_encoder_decoder( + input: &DeriveInput, + plutus_data_input_var: &Ident, +) -> Result<(Block, Block)> { + Ok(match &input.data { + Data::Enum(e) => get_enum_constr_encoder_decoder(e, plutus_data_input_var), + Data::Struct(s) => get_struct_constr_encoder_decoder(s, plutus_data_input_var), + _ => Err(Error::new( + input.span(), + ConstrStrategyError::UnexpectedDataVariant, + ))?, + }) +} + +fn get_enum_constr_encoder_decoder(e: &DataEnum, plutus_data_input_var: &Ident) -> (Block, Block) { + ( + enum_to_plutus_data_constr(&e), + enum_from_plutus_data_constr(&e, plutus_data_input_var), + ) +} + +fn get_struct_constr_encoder_decoder( + s: &DataStruct, + plutus_data_input_var: &Ident, +) -> (Block, Block) { + match &s.fields { + Fields::Named(fields_named) => ( + struct_with_named_fields_to_plutus_data_constr(fields_named), + struct_with_named_fields_from_plutus_data_constr(fields_named, plutus_data_input_var), + ), + Fields::Unnamed(fields_unnamed) => ( + struct_with_unnamed_fields_to_plutus_data_constr(fields_unnamed), + struct_with_unnamed_fields_from_plutus_data_constr( + fields_unnamed, + plutus_data_input_var, + ), + ), + Fields::Unit => ( + struct_with_no_field_to_plutus_data_constr(), + struct_with_no_field_from_plutus_data_constr(plutus_data_input_var), + ), + } +} + +fn enum_to_plutus_data_constr(e: &DataEnum) -> Block { + let variants = &e.variants; + let tags = 0..variants.len(); + + let arms = tags.zip(variants.iter()).map(|(tag, variant)| { + let variant_name = &variant.ident; + let constructor: Path = parse_quote!(Self::#variant_name); + let fields = &variant.fields; + variant_to_plutus_data(&constructor, tag, fields) + }); + + parse_quote!({ + match &self { + #(#arms),* + } + }) +} + +fn enum_from_plutus_data_constr(e: &DataEnum, plutus_data_input_var: &Ident) -> Block { + let variants = &e.variants; + let tags = 0..variants.len(); + let expected_tags_str = String::from("Constr with tag: ") + + &tags + .clone() + .map(|t| t.to_string()) + .collect::>() + .join("/"); + let plutus_data_list_var: Ident = parse_quote!(plutus_data_list); + + let arms = tags.zip(variants.iter()).map(|(tag, variant)| { + let variant_name = &variant.ident; + let constructor: Path = parse_quote!(Self::#variant_name); + let fields = &variant.fields; + + variant_from_plutus_data(&constructor, tag, fields, &plutus_data_list_var) + }); + + parse_quote!( + { + let (tag, #plutus_data_list_var) = plutus_ledger_api::plutus_data::parse_constr(#plutus_data_input_var)?; + + match tag { + #(#arms),* + tag => Err(plutus_ledger_api::plutus_data::PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!(#expected_tags_str), + got: tag.to_string(), + }), + } + } + ) +} + +fn variant_to_plutus_data(constructor: &Path, tag: usize, fields: &Fields) -> Arm { + match fields { + Fields::Named(named) => variant_with_named_fields_to_plutus_data(&constructor, tag, &named), + Fields::Unnamed(unnamed) => { + variant_with_unnamed_field_to_plutus_data(&constructor, tag, &unnamed) + } + Fields::Unit => variant_with_no_field_to_plutus_data(&constructor, tag), + } +} + +fn variant_from_plutus_data( + constructor: &Path, + tag: usize, + fields: &Fields, + plutus_data_list_var: &Ident, +) -> Arm { + let block = match fields { + Fields::Named(named) => variant_with_named_fields_from_plutus_data_list( + constructor, + named, + plutus_data_list_var, + ), + Fields::Unnamed(unnamed) => variant_with_unnamed_fields_from_plutus_data_list( + constructor, + unnamed, + plutus_data_list_var, + ), + Fields::Unit => { + variant_with_no_field_from_plutus_data_list(constructor, plutus_data_list_var) + } + }; + + let tag = tag as u32; + + parse_quote!( + #tag => #block + ) +} + +fn variant_with_named_fields_to_plutus_data( + constructor: &Path, + tag: usize, + fields_named: &FieldsNamed, +) -> Arm { + let field_names = fields_named + .named + .iter() + .map(|field| field.ident.as_ref().unwrap()); + + let field_accessors = field_names + .clone() + .map(|field_name| -> Expr { parse_quote!(#field_name) }) + .collect::>(); + + let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); + + parse_quote!( + #constructor{ #(#field_names),* } => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + ) +} + +fn variant_with_named_fields_from_plutus_data_list( + constructor: &Path, + fields_named: &FieldsNamed, + plutus_data_list_var: &Ident, +) -> Block { + data_with_named_fields_from_list_of_plutus_data(constructor, fields_named, plutus_data_list_var) +} + +fn variant_with_unnamed_field_to_plutus_data( + constructor: &Path, + tag: usize, + fields_unnamed: &FieldsUnnamed, +) -> Arm { + let field_names = (0..fields_unnamed.unnamed.len()).map(|idx| format_ident!("field_{}", idx)); + + let field_accessors = field_names + .clone() + .map(|field_name| -> Expr { parse_quote!(#field_name) }) + .collect::>(); + + let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); + + parse_quote!( + #constructor(#(#field_names),*) => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + ) +} + +fn variant_with_unnamed_fields_from_plutus_data_list( + constructor: &Path, + fields_unnamed: &FieldsUnnamed, + plutus_data_list_var: &Ident, +) -> Block { + data_with_unnamed_fields_from_list_of_plutus_data( + constructor, + fields_unnamed, + plutus_data_list_var, + ) +} + +fn variant_with_no_field_to_plutus_data(constructor: &Path, tag: usize) -> Arm { + parse_quote!( + #constructor => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), vec![]) + ) +} + +fn variant_with_no_field_from_plutus_data_list( + constructor: &Path, + plutus_data_list_var: &Ident, +) -> Block { + data_with_no_fields_from_list_of_plutus_data(constructor, plutus_data_list_var) +} + +fn struct_with_named_fields_to_list_of_plutus_data(fields: &FieldsNamed) -> Block { + let field_accessors = fields + .named + .iter() + .map(|field| -> Expr { + let field_name = field.ident.as_ref().unwrap(); + + parse_quote!(self.#field_name) + }) + .collect::>(); + + data_fields_to_list_of_plutus_data(&field_accessors) +} + +fn struct_with_named_fields_from_list_of_plutus_data( + fields: &FieldsNamed, + plutus_data_list_var: &Ident, +) -> Block { + let constructor: Path = parse_quote!(Self); + + data_with_named_fields_from_list_of_plutus_data(&constructor, fields, &plutus_data_list_var) +} + +fn struct_with_named_fields_to_plutus_data_list(fields: &FieldsNamed) -> Block { + let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); + + parse_quote!({ + plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) + }) +} + +fn struct_with_named_fields_from_plutus_data_list( + fields: &FieldsNamed, + plutus_data_input_var: &Ident, +) -> Block { + let list_of_plutus_data_var: Ident = parse_quote!(list_of_plutus_data); + + let from_list_of_plutus_data = + struct_with_named_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); + + parse_quote!({ + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; + + #from_list_of_plutus_data + }) +} + +fn struct_with_named_fields_to_plutus_data_constr(fields: &FieldsNamed) -> Block { + let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); + + parse_quote!({ + plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + }) +} + +fn struct_with_named_fields_from_plutus_data_constr( + fields: &FieldsNamed, + plutus_data_input_var: &Ident, +) -> Block { + let plutus_data_list_var: Ident = parse_quote!(plutus_data_list); + + let from_plutus_data_list = + struct_with_named_fields_from_list_of_plutus_data(fields, &plutus_data_list_var); + + parse_quote!({ + let #plutus_data_list_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + + #from_plutus_data_list + }) +} + +fn struct_with_unnamed_fields_to_list_of_plutus_data(fields: &FieldsUnnamed) -> Block { + let len = fields.unnamed.len(); + + let field_accessors = (0..len) + .into_iter() + .map(|idx| -> Expr { + let idx: Index = idx.into(); + + parse_quote!(self.#idx) + }) + .collect::>(); + + data_fields_to_list_of_plutus_data(&field_accessors) +} + +fn struct_with_unnamed_fields_from_list_of_plutus_data( + fields: &FieldsUnnamed, + plutus_data_list_var: &Ident, +) -> Block { + data_with_unnamed_fields_from_list_of_plutus_data( + &parse_quote!(Self), + fields, + plutus_data_list_var, + ) +} + +fn struct_with_unnamed_fields_to_plutus_data_list(fields: &FieldsUnnamed) -> Block { + let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); + + parse_quote!({ + plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) + }) +} + +fn struct_with_unnamed_fields_from_plutus_data_list( + fields: &FieldsUnnamed, + plutus_data_input_var: &Ident, +) -> Block { + let list_of_plutus_data_var: Ident = parse_quote!(list_of_plutus_data); + + let from_list_of_plutus_data = + struct_with_unnamed_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); + + parse_quote!({ + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; + + #from_list_of_plutus_data + }) +} + +fn struct_with_unnamed_fields_to_plutus_data_constr(fields: &FieldsUnnamed) -> Block { + let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); + + parse_quote!({ + plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + }) +} + +fn struct_with_unnamed_fields_from_plutus_data_constr( + fields: &FieldsUnnamed, + plutus_data_input_var: &Ident, +) -> Block { + let plutus_data_list_var: Ident = parse_quote!(plutus_data_list); + + let from_list_of_plutus_data = + struct_with_unnamed_fields_from_list_of_plutus_data(fields, &plutus_data_list_var); + + parse_quote!({ + let #plutus_data_list_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + + #from_list_of_plutus_data + }) +} + +fn struct_with_no_field_to_plutus_data_list() -> Block { + parse_quote!(plutus_ledger_api::plutus_data::PlutusData::Constr( + 0.into(), + vec![] + )) +} + +fn struct_with_no_field_from_plutus_data_list(plutus_data_input_var: &Ident) -> Block { + let list_of_plutus_data_var: Ident = parse_quote!(list_of_plutus_data); + + let from_list_of_plutus_data = + data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &list_of_plutus_data_var); + + parse_quote!({ + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; + + + + + #from_list_of_plutus_data + }) +} + +fn struct_with_no_field_to_plutus_data_constr() -> Block { + parse_quote!(plutus_ledger_api::plutus_data::PlutusData::Constr( + 0.into(), + vec![] + )) +} + +fn struct_with_no_field_from_plutus_data_constr(plutus_data_input_var: &Ident) -> Block { + let list_of_plutus_data_var: Ident = parse_quote!(list_of_plutus_data); + + let from_list_of_plutus_data = + data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &list_of_plutus_data_var); + + parse_quote!({ + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + + #from_list_of_plutus_data + }) +} + +fn data_fields_to_list_of_plutus_data(field_accessors: &[Expr]) -> Block { + let fields_to_plutus_data = field_accessors + .iter() + .map(|a| -> Expr { parse_quote!(#a.to_plutus_data()) }); + + parse_quote!({ vec![ #(#fields_to_plutus_data),* ] }) +} + +fn data_with_named_fields_from_list_of_plutus_data( + constructor: &Path, + fields_named: &FieldsNamed, + plutus_data_list_var: &Ident, +) -> Block { + let field_count = fields_named.named.len(); + + let field_idents = fields_named + .named + .iter() + .map(|field| field.ident.as_ref().unwrap()); + + let unparsed_field_idents = field_idents + .clone() + .map(|field_ident| format_ident!("unparsed_{}", field_ident)); + + let field_decoded_stmts = field_idents.clone().zip(unparsed_field_idents.clone()).map( + |(field_ident, unparsed_field_ident)| -> Stmt { + parse_quote!( + let #field_ident = plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(#unparsed_field_ident)?; + ) + }, + ); + + parse_quote!( + { + let [ #(#unparsed_field_idents),* ] = parse_fixed_len_plutus_data_list::<#field_count>(#plutus_data_list_var)?; + #(#field_decoded_stmts)* + Ok(#constructor{ #(#field_idents),* }) + } + ) +} + +fn data_with_unnamed_fields_from_list_of_plutus_data( + constructor: &Path, + fields_unnamed: &FieldsUnnamed, + plutus_data_list_var: &Ident, +) -> Block { + let field_count = fields_unnamed.unnamed.len(); + + let unparsed_field_idents = + (0..field_count).map(|field_index| format_ident!("unparsed_{}", field_index)); + + let parsed_field_idents = + (0..field_count).map(|field_index| format_ident!("parsed_{}", field_index)); + + let field_decoded_stmts = unparsed_field_idents + .clone() + .zip(parsed_field_idents.clone()) + .map(|(unparsed, parsed)| -> Stmt { + parse_quote!( + let #parsed = IsPlutusData::from_plutus_data(#unparsed)?; + ) + }); + + parse_quote!({ + let [ #(#unparsed_field_idents),* ] = parse_fixed_len_plutus_data_list::<#field_count>(#plutus_data_list_var)?; + #(#field_decoded_stmts)* + Ok(#constructor(#(#parsed_field_idents),*)) + }) +} + +fn data_with_no_fields_from_list_of_plutus_data( + constructor: &Path, + list_of_plutus_data_var: &Ident, +) -> Block { + parse_quote!({ + let [ ] = parse_fixed_len_plutus_data_list::<0>(#list_of_plutus_data_var)?; + Ok(#constructor) + }) +} diff --git a/is-plutus-data-derive/src/lib.rs b/is-plutus-data-derive/src/lib.rs new file mode 100644 index 0000000..4e54429 --- /dev/null +++ b/is-plutus-data-derive/src/lib.rs @@ -0,0 +1,13 @@ +use quote::ToTokens; +use syn::{parse_macro_input, DeriveInput}; + +pub(crate) mod derive_impl; + +#[proc_macro_derive(IsPlutusData, attributes(plutus_data_derive_strategy))] +pub fn derive_is_plutus_data(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as DeriveInput); + derive_impl::get_is_plutus_data_instance(input) + .unwrap() + .into_token_stream() + .into() +} From 21efc52e04be49b59884e61774482d45f8d6d86b Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Thu, 17 Oct 2024 23:46:35 +0800 Subject: [PATCH 10/38] separate `PlutusData` and `IsPlutusData` from plutus-ledger-api --- .gitignore | 1 + flake.nix | 1 + is-plutus-data-derive/src/derive_impl.rs | 80 +-- plutus-data/.envrc | 1 + plutus-data/Cargo.lock | 657 ++++++++++++++++++ plutus-data/Cargo.toml | 19 + plutus-data/build.nix | 19 + plutus-data/src/is_plutus_data/aux.rs | 66 ++ plutus-data/src/is_plutus_data/instances.rs | 292 ++++++++ .../src/is_plutus_data/is_plutus_data.rs | 22 + plutus-data/src/is_plutus_data/mod.rs | 3 + plutus-data/src/lib.rs | 8 + plutus-data/src/plutus_data.rs | 183 +++++ 13 files changed, 1306 insertions(+), 46 deletions(-) create mode 100644 plutus-data/.envrc create mode 100644 plutus-data/Cargo.lock create mode 100644 plutus-data/Cargo.toml create mode 100644 plutus-data/build.nix create mode 100644 plutus-data/src/is_plutus_data/aux.rs create mode 100644 plutus-data/src/is_plutus_data/instances.rs create mode 100644 plutus-data/src/is_plutus_data/is_plutus_data.rs create mode 100644 plutus-data/src/is_plutus_data/mod.rs create mode 100644 plutus-data/src/lib.rs create mode 100644 plutus-data/src/plutus_data.rs diff --git a/.gitignore b/.gitignore index 0871c3a..1f902d2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ result .pre-commit-config.yaml .DS_Store target +.extras diff --git a/flake.nix b/flake.nix index 8d68e4d..29f46ea 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,7 @@ ./plutus-ledger-api/build.nix ./is-plutus-data-derive/build.nix + ./plutus-data/build.nix ]; debug = true; systems = [ "x86_64-linux" "x86_64-darwin" ]; diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs index d287406..35fc5e5 100644 --- a/is-plutus-data-derive/src/derive_impl.rs +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -24,22 +24,20 @@ pub(crate) fn get_is_plutus_data_instance(input: DeriveInput) -> Result plutus_ledger_api::plutus_data::PlutusData { + impl #impl_generics plutus_data::IsPlutusData for #type_name #type_generics #where_clause { + fn to_plutus_data(&self) -> plutus_data::PlutusData { #encoder } - fn from_plutus_data(plutus_data: &plutus_ledger_api::plutus_data::PlutusData) -> Result + fn from_plutus_data(plutus_data: &plutus_data::PlutusData) -> Result where Self: Sized { #decoder } @@ -171,15 +169,15 @@ fn get_newtype_encoder_decoder(input: &DeriveInput) -> Result<(Block, Block)> { Some(field_name) => { parse_quote!({ Ok(Self { - #field_name: plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)? + #field_name: plutus_data::IsPlutusData::from_plutus_data(plutus_data)? }) }) } None => { parse_quote!({ - Ok(Self( - plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)?, - )) + Ok(Self(plutus_data::IsPlutusData::from_plutus_data( + plutus_data, + )?)) }) } }; @@ -311,11 +309,11 @@ fn enum_from_plutus_data_constr(e: &DataEnum, plutus_data_input_var: &Ident) -> parse_quote!( { - let (tag, #plutus_data_list_var) = plutus_ledger_api::plutus_data::parse_constr(#plutus_data_input_var)?; + let (tag, #plutus_data_list_var) = plutus_data::is_plutus_data::aux::parse_constr(#plutus_data_input_var)?; match tag { #(#arms),* - tag => Err(plutus_ledger_api::plutus_data::PlutusDataError::UnexpectedPlutusInvariant { + tag => Err(plutus_data::PlutusDataError::UnexpectedPlutusInvariant { wanted: format!(#expected_tags_str), got: tag.to_string(), }), @@ -381,7 +379,7 @@ fn variant_with_named_fields_to_plutus_data( let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); parse_quote!( - #constructor{ #(#field_names),* } => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + #constructor{ #(#field_names),* } => plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) ) } @@ -408,7 +406,7 @@ fn variant_with_unnamed_field_to_plutus_data( let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); parse_quote!( - #constructor(#(#field_names),*) => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + #constructor(#(#field_names),*) => plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) ) } @@ -426,7 +424,7 @@ fn variant_with_unnamed_fields_from_plutus_data_list( fn variant_with_no_field_to_plutus_data(constructor: &Path, tag: usize) -> Arm { parse_quote!( - #constructor => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), vec![]) + #constructor => plutus_data::PlutusData::Constr(#tag.into(), vec![]) ) } @@ -464,7 +462,7 @@ fn struct_with_named_fields_to_plutus_data_list(fields: &FieldsNamed) -> Block { let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) + plutus_data::PlutusData::List(#to_list_of_plutus_data) }) } @@ -478,7 +476,7 @@ fn struct_with_named_fields_from_plutus_data_list( struct_with_named_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; + let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) @@ -488,7 +486,7 @@ fn struct_with_named_fields_to_plutus_data_constr(fields: &FieldsNamed) -> Block let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) }) } @@ -502,7 +500,7 @@ fn struct_with_named_fields_from_plutus_data_constr( struct_with_named_fields_from_list_of_plutus_data(fields, &plutus_data_list_var); parse_quote!({ - let #plutus_data_list_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #plutus_data_list_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; #from_plutus_data_list }) @@ -538,7 +536,7 @@ fn struct_with_unnamed_fields_to_plutus_data_list(fields: &FieldsUnnamed) -> Blo let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) + plutus_data::PlutusData::List(#to_list_of_plutus_data) }) } @@ -552,7 +550,7 @@ fn struct_with_unnamed_fields_from_plutus_data_list( struct_with_unnamed_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; + let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) @@ -562,7 +560,7 @@ fn struct_with_unnamed_fields_to_plutus_data_constr(fields: &FieldsUnnamed) -> B let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) }) } @@ -570,23 +568,19 @@ fn struct_with_unnamed_fields_from_plutus_data_constr( fields: &FieldsUnnamed, plutus_data_input_var: &Ident, ) -> Block { - let plutus_data_list_var: Ident = parse_quote!(plutus_data_list); + let fields_var: Ident = parse_quote!(fields); - let from_list_of_plutus_data = - struct_with_unnamed_fields_from_list_of_plutus_data(fields, &plutus_data_list_var); + let from_fields = struct_with_unnamed_fields_from_list_of_plutus_data(fields, &fields_var); parse_quote!({ - let #plutus_data_list_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #fields_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; - #from_list_of_plutus_data + #from_fields }) } fn struct_with_no_field_to_plutus_data_list() -> Block { - parse_quote!(plutus_ledger_api::plutus_data::PlutusData::Constr( - 0.into(), - vec![] - )) + parse_quote!(plutus_data::PlutusData::Constr(0.into(), vec![])) } fn struct_with_no_field_from_plutus_data_list(plutus_data_input_var: &Ident) -> Block { @@ -596,32 +590,26 @@ fn struct_with_no_field_from_plutus_data_list(plutus_data_input_var: &Ident) -> data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; - - - + let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) } fn struct_with_no_field_to_plutus_data_constr() -> Block { - parse_quote!(plutus_ledger_api::plutus_data::PlutusData::Constr( - 0.into(), - vec![] - )) + parse_quote!(plutus_data::PlutusData::Constr(0.into(), vec![])) } fn struct_with_no_field_from_plutus_data_constr(plutus_data_input_var: &Ident) -> Block { - let list_of_plutus_data_var: Ident = parse_quote!(list_of_plutus_data); + let fields_var: Ident = parse_quote!(fields); - let from_list_of_plutus_data = - data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &list_of_plutus_data_var); + let from_fields = + data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &fields_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #fields_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; - #from_list_of_plutus_data + #from_fields }) } @@ -652,7 +640,7 @@ fn data_with_named_fields_from_list_of_plutus_data( let field_decoded_stmts = field_idents.clone().zip(unparsed_field_idents.clone()).map( |(field_ident, unparsed_field_ident)| -> Stmt { parse_quote!( - let #field_ident = plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(#unparsed_field_ident)?; + let #field_ident = plutus_data::IsPlutusData::from_plutus_data(#unparsed_field_ident)?; ) }, ); diff --git a/plutus-data/.envrc b/plutus-data/.envrc new file mode 100644 index 0000000..6841e87 --- /dev/null +++ b/plutus-data/.envrc @@ -0,0 +1 @@ +use flake .#dev-plutus-data-rust diff --git a/plutus-data/Cargo.lock b/plutus-data/Cargo.lock new file mode 100644 index 0000000..690b993 --- /dev/null +++ b/plutus-data/Cargo.lock @@ -0,0 +1,657 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "dissimilar" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is-plutus-data-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "thiserror", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lbr-prelude" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21471892874c4667636a067ed7a158b9691178988a4c5988585e1010e9b5817d" +dependencies = [ + "data-encoding", + "lbr-prelude-derive", + "num-bigint", + "proptest", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "lbr-prelude-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370d0aa0809ee84ccf7c6d84ae2d6ac97b84cb1337b3d145101bcf6a7319deac" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "trybuild", +] + +[[package]] +name = "libc" +version = "0.2.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "plutus-data" +version = "0.1.0" +dependencies = [ + "data-encoding", + "is-plutus-data-derive", + "lbr-prelude", + "num-bigint", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "trybuild" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8923cde76a6329058a86f04d033f0945a2c6df8b94093512e4ab188b3e3a8950" +dependencies = [ + "dissimilar", + "glob", + "serde", + "serde_derive", + "serde_json", + "termcolor", + "toml", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/plutus-data/Cargo.toml b/plutus-data/Cargo.toml new file mode 100644 index 0000000..ade6890 --- /dev/null +++ b/plutus-data/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "plutus-data" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = { version = "^1.0.189", features = ["derive"], optional = true } +serde_json = { version = "1.0.128", optional = true } +num-bigint = "~0.4" +is-plutus-data-derive = { path = ".extras/is-plutus-data-derive-0", optional = true } +lbr-prelude = { version = "0.1.1", optional = true } +data-encoding = { version = "2.6.0", optional = true } +thiserror = "1.0.64" + +[features] +default = [] +serde = ["dep:serde", "num-bigint/serde", "dep:serde_json"] +lbf = ["dep:lbr-prelude", "dep:serde_json", "dep:data-encoding"] +derive = ["dep:is-plutus-data-derive"] diff --git a/plutus-data/build.nix b/plutus-data/build.nix new file mode 100644 index 0000000..33b0093 --- /dev/null +++ b/plutus-data/build.nix @@ -0,0 +1,19 @@ +{ inputs, ... }: { + perSystem = { config, system, ... }: + let + rustFlake = + inputs.flake-lang.lib.${system}.rustFlake { + src = ./.; + version = "0"; + crateName = "plutus-data"; + devShellHook = config.settings.shell.hook; + cargoNextestExtraArgs = "--all-features"; + extraSources = [ + config.packages.is-plutus-data-derive-rust-src + ]; + }; + in + { + inherit (rustFlake) packages checks devShells; + }; +} diff --git a/plutus-data/src/is_plutus_data/aux.rs b/plutus-data/src/is_plutus_data/aux.rs new file mode 100644 index 0000000..b793f7f --- /dev/null +++ b/plutus-data/src/is_plutus_data/aux.rs @@ -0,0 +1,66 @@ +use crate::{PlutusData, PlutusDataError, PlutusType}; + +/// Given a vector of PlutusData, parse it as an array whose length is known at +/// compile time. +/// +/// This function is used by the derive macro. +pub fn parse_fixed_len_constr_fields( + v: &[PlutusData], +) -> Result<&[PlutusData; LEN], PlutusDataError> { + v.try_into() + .map_err(|_| PlutusDataError::UnexpectedListLength { + got: v.len(), + wanted: LEN, + }) +} + +/// Given a PlutusData, parse it as PlutusData::Constr and its tag as u32. Return +/// the u32 tag and fields. +/// +/// This function is used by the derive macro. +pub fn parse_constr(data: &PlutusData) -> Result<(u32, &Vec), PlutusDataError> { + match data { + PlutusData::Constr(tag, fields) => u32::try_from(tag) + .map_err(|err| PlutusDataError::UnexpectedPlutusInvariant { + got: err.to_string(), + wanted: "Constr bigint tag within u32 range".into(), + }) + .map(|tag| (tag, fields)), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Constr, + got: PlutusType::from(data), + }), + } +} + +/// Given a PlutusData, parse it as PlutusData::Constr and verify its tag. +/// +/// This function is used by the derive macro. +pub fn parse_constr_with_tag( + data: &PlutusData, + expected_tag: u32, +) -> Result<&Vec, PlutusDataError> { + let (tag, fields) = parse_constr(data)?; + + if tag != expected_tag { + Err(PlutusDataError::UnexpectedPlutusInvariant { + got: tag.to_string(), + wanted: format!("Constr with tag {}", expected_tag), + }) + } else { + Ok(fields) + } +} + +/// Given a PlutusData, parse it as PlutusData::List. Return the plutus data list. +/// +/// This function is used by the derive macro. +pub fn parse_list(data: &PlutusData) -> Result<&Vec, PlutusDataError> { + match data { + PlutusData::List(list_of_plutus_data) => Ok(list_of_plutus_data), + _ => Err(PlutusDataError::UnexpectedPlutusType { + got: PlutusType::from(data), + wanted: PlutusType::List, + }), + } +} diff --git a/plutus-data/src/is_plutus_data/instances.rs b/plutus-data/src/is_plutus_data/instances.rs new file mode 100644 index 0000000..5c7838a --- /dev/null +++ b/plutus-data/src/is_plutus_data/instances.rs @@ -0,0 +1,292 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use num_bigint::BigInt; + +use crate::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}; + +use super::aux::{parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, parse_list}; + +impl IsPlutusData for PlutusData { + fn to_plutus_data(&self) -> PlutusData { + self.clone() + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + Ok(plutus_data.clone()) + } +} + +// MARK: Orphan Instances + +impl IsPlutusData for BigInt { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Integer(self.clone()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Integer(int) => Ok(int.clone()), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Integer, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for Vec { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Bytes(self.clone()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Bytes(bytes) => Ok(bytes.clone()), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Bytes, + got: PlutusType::from(plutus_data), + }), + } + } +} + +const BOOL_FALSE_TAG: u32 = 0; +const BOOL_TRUE_TAG: u32 = 1; + +impl IsPlutusData for bool { + fn to_plutus_data(&self) -> PlutusData { + if *self { + PlutusData::Constr(BOOL_TRUE_TAG.into(), vec![]) + } else { + PlutusData::Constr(BOOL_FALSE_TAG.into(), vec![]) + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + match tag { + BOOL_TRUE_TAG => Ok(true), + BOOL_FALSE_TAG => Ok(false), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {BOOL_TRUE_TAG} or {BOOL_FALSE_TAG}"), + got: tag.to_string(), + }), + } + } +} + +impl IsPlutusData for String { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Bytes(self.as_bytes().into()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Bytes(bytes) => String::from_utf8(bytes.clone()).map_err(|err| { + PlutusDataError::InternalError(format!( + "Couldn't convert Plutus bytes to String: {:?}", + err + )) + }), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Bytes, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for char { + fn to_plutus_data(&self) -> PlutusData { + String::from(*self).to_plutus_data() + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + String::from_plutus_data(plutus_data).and_then(|str| { + let mut chars = str.chars(); + let ch = chars.next(); + let rest = chars.next(); + match (ch, rest) { + (Some(ch), None) => Ok(ch), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + got: "string".to_owned(), + wanted: "char".to_owned(), + }), + } + }) + } +} + +const OPTION_SOME_TAG: u32 = 0; +const OPTION_NONE_TAG: u32 = 1; + +impl IsPlutusData for Option +where + T: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + match self { + Some(val) => PlutusData::Constr(OPTION_SOME_TAG.into(), vec![val.to_plutus_data()]), + None => PlutusData::Constr(OPTION_NONE_TAG.into(), vec![]), + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + + match tag { + OPTION_SOME_TAG => { + let [data] = parse_fixed_len_constr_fields::<1>(fields)?; + Ok(Some(T::from_plutus_data(data)?)) + } + OPTION_NONE_TAG => { + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(None) + } + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {OPTION_SOME_TAG} or {OPTION_NONE_TAG}"), + got: tag.to_string(), + }), + } + } +} + +const RESULT_ERR_TAG: u32 = 0; +const RESULT_OK_TAG: u32 = 1; + +impl IsPlutusData for Result +where + T: IsPlutusData, + E: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + match self { + Err(err) => PlutusData::Constr(RESULT_ERR_TAG.into(), vec![err.to_plutus_data()]), + Ok(val) => PlutusData::Constr(RESULT_OK_TAG.into(), vec![val.to_plutus_data()]), + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + let [field] = parse_fixed_len_constr_fields::<1>(fields)?; + + match tag { + RESULT_ERR_TAG => Ok(Err(E::from_plutus_data(field)?)), + RESULT_OK_TAG => Ok(Ok(T::from_plutus_data(field)?)), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {RESULT_ERR_TAG} or {RESULT_OK_TAG}"), + got: tag.to_string(), + }), + } + } +} + +impl IsPlutusData for Vec +where + T: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + let values = self + .iter() + .map(|val| val.to_plutus_data()) + .collect::>(); + + PlutusData::List(values) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let list = parse_list(plutus_data)?; + list.iter().map(T::from_plutus_data).collect() + } +} + +impl IsPlutusData for BTreeSet +where + T: IsPlutusData + Eq + Ord, +{ + fn to_plutus_data(&self) -> PlutusData { + let set = self + .iter() + .map(|val| val.to_plutus_data()) + .collect::>(); + + PlutusData::List(set) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::List(vec) => vec + .iter() + .map(|val| T::from_plutus_data(val)) + .collect::>(), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::List, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for BTreeMap +where + K: IsPlutusData + Eq + Ord, + V: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + let assoc_map = self + .iter() + .map(|(key, val)| (key.to_plutus_data(), val.to_plutus_data())) + .collect::>(); + + PlutusData::Map(assoc_map) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Map(dict) => dict + .iter() + .map(|(key, val)| Ok((K::from_plutus_data(key)?, V::from_plutus_data(val)?))) + .collect::>(), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Map, + got: PlutusType::from(plutus_data), + }), + } + } +} + +const UNIT_TAG: u32 = 0; + +impl IsPlutusData for () { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Constr(UNIT_TAG.into(), vec![]) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let fields = parse_constr_with_tag(plutus_data, UNIT_TAG)?; + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(()) + } +} + +const PAIR_TAG: u32 = 0; + +impl IsPlutusData for (A, B) +where + A: IsPlutusData, + B: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Constr( + BigInt::from(PAIR_TAG), + vec![self.0.to_plutus_data(), self.1.to_plutus_data()], + ) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let fields = parse_constr_with_tag(plutus_data, PAIR_TAG)?; + let [a, b] = parse_fixed_len_constr_fields::<2>(fields)?; + Ok((A::from_plutus_data(a)?, B::from_plutus_data(b)?)) + } +} diff --git a/plutus-data/src/is_plutus_data/is_plutus_data.rs b/plutus-data/src/is_plutus_data/is_plutus_data.rs new file mode 100644 index 0000000..4f73c15 --- /dev/null +++ b/plutus-data/src/is_plutus_data/is_plutus_data.rs @@ -0,0 +1,22 @@ +use crate::{PlutusData, PlutusType}; + +pub trait IsPlutusData { + fn to_plutus_data(&self) -> PlutusData; + + fn from_plutus_data(plutus_data: &PlutusData) -> Result + where + Self: Sized; +} + +// TODO(chfanghr): improve error reporting +#[derive(Clone, Debug, thiserror::Error)] +pub enum PlutusDataError { + #[error("Expected a PlutusData type {wanted:?}, but got {got:?}")] + UnexpectedPlutusType { got: PlutusType, wanted: PlutusType }, + #[error("Expected a PlutusData type as {wanted:?}, but got {got:?}")] + UnexpectedPlutusInvariant { got: String, wanted: String }, + #[error("Expected a Plutus List with {wanted:?} elements, but got {got:?} elements")] + UnexpectedListLength { got: usize, wanted: usize }, + #[error("Some internal error happened: {0}")] + InternalError(String), +} diff --git a/plutus-data/src/is_plutus_data/mod.rs b/plutus-data/src/is_plutus_data/mod.rs new file mode 100644 index 0000000..526bebf --- /dev/null +++ b/plutus-data/src/is_plutus_data/mod.rs @@ -0,0 +1,3 @@ +pub mod aux; +mod instances; +pub mod is_plutus_data; diff --git a/plutus-data/src/lib.rs b/plutus-data/src/lib.rs new file mode 100644 index 0000000..c2c607a --- /dev/null +++ b/plutus-data/src/lib.rs @@ -0,0 +1,8 @@ +pub mod is_plutus_data; +pub mod plutus_data; + +#[cfg(feature = "derive")] +pub use is_plutus_data_derive::IsPlutusData; + +pub use is_plutus_data::is_plutus_data::{IsPlutusData, PlutusDataError}; +pub use plutus_data::{PlutusData, PlutusType}; diff --git a/plutus-data/src/plutus_data.rs b/plutus-data/src/plutus_data.rs new file mode 100644 index 0000000..9c3cbfc --- /dev/null +++ b/plutus-data/src/plutus_data.rs @@ -0,0 +1,183 @@ +use num_bigint::BigInt; + +#[cfg(feature = "lbf")] +use data_encoding::HEXLOWER; +#[cfg(feature = "lbf")] +use lbr_prelude::error::Error; +#[cfg(feature = "lbf")] +use lbr_prelude::json::{ + case_json_constructor, case_json_object, json_constructor, json_object, Json, +}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// Data representation of on-chain data such as Datums and Redeemers +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum PlutusData { + Constr(BigInt, Vec), + Map(Vec<(PlutusData, PlutusData)>), + List(Vec), + Integer(BigInt), + Bytes(Vec), +} + +#[derive(Clone, Debug)] +pub enum PlutusType { + Constr, + Map, + List, + Integer, + Bytes, +} + +impl From<&PlutusData> for PlutusType { + fn from(plutus_data: &PlutusData) -> Self { + match plutus_data { + PlutusData::Constr(_, _) => PlutusType::Constr, + PlutusData::Map(_) => PlutusType::Map, + PlutusData::List(_) => PlutusType::List, + PlutusData::Integer(_) => PlutusType::Integer, + PlutusData::Bytes(_) => PlutusType::Bytes, + } + } +} + +impl PlutusData { + pub fn constr(tag: u32, fields: Vec) -> Self { + PlutusData::Constr(BigInt::from(tag), fields) + } + + pub fn map(fields: Vec<(PlutusData, PlutusData)>) -> Self { + PlutusData::Map(fields) + } + + pub fn list(fields: Vec) -> Self { + PlutusData::List(fields) + } + + pub fn integer(value: u32) -> Self { + PlutusData::Integer(BigInt::from(value)) + } + + pub fn bytes(value: Vec) -> Self { + PlutusData::Bytes(value) + } +} + +#[cfg(feature = "lbf")] +impl Json for PlutusData { + fn to_json(&self) -> serde_json::Value { + match self { + PlutusData::Constr(index, fields) => json_constructor( + "Constr", + vec![json_object(vec![ + ("index".to_string(), index.to_json()), + ("fields".to_string(), fields.to_json()), + ])], + ), + PlutusData::Map(map) => json_constructor("Map", vec![map.to_json()]), + PlutusData::List(list) => json_constructor("List", vec![list.to_json()]), + PlutusData::Integer(int) => json_constructor("Integer", vec![int.to_json()]), + PlutusData::Bytes(bytes) => { + json_constructor("Bytes", vec![String::to_json(&HEXLOWER.encode(bytes))]) + } + } + } + + fn from_json(value: &serde_json::Value) -> Result { + case_json_constructor( + "PlutusV1.PlutusData", + vec![ + ( + "Constr", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => case_json_object( + |obj| { + let index = obj.get("index").ok_or(Error::UnexpectedFieldName { + wanted: "index".to_owned(), + got: obj.keys().cloned().collect(), + parser: "PlutusV1.PlutusData".to_owned(), + })?; + + let fields = + obj.get("fields").ok_or(Error::UnexpectedFieldName { + wanted: "fields".to_owned(), + got: obj.keys().cloned().collect(), + parser: "PlutusV1.PlutusData".to_owned(), + })?; + Ok(PlutusData::Constr( + BigInt::from_json(index)?, + >::from_json(fields)?, + )) + }, + val, + ), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Map", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::Map(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "List", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::List(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Integer", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::Integer(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Bytes", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => { + let bytes = String::from_json(val).and_then(|str| { + HEXLOWER.decode(&str.into_bytes()).map_err(|_| { + Error::UnexpectedJsonInvariant { + wanted: "base16 string".to_owned(), + got: "unexpected string".to_owned(), + parser: "Plutus.V1.Bytes".to_owned(), + } + }) + })?; + Ok(PlutusData::Bytes(bytes)) + } + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ], + value, + ) + } +} From 1a7c261b20bc83595921b0a564e27cdbf96ce7c2 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Thu, 17 Oct 2024 23:58:01 +0800 Subject: [PATCH 11/38] lower version requirement of proc-macro2 --- is-plutus-data-derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/is-plutus-data-derive/Cargo.toml b/is-plutus-data-derive/Cargo.toml index acaf07f..770f519 100644 --- a/is-plutus-data-derive/Cargo.toml +++ b/is-plutus-data-derive/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -proc-macro2 = "1.0.87" +proc-macro2 = "^1.0.66" quote = "1.0.37" syn = { version = "2.0.79", features = ["full", "extra-traits"]} thiserror = "1.0.64" From 167395f67add825645763208fece00bfb545e4d4 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 00:02:29 +0800 Subject: [PATCH 12/38] `plutus_data_derive_strategy` -> `is_plutus_data_derive_strategy` --- is-plutus-data-derive/src/derive_impl.rs | 2 +- is-plutus-data-derive/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs index 35fc5e5..b40bc6f 100644 --- a/is-plutus-data-derive/src/derive_impl.rs +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -96,7 +96,7 @@ fn try_parse_derive_strategy(attr: &Attribute) -> Option> let value = match &attr.meta { Meta::NameValue(name_value) => name_value .path - .is_ident("plutus_data_derive_strategy") + .is_ident("is_plutus_data_derive_strategy") .then_some(&name_value.value), _ => None, }?; diff --git a/is-plutus-data-derive/src/lib.rs b/is-plutus-data-derive/src/lib.rs index 4e54429..2ba5263 100644 --- a/is-plutus-data-derive/src/lib.rs +++ b/is-plutus-data-derive/src/lib.rs @@ -3,7 +3,7 @@ use syn::{parse_macro_input, DeriveInput}; pub(crate) mod derive_impl; -#[proc_macro_derive(IsPlutusData, attributes(plutus_data_derive_strategy))] +#[proc_macro_derive(IsPlutusData, attributes(is_plutus_data_derive_strategy))] pub fn derive_is_plutus_data(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); derive_impl::get_is_plutus_data_instance(input) From 4d5a08b2b41e7cc96d863b7368aa3fd9e1bde053 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 00:03:58 +0800 Subject: [PATCH 13/38] fix `parse_fixed_len_plutus_data_list` not in scope --- is-plutus-data-derive/src/derive_impl.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs index b40bc6f..51f483f 100644 --- a/is-plutus-data-derive/src/derive_impl.rs +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -647,7 +647,7 @@ fn data_with_named_fields_from_list_of_plutus_data( parse_quote!( { - let [ #(#unparsed_field_idents),* ] = parse_fixed_len_plutus_data_list::<#field_count>(#plutus_data_list_var)?; + let [ #(#unparsed_field_idents),* ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; #(#field_decoded_stmts)* Ok(#constructor{ #(#field_idents),* }) } @@ -677,7 +677,7 @@ fn data_with_unnamed_fields_from_list_of_plutus_data( }); parse_quote!({ - let [ #(#unparsed_field_idents),* ] = parse_fixed_len_plutus_data_list::<#field_count>(#plutus_data_list_var)?; + let [ #(#unparsed_field_idents),* ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; #(#field_decoded_stmts)* Ok(#constructor(#(#parsed_field_idents),*)) }) @@ -688,7 +688,7 @@ fn data_with_no_fields_from_list_of_plutus_data( list_of_plutus_data_var: &Ident, ) -> Block { parse_quote!({ - let [ ] = parse_fixed_len_plutus_data_list::<0>(#list_of_plutus_data_var)?; + let [ ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<0>(#list_of_plutus_data_var)?; Ok(#constructor) }) } From 001c5588fe19d36e3bc89d4e52b388cf25626973 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 00:35:51 +0800 Subject: [PATCH 14/38] attribute value can only be literal --- is-plutus-data-derive/src/derive_impl.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs index 51f483f..0b0886c 100644 --- a/is-plutus-data-derive/src/derive_impl.rs +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -5,8 +5,8 @@ use syn::{ parse::{Parse, ParseStream}, parse_quote, spanned::Spanned, - Arm, Attribute, Block, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, Fields, - FieldsNamed, FieldsUnnamed, Ident, Index, ItemImpl, Meta, Path, Result, Stmt, + Arm, Attribute, Block, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, ExprLit, Fields, + FieldsNamed, FieldsUnnamed, Ident, Index, ItemImpl, Lit, Meta, Path, Result, Stmt, }; pub(crate) fn get_is_plutus_data_instance(input: DeriveInput) -> Result { @@ -56,7 +56,7 @@ enum DeriveStrategy { enum DeriveStrategyError { #[error("Unknown strategy {0}. Should be one of Newtype, List and Constr.")] UnknownStrategy(String), - #[error("Unable to parse strategy. Should be an Ident.")] + #[error("Unable to parse strategy. Should be a string literal Newtype, Constr or List.")] UnexpectedToken, #[error("More than one strategies specified.")] MoreThanOneSpecified, @@ -102,10 +102,11 @@ fn try_parse_derive_strategy(attr: &Attribute) -> Option> }?; Some(match &value { - Expr::Path(path) => (|| -> Result { - let ident = path.path.require_ident()?; - DeriveStrategy::from_str(&ident.to_string()) - .map_err(|err| Error::new(ident.span(), err)) + Expr::Lit(ExprLit { + lit: Lit::Str(str_lit), + .. + }) => (|| -> Result { + DeriveStrategy::from_str(&str_lit.value()).map_err(|err| Error::new(attr.span(), err)) })(), _ => Err(Error::new( value.span(), From c7812dd13805183e5b9b733712514a175add7d26 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 01:03:38 +0800 Subject: [PATCH 15/38] derive the shit out of it --- plutus-ledger-api/Cargo.lock | 24 + plutus-ledger-api/Cargo.toml | 5 +- plutus-ledger-api/build.nix | 4 + plutus-ledger-api/src/plutus_data.rs | 608 +----------------------- plutus-ledger-api/src/v1/address.rs | 169 ++----- plutus-ledger-api/src/v1/crypto.rs | 89 +--- plutus-ledger-api/src/v1/datum.rs | 28 +- plutus-ledger-api/src/v1/interval.rs | 127 ++--- plutus-ledger-api/src/v1/redeemer.rs | 28 +- plutus-ledger-api/src/v1/script.rs | 41 +- plutus-ledger-api/src/v1/transaction.rs | 325 +------------ plutus-ledger-api/src/v1/value.rs | 41 +- plutus-ledger-api/src/v2/datum.rs | 51 +- plutus-ledger-api/src/v2/transaction.rs | 150 +----- 14 files changed, 155 insertions(+), 1535 deletions(-) diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 17e1f90..e2f7fa2 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -398,6 +398,16 @@ dependencies = [ "hashbrown 0.15.0", ] +[[package]] +name = "is-plutus-data-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "thiserror", +] + [[package]] name = "itertools" version = "0.10.5" @@ -598,6 +608,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "plutus-data" +version = "0.1.0" +dependencies = [ + "data-encoding", + "is-plutus-data-derive", + "lbr-prelude", + "num-bigint", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "plutus-ledger-api" version = "2.0.0-beta.1" @@ -612,6 +635,7 @@ dependencies = [ "linked-hash-map", "num-bigint", "num-traits", + "plutus-data", "proptest", "serde", "serde_json", diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index 66411b0..d09b07f 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -23,11 +23,12 @@ impl_ops = "0.1.1" chrono = { version = "0.4.34", optional = true } cardano-serialization-lib = "12.1.0" anyhow = "1.0.86" +plutus-data = { path = ".extras/plutus-data-0", features = [ "derive" ]} [features] default = [] -serde = ["dep:serde", "num-bigint/serde", "dep:serde_json"] -lbf = ["dep:lbr-prelude", "dep:serde_json"] +serde = ["dep:serde", "num-bigint/serde", "dep:serde_json", "plutus-data/serde"] +lbf = ["dep:lbr-prelude", "dep:serde_json", "plutus-data/lbf"] chrono = ["dep:chrono"] [dev-dependencies] diff --git a/plutus-ledger-api/build.nix b/plutus-ledger-api/build.nix index c4ad5db..4fa2517 100644 --- a/plutus-ledger-api/build.nix +++ b/plutus-ledger-api/build.nix @@ -11,6 +11,10 @@ extraSourceFilters = [ (path: _type: builtins.match ".*golden$" path != null) ]; + extraSources = [ + config.packages.is-plutus-data-derive-rust-src + config.packages.plutus-data-rust-src + ]; }; plutus-ledger-api-rust-github-pages = pkgs.stdenv.mkDerivation { diff --git a/plutus-ledger-api/src/plutus_data.rs b/plutus-ledger-api/src/plutus_data.rs index 8329704..e446ed7 100644 --- a/plutus-ledger-api/src/plutus_data.rs +++ b/plutus-ledger-api/src/plutus_data.rs @@ -1,170 +1,13 @@ //! Plutus Data related types and traits use cardano_serialization_lib as csl; -#[cfg(feature = "lbf")] -use data_encoding::HEXLOWER; -#[cfg(feature = "lbf")] -use lbr_prelude::error::Error; -#[cfg(feature = "lbf")] -use lbr_prelude::json::{ - case_json_constructor, case_json_object, json_constructor, json_object, Json, -}; use num_bigint::BigInt; -use std::collections::{BTreeMap, BTreeSet}; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -/// Data representation of on-chain data such as Datums and Redeemers -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum PlutusData { - Constr(BigInt, Vec), - Map(Vec<(PlutusData, PlutusData)>), - List(Vec), - Integer(BigInt), - Bytes(Vec), -} - -impl PlutusData { - pub fn constr(tag: u32, fields: Vec) -> Self { - PlutusData::Constr(BigInt::from(tag), fields) - } - - pub fn map(fields: Vec<(PlutusData, PlutusData)>) -> Self { - PlutusData::Map(fields) - } - - pub fn list(fields: Vec) -> Self { - PlutusData::List(fields) - } - - pub fn integer(value: u32) -> Self { - PlutusData::Integer(BigInt::from(value)) - } - - pub fn bytes(value: Vec) -> Self { - PlutusData::Bytes(value) - } -} - -#[cfg(feature = "lbf")] -impl Json for PlutusData { - fn to_json(&self) -> serde_json::Value { - match self { - PlutusData::Constr(index, fields) => json_constructor( - "Constr", - vec![json_object(vec![ - ("index".to_string(), index.to_json()), - ("fields".to_string(), fields.to_json()), - ])], - ), - PlutusData::Map(map) => json_constructor("Map", vec![map.to_json()]), - PlutusData::List(list) => json_constructor("List", vec![list.to_json()]), - PlutusData::Integer(int) => json_constructor("Integer", vec![int.to_json()]), - PlutusData::Bytes(bytes) => { - json_constructor("Bytes", vec![String::to_json(&HEXLOWER.encode(bytes))]) - } - } - } - - fn from_json(value: &serde_json::Value) -> Result { - case_json_constructor( - "PlutusV1.PlutusData", - vec![ - ( - "Constr", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => case_json_object( - |obj| { - let index = obj.get("index").ok_or(Error::UnexpectedFieldName { - wanted: "index".to_owned(), - got: obj.keys().cloned().collect(), - parser: "PlutusV1.PlutusData".to_owned(), - })?; - - let fields = - obj.get("fields").ok_or(Error::UnexpectedFieldName { - wanted: "fields".to_owned(), - got: obj.keys().cloned().collect(), - parser: "PlutusV1.PlutusData".to_owned(), - })?; - Ok(PlutusData::Constr( - BigInt::from_json(index)?, - >::from_json(fields)?, - )) - }, - val, - ), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Map", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::Map(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "List", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::List(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Integer", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::Integer(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Bytes", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => { - let bytes = String::from_json(val).and_then(|str| { - HEXLOWER.decode(&str.into_bytes()).map_err(|_| { - Error::UnexpectedJsonInvariant { - wanted: "base16 string".to_owned(), - got: "unexpected string".to_owned(), - parser: "Plutus.V1.Bytes".to_owned(), - } - }) - })?; - Ok(PlutusData::Bytes(bytes)) - } - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ], - value, - ) - } -} +pub use plutus_data::{ + is_plutus_data::aux::*, IsPlutusData, PlutusData, PlutusDataError, PlutusType, +}; /// Deserialise a Plutus data using parsers for each variant pub fn case_plutus_data<'a, T>( @@ -175,386 +18,10 @@ pub fn case_plutus_data<'a, T>( pd: &'a PlutusData, ) -> T { match pd { - PlutusData::Constr(tag, args) => ctor_case(tag)(args), - PlutusData::List(args) => list_case(args), - PlutusData::Integer(i) => int_case(i), - other => other_case(other), - } -} - -pub trait IsPlutusData { - fn to_plutus_data(&self) -> PlutusData; - - fn from_plutus_data(plutus_data: &PlutusData) -> Result - where - Self: Sized; -} - -#[derive(Clone, Debug)] -pub enum PlutusType { - Constr, - Map, - List, - Integer, - Bytes, -} - -impl From<&PlutusData> for PlutusType { - fn from(plutus_data: &PlutusData) -> Self { - match plutus_data { - PlutusData::Constr(_, _) => PlutusType::Constr, - PlutusData::Map(_) => PlutusType::Map, - PlutusData::List(_) => PlutusType::List, - PlutusData::Integer(_) => PlutusType::Integer, - PlutusData::Bytes(_) => PlutusType::Bytes, - } - } -} - -#[derive(Clone, Debug, thiserror::Error)] -pub enum PlutusDataError { - #[error("Expected a PlutusData type {wanted:?}, but got {got:?}")] - UnexpectedPlutusType { got: PlutusType, wanted: PlutusType }, - #[error("Expected a PlutusData type as {wanted:?}, but got {got:?}")] - UnexpectedPlutusInvariant { got: String, wanted: String }, - #[error("Expected a Plutus List with {wanted:?} elements, but got {got:?} elements")] - UnexpectedListLength { got: usize, wanted: usize }, - #[error("Some internal error happened: {0}")] - InternalError(String), -} - -impl IsPlutusData for BigInt { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Integer(self.clone()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Integer(int) => Ok(int.clone()), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Integer, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for bool { - fn to_plutus_data(&self) -> PlutusData { - if *self { - PlutusData::Constr(BigInt::from(1), Vec::with_capacity(0)) - } else { - PlutusData::Constr(BigInt::from(0), Vec::with_capacity(0)) - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 0)?; - Ok(false) - } - Ok(1) => { - verify_constr_fields(fields, 0)?; - Ok(true) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for char { - fn to_plutus_data(&self) -> PlutusData { - String::from(*self).to_plutus_data() - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - String::from_plutus_data(plutus_data).and_then(|str| { - let mut chars = str.chars(); - let ch = chars.next(); - let rest = chars.next(); - match (ch, rest) { - (Some(ch), None) => Ok(ch), - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - got: "string".to_owned(), - wanted: "char".to_owned(), - }), - } - }) - } -} - -impl IsPlutusData for Vec { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Bytes(self.clone()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Bytes(bytes) => Ok(bytes.clone()), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for String { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Bytes(self.as_bytes().into()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Bytes(bytes) => String::from_utf8(bytes.clone()).map_err(|err| { - PlutusDataError::InternalError(format!( - "Couldn't convert Plutus bytes to String: {:?}", - err - )) - }), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Integer, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for Option -where - T: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - match self { - Some(val) => PlutusData::Constr(BigInt::from(0), vec![val.to_plutus_data()]), - None => PlutusData::Constr(BigInt::from(1), Vec::with_capacity(0)), - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 1)?; - Ok(Some(T::from_plutus_data(&fields[0])?)) - } - Ok(1) => { - verify_constr_fields(fields, 0)?; - Ok(None) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for Result -where - T: IsPlutusData, - E: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - match self { - Err(val) => PlutusData::Constr(BigInt::from(0), vec![val.to_plutus_data()]), - Ok(val) => PlutusData::Constr(BigInt::from(1), vec![val.to_plutus_data()]), - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 1)?; - Ok(Err(E::from_plutus_data(&fields[0])?)) - } - Ok(1) => { - verify_constr_fields(fields, 1)?; - Ok(Ok(T::from_plutus_data(&fields[0])?)) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for Vec -where - T: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - let values = self - .iter() - .map(|val| val.to_plutus_data()) - .collect::>(); - - PlutusData::List(values) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::List(vec) => vec - .iter() - .map(|val| T::from_plutus_data(val)) - .collect::, PlutusDataError>>(), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::List, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for BTreeSet -where - T: IsPlutusData + Eq + Ord, -{ - fn to_plutus_data(&self) -> PlutusData { - let set = self - .iter() - .map(|val| val.to_plutus_data()) - .collect::>(); - - PlutusData::List(set) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::List(vec) => vec - .iter() - .map(|val| T::from_plutus_data(val)) - .collect::>(), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Map, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for BTreeMap -where - K: IsPlutusData + Eq + Ord, - V: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - let assoc_map = self - .iter() - .map(|(key, val)| (key.to_plutus_data(), val.to_plutus_data())) - .collect::>(); - - PlutusData::Map(assoc_map) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Map(dict) => dict - .iter() - .map(|(key, val)| Ok((K::from_plutus_data(key)?, V::from_plutus_data(val)?))) - .collect::>(), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Map, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for () { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr(BigInt::from(0), Vec::with_capacity(0)) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 0)?; - Ok(()) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for PlutusData { - fn to_plutus_data(&self) -> PlutusData { - self.clone() - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - Ok(plutus_data.clone()) - } -} - -impl IsPlutusData for (A, B) -where - A: IsPlutusData, - B: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![self.0.to_plutus_data(), self.1.to_plutus_data()], - ) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(( - A::from_plutus_data(&fields[0])?, - B::from_plutus_data(&fields[1])?, - )) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(plutus_data), - }), - } + PlutusData::Constr(tag, args) => ctor_case(&tag)(&args), + PlutusData::List(args) => list_case(&args), + PlutusData::Integer(i) => int_case(&i), + other => other_case(&other), } } @@ -642,64 +109,3 @@ impl TryFromPLA> for csl::PlutusMap { }) } } - -/// Verify the number of fields contained in a PlutusData::Constr -pub fn verify_constr_fields( - fields: &Vec, - expected: usize, -) -> Result<(), PlutusDataError> { - if fields.len() != expected { - Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: format!("Constr with {} fields", expected), - got: format!("{:?}", fields), - }) - } else { - Ok(()) - } -} - -/// Given a vector of PlutusData, parse it as an array whose length is known at -/// compile time. -pub fn parse_fixed_len_constr_fields( - v: &[PlutusData], -) -> Result<&[PlutusData; LEN], PlutusDataError> { - v.try_into() - .map_err(|_| PlutusDataError::UnexpectedListLength { - got: v.len(), - wanted: LEN, - }) -} - -/// Given a PlutusData, parse it as PlutusData::Constr and its tag as u32. Return -/// the u32 tag and fields. -pub fn parse_constr(data: &PlutusData) -> Result<(u32, &Vec), PlutusDataError> { - match data { - PlutusData::Constr(tag, fields) => u32::try_from(tag) - .map_err(|err| PlutusDataError::UnexpectedPlutusInvariant { - got: err.to_string(), - wanted: "Constr bigint tag within u32 range".into(), - }) - .map(|tag| (tag, fields)), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } -} - -/// Given a PlutusData, parse it as PlutusData::Constr and verify its tag. -pub fn parse_constr_with_tag( - data: &PlutusData, - expected_tag: u32, -) -> Result<&Vec, PlutusDataError> { - let (tag, fields) = parse_constr(data)?; - - if tag != expected_tag { - Err(PlutusDataError::UnexpectedPlutusInvariant { - got: tag.to_string(), - wanted: format!("Constr tag to be: {}", expected_tag), - }) - } else { - Ok(fields) - } -} diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index b80677f..9230518 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -3,12 +3,11 @@ use std::str::FromStr; use anyhow::anyhow; use cardano_serialization_lib as csl; +use plutus_data::is_plutus_data::aux::{parse_constr, parse_fixed_len_constr_fields}; use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, -}; +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; use crate::v1::crypto::Ed25519PubKeyHash; use crate::v1::script::ValidatorHash; #[cfg(feature = "lbf")] @@ -27,7 +26,7 @@ use serde::{Deserialize, Serialize}; /// An address consists of a payment part (credential) and a delegation part (staking_credential). /// In order to serialize an address to `bech32`, the network kind must be known. /// For a better understanding of all the Cardano address types, read [CIP 19](https://cips.cardano.org/cips/cip19/) -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Address { @@ -44,43 +43,6 @@ impl Address { } } -impl IsPlutusData for Address { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.credential.to_plutus_data(), - self.staking_credential.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(Address { - credential: Credential::from_plutus_data(&fields[0])?, - staking_credential: >::from_plutus_data( - &fields[1], - )?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - impl FromStr for Address { type Err = anyhow::Error; @@ -162,54 +124,13 @@ impl std::fmt::Display for AddressWithExtraInfo<'_> { //////////////// /// A public key hash or validator hash credential (used as a payment or a staking credential) -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Credential { PubKey(Ed25519PubKeyHash), Script(ValidatorHash), } -impl IsPlutusData for Credential { - fn to_plutus_data(&self) -> PlutusData { - match self { - Credential::PubKey(pkh) => { - PlutusData::Constr(BigInt::from(0), vec![pkh.to_plutus_data()]) - } - Credential::Script(val_hash) => { - PlutusData::Constr(BigInt::from(1), vec![val_hash.to_plutus_data()]) - } - } - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 1)?; - Ok(Credential::PubKey(Ed25519PubKeyHash::from_plutus_data( - &fields[0], - )?)) - } - Ok(1) => { - verify_constr_fields(fields, 1)?; - Ok(Credential::Script(ValidatorHash::from_plutus_data( - &fields[0], - )?)) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - #[cfg(feature = "lbf")] impl Json for Credential { fn to_json(&self) -> serde_json::Value { @@ -289,6 +210,7 @@ pub enum StakingCredential { Pointer(ChainPointer), } +// NOTE(chfanghr): ChainPointer doesn't have a IsPlutusData instance so derive doesn't work here. impl IsPlutusData for StakingCredential { fn to_plutus_data(&self) -> PlutusData { match self { @@ -311,31 +233,23 @@ impl IsPlutusData for StakingCredential { } fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 1)?; - Ok(StakingCredential::Hash(Credential::from_plutus_data( - &fields[0], - )?)) - } - Ok(1) => { - verify_constr_fields(fields, 3)?; - Ok(StakingCredential::Pointer(ChainPointer { - slot_number: Slot::from_plutus_data(&fields[0])?, - transaction_index: TransactionIndex::from_plutus_data(&fields[1])?, - certificate_index: CertificateIndex::from_plutus_data(&fields[2])?, - })) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), + let (tag, fields) = parse_constr(data)?; + match tag { + 0 => { + let [field] = parse_fixed_len_constr_fields::<1>(fields)?; + Ok(Self::Hash(Credential::from_plutus_data(field)?)) + } + 1 => { + let [field_0, field_1, field_2] = parse_fixed_len_constr_fields::<3>(fields)?; + Ok(Self::Pointer(ChainPointer { + slot_number: Slot::from_plutus_data(field_0)?, + transaction_index: TransactionIndex::from_plutus_data(field_1)?, + certificate_index: CertificateIndex::from_plutus_data(field_2)?, + })) + } + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: "Constr with tag 0 or 1".to_owned(), + got: tag.to_string(), }), } } @@ -467,21 +381,12 @@ impl TryFromPLA for csl::Pointer { ////////// /// Number of slots elapsed since genesis -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Slot(pub BigInt); -impl IsPlutusData for Slot { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for Slot { fn from_csl(value: &csl::BigNum) -> Self { Slot(BigInt::from_csl(value)) @@ -499,21 +404,12 @@ impl TryFromPLA for csl::BigNum { ////////////////////// /// Position of the certificate in a certain transaction -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct CertificateIndex(pub BigInt); -impl IsPlutusData for CertificateIndex { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for CertificateIndex { fn from_csl(value: &csl::BigNum) -> Self { CertificateIndex(BigInt::from_csl(value)) @@ -532,21 +428,12 @@ impl TryFromPLA for csl::BigNum { /// Position of a transaction in a given slot /// This is not identical to the index of a `TransactionInput` -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionIndex(pub BigInt); -impl IsPlutusData for TransactionIndex { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for TransactionIndex { fn from_csl(value: &csl::BigNum) -> Self { TransactionIndex(BigInt::from_csl(value)) diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index 4517dd6..4555ff9 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -3,15 +3,13 @@ use cardano_serialization_lib as csl; use data_encoding::HEXLOWER; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json}; +use plutus_data::IsPlutusData; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{ - csl::{ - csl_to_pla::FromCSL, - pla_to_csl::{TryFromPLA, TryFromPLAError}, - }, - plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}, +use crate::csl::{ + csl_to_pla::FromCSL, + pla_to_csl::{TryFromPLA, TryFromPLAError}, }; /////////////////////// @@ -21,28 +19,12 @@ use crate::{ /// ED25519 public key hash /// This is the standard cryptography in Cardano, commonly referred to as `PubKeyHash` in Plutus /// and other libraries -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Ed25519PubKeyHash(pub LedgerBytes); -impl IsPlutusData for Ed25519PubKeyHash { - fn to_plutus_data(&self) -> PlutusData { - let Ed25519PubKeyHash(LedgerBytes(bytes)) = self; - PlutusData::Bytes(bytes.clone()) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Bytes(bytes) => Ok(Self(LedgerBytes(bytes.clone()))), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(data), - }), - } - } -} - impl FromCSL for Ed25519PubKeyHash { fn from_csl(value: &csl::Ed25519KeyHash) -> Self { Ed25519PubKeyHash(LedgerBytes(value.to_bytes())) @@ -69,61 +51,30 @@ impl FromCSL for Vec { /////////////////////// /// Standard public key hash used to verify a transaction witness -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct PaymentPubKeyHash(pub Ed25519PubKeyHash); -impl IsPlutusData for PaymentPubKeyHash { - fn to_plutus_data(&self) -> PlutusData { - let PaymentPubKeyHash(Ed25519PubKeyHash(LedgerBytes(bytes))) = self; - PlutusData::Bytes(bytes.clone()) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Bytes(bytes) => Ok(Self(Ed25519PubKeyHash(LedgerBytes(bytes.clone())))), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(data), - }), - } - } -} - ///////////////////// // StakePubKeyHash // ///////////////////// /// Standard public key hash used to verify a staking -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct StakePubKeyHash(pub Ed25519PubKeyHash); -impl IsPlutusData for StakePubKeyHash { - fn to_plutus_data(&self) -> PlutusData { - let StakePubKeyHash(Ed25519PubKeyHash(LedgerBytes(bytes))) = self; - PlutusData::Bytes(bytes.clone()) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Bytes(bytes) => Ok(Self(Ed25519PubKeyHash(LedgerBytes(bytes.clone())))), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(data), - }), - } - } -} - ///////////////// // LedgerBytes // ///////////////// /// A bytestring in the Cardano ledger context -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LedgerBytes(pub Vec); @@ -139,22 +90,6 @@ impl std::fmt::Display for LedgerBytes { } } -impl IsPlutusData for LedgerBytes { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Bytes(self.0.clone()) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Bytes(bytes) => Ok(Self(bytes.clone())), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(data), - }), - } - } -} - #[cfg(feature = "lbf")] impl Json for LedgerBytes { fn to_json(&self) -> serde_json::Value { diff --git a/plutus-ledger-api/src/v1/datum.rs b/plutus-ledger-api/src/v1/datum.rs index eba5f64..49901ab 100644 --- a/plutus-ledger-api/src/v1/datum.rs +++ b/plutus-ledger-api/src/v1/datum.rs @@ -4,7 +4,7 @@ use cardano_serialization_lib as csl; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::plutus_data::{IsPlutusData, PlutusData}; use crate::v1::crypto::LedgerBytes; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; @@ -17,21 +17,12 @@ use serde::{Deserialize, Serialize}; /////////////// /// blake2b-256 hash of a datum -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DatumHash(pub LedgerBytes); -impl IsPlutusData for DatumHash { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for DatumHash { fn from_csl(value: &csl::DataHash) -> Self { DatumHash(LedgerBytes(value.to_bytes())) @@ -49,21 +40,12 @@ impl TryFromPLA for csl::DataHash { /////////// /// Piece of information associated with a UTxO encoded into a PlutusData type. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Datum(pub PlutusData); -impl IsPlutusData for Datum { - fn to_plutus_data(&self) -> PlutusData { - self.0.clone() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl TryFromPLA for csl::PlutusData { fn try_from_pla(val: &Datum) -> Result { val.0.try_to_csl() diff --git a/plutus-ledger-api/src/v1/interval.rs b/plutus-ledger-api/src/v1/interval.rs index 399e64a..eb78927 100644 --- a/plutus-ledger-api/src/v1/interval.rs +++ b/plutus-ledger-api/src/v1/interval.rs @@ -1,11 +1,12 @@ //! Types related to PlutusInterval use crate::feature_traits::FeatureTraits; -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, -}; +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; use num_bigint::BigInt; +use plutus_data::is_plutus_data::aux::{ + parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, +}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::cmp; @@ -268,26 +269,12 @@ where } fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(PlutusInterval { - from: >::from_plutus_data(&fields[0])?, - to: >::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } + let fields = parse_constr_with_tag(data, 0)?; + let [field_0, field_1] = parse_fixed_len_constr_fields::<2>(fields)?; + Ok(Self { + from: IsPlutusData::from_plutus_data(field_0)?, + to: IsPlutusData::from_plutus_data(field_1)?, + }) } } @@ -318,26 +305,12 @@ where } fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(UpperBound { - bound: >::from_plutus_data(&fields[0])?, - closed: bool::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } + let fields = parse_constr_with_tag(data, 0)?; + let [field_0, field_1] = parse_fixed_len_constr_fields::<2>(fields)?; + Ok(Self { + bound: IsPlutusData::from_plutus_data(field_0)?, + closed: IsPlutusData::from_plutus_data(field_1)?, + }) } } @@ -368,26 +341,12 @@ where } fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(LowerBound { - bound: >::from_plutus_data(&fields[0])?, - closed: bool::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } + let fields = parse_constr_with_tag(data, 0)?; + let [field_0, field_1] = parse_fixed_len_constr_fields::<2>(fields)?; + Ok(Self { + bound: IsPlutusData::from_plutus_data(field_0)?, + closed: IsPlutusData::from_plutus_data(field_1)?, + }) } } @@ -465,31 +424,23 @@ where } fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 0)?; - Ok(Extended::NegInf) - } - Ok(1) => { - verify_constr_fields(fields, 1)?; - Ok(Extended::Finite(IsPlutusData::from_plutus_data( - &fields[0], - )?)) - } - Ok(2) => { - verify_constr_fields(fields, 0)?; - Ok(Extended::PosInf) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), + let (tag, fields) = parse_constr(data)?; + match tag { + 0 => { + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(Extended::NegInf) + } + 1 => { + let [field] = parse_fixed_len_constr_fields::<1>(fields)?; + Ok(Extended::Finite(IsPlutusData::from_plutus_data(field)?)) + } + 2 => { + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(Extended::PosInf) + } + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: "Constr with tag 0, 1 or 2".to_owned(), + got: tag.to_string(), }), } } diff --git a/plutus-ledger-api/src/v1/redeemer.rs b/plutus-ledger-api/src/v1/redeemer.rs index 95ffa9c..c46e39a 100644 --- a/plutus-ledger-api/src/v1/redeemer.rs +++ b/plutus-ledger-api/src/v1/redeemer.rs @@ -8,7 +8,7 @@ use lbr_prelude::json::Json; use serde::{Deserialize, Serialize}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::plutus_data::{IsPlutusData, PlutusData}; use crate::v1::crypto::LedgerBytes; ////////////// @@ -17,21 +17,12 @@ use crate::v1::crypto::LedgerBytes; /// Piece of information attached to a transaction when redeeming a value from a validator or a /// minting policy -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Redeemer(pub PlutusData); -impl IsPlutusData for Redeemer { - fn to_plutus_data(&self) -> PlutusData { - self.0.clone() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - #[derive(Clone, Debug)] pub struct RedeemerWithExtraInfo<'a> { pub redeemer: &'a Redeemer, @@ -56,17 +47,8 @@ impl TryFromPLA> for csl::Redeemer { ////////////////// /// blake2b-256 hash of a datum -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "lbf", derive(Json))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RedeemerHash(pub LedgerBytes); - -impl IsPlutusData for RedeemerHash { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index ddfcb89..5afcf2a 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::plutus_data::IsPlutusData; use crate::v1::crypto::LedgerBytes; /////////////////// @@ -17,21 +17,12 @@ use crate::v1::crypto::LedgerBytes; /////////////////// /// Identifier of a validator script -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ValidatorHash(pub ScriptHash); -impl IsPlutusData for ValidatorHash { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for ValidatorHash { fn from_csl(value: &csl::ScriptHash) -> Self { ValidatorHash(ScriptHash::from_csl(value)) @@ -43,21 +34,12 @@ impl FromCSL for ValidatorHash { /////////////////////// /// Hash of a minting policy script -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct MintingPolicyHash(pub ScriptHash); -impl IsPlutusData for MintingPolicyHash { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for MintingPolicyHash { fn from_csl(value: &csl::PolicyID) -> Self { MintingPolicyHash(ScriptHash(LedgerBytes(value.to_bytes()))) @@ -75,21 +57,12 @@ impl TryFromPLA for csl::PolicyID { //////////////// /// Hash of a Plutus script -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptHash(pub LedgerBytes); -impl IsPlutusData for ScriptHash { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - impl FromCSL for ScriptHash { fn from_csl(value: &csl::ScriptHash) -> Self { ScriptHash(LedgerBytes(value.to_bytes())) diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 54fcff0..efe574b 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -16,16 +16,10 @@ use super::{ value::{CurrencySymbol, Value}, }; +use crate::csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}; use crate::{ csl::pla_to_csl::{TryFromPLAError, TryToCSL}, - plutus_data::{ - parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, verify_constr_fields, - IsPlutusData, PlutusData, PlutusDataError, PlutusType, - }, -}; -use crate::{ - csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}, - utils::aux::{none, singleton}, + plutus_data::IsPlutusData, }; ////////////////////// @@ -36,7 +30,7 @@ use crate::{ /// /// Also know as `TxOutRef` from Plutus, this identifies a UTxO by its transacton hash and index /// inside the transaction -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInput { @@ -50,41 +44,6 @@ impl fmt::Display for TransactionInput { } } -impl IsPlutusData for TransactionInput { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.transaction_id.to_plutus_data(), - self.index.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(TransactionInput { - transaction_id: TransactionHash::from_plutus_data(&fields[0])?, - index: BigInt::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - impl FromCSL for TransactionInput { fn from_csl(value: &csl::TransactionInput) -> Self { TransactionInput { @@ -129,7 +88,7 @@ impl TryFromPLA> for csl::TransactionInputs { /// /// Also known as Transaction ID or `TxID`. /// Note: Plutus docs might incorrectly state that it uses SHA256. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionHash(pub LedgerBytes); @@ -140,32 +99,6 @@ impl fmt::Display for TransactionHash { } } -impl IsPlutusData for TransactionHash { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr(BigInt::from(0), vec![self.0.to_plutus_data()]) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 1)?; - Ok(TransactionHash(IsPlutusData::from_plutus_data(&fields[0])?)) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - impl FromCSL for TransactionHash { fn from_csl(value: &csl::TransactionHash) -> Self { TransactionHash(LedgerBytes(value.to_bytes())) @@ -187,7 +120,7 @@ impl TryFromPLA for csl::TransactionHash { /// /// This must include the target address, the hash of the datum attached, and the amount of output /// tokens -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionOutput { @@ -196,63 +129,17 @@ pub struct TransactionOutput { pub datum_hash: Option, } -impl IsPlutusData for TransactionOutput { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.address.to_plutus_data(), - self.value.to_plutus_data(), - self.datum_hash.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 3)?; - Ok(TransactionOutput { - address: Address::from_plutus_data(&fields[0])?, - value: Value::from_plutus_data(&fields[1])?, - datum_hash: >::from_plutus_data(&fields[2])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - /////////////// // POSIXTime // /////////////// /// POSIX time is measured as the number of milliseconds since 1970-01-01T00:00:00Z -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct POSIXTime(pub BigInt); -impl IsPlutusData for POSIXTime { - fn to_plutus_data(&self) -> PlutusData { - self.0.to_plutus_data() - } - - fn from_plutus_data(data: &PlutusData) -> Result { - IsPlutusData::from_plutus_data(data).map(Self) - } -} - #[cfg(feature = "chrono")] #[derive(thiserror::Error, Debug)] pub enum POSIXTimeConversionError { @@ -293,7 +180,7 @@ pub type POSIXTimeRange = PlutusInterval; ////////////// /// An input of a pending transaction. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TxInInfo { @@ -301,41 +188,6 @@ pub struct TxInInfo { pub output: TransactionOutput, } -impl IsPlutusData for TxInInfo { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.reference.to_plutus_data(), - self.output.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(TxInInfo { - reference: TransactionInput::from_plutus_data(&fields[0])?, - output: TransactionOutput::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - impl From<(TransactionInput, TransactionOutput)> for TxInInfo { fn from((reference, output): (TransactionInput, TransactionOutput)) -> TxInInfo { TxInInfo { reference, output } @@ -347,7 +199,7 @@ impl From<(TransactionInput, TransactionOutput)> for TxInInfo { /////////// /// Partial representation of digests of certificates on the ledger. -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum DCert { @@ -375,78 +227,12 @@ pub enum DCert { Mir, } -impl IsPlutusData for DCert { - fn to_plutus_data(&self) -> PlutusData { - let (tag, fields) = match self { - DCert::DelegRegKey(c) => (0u32, singleton(c.to_plutus_data())), - DCert::DelegDeRegKey(c) => (1, singleton(c.to_plutus_data())), - DCert::DelegDelegate(c, pkh) => (2, vec![c.to_plutus_data(), pkh.to_plutus_data()]), - DCert::PoolRegister(pkh, pkh1) => { - (3, vec![pkh.to_plutus_data(), pkh1.to_plutus_data()]) - } - DCert::PoolRetire(pkh, i) => (4, vec![pkh.to_plutus_data(), i.to_plutus_data()]), - DCert::Genesis => (5, none()), - DCert::Mir => (6, none()), - }; - - PlutusData::Constr(BigInt::from(tag), fields) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - let (tag, fields) = parse_constr(data)?; - - match tag { - 0 => { - let [field] = parse_fixed_len_constr_fields::<1>(fields)?; - IsPlutusData::from_plutus_data(field).map(Self::DelegRegKey) - } - 1 => { - let [field] = parse_fixed_len_constr_fields::<1>(fields)?; - IsPlutusData::from_plutus_data(field).map(Self::DelegDeRegKey) - } - 2 => { - let [field1, field2] = parse_fixed_len_constr_fields::<2>(fields)?; - Ok(Self::DelegDelegate( - IsPlutusData::from_plutus_data(field1)?, - IsPlutusData::from_plutus_data(field2)?, - )) - } - 3 => { - let [field1, field2] = parse_fixed_len_constr_fields::<2>(fields)?; - Ok(Self::PoolRegister( - IsPlutusData::from_plutus_data(field1)?, - IsPlutusData::from_plutus_data(field2)?, - )) - } - 4 => { - let [field1, field2] = parse_fixed_len_constr_fields::<2>(fields)?; - Ok(Self::PoolRetire( - IsPlutusData::from_plutus_data(field1)?, - IsPlutusData::from_plutus_data(field2)?, - )) - } - 5 => { - let [] = parse_fixed_len_constr_fields::<0>(fields)?; - Ok(Self::Genesis) - } - 6 => { - let [] = parse_fixed_len_constr_fields::<0>(fields)?; - Ok(Self::Mir) - } - bad_tag => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr tag to be 0, 1, 2, 3, 4, 5 or 6".to_owned(), - got: bad_tag.to_string(), - }), - } - } -} - /////////////////// // ScriptPurpose // /////////////////// /// The purpose of the script that's currently running. -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum ScriptPurpose { @@ -456,41 +242,12 @@ pub enum ScriptPurpose { Certifying(DCert), } -impl IsPlutusData for ScriptPurpose { - fn to_plutus_data(&self) -> PlutusData { - let (tag, field) = match self { - ScriptPurpose::Minting(cs) => (0u32, cs.to_plutus_data()), - ScriptPurpose::Spending(i) => (1, i.to_plutus_data()), - ScriptPurpose::Rewarding(c) => (2, c.to_plutus_data()), - ScriptPurpose::Certifying(c) => (3, c.to_plutus_data()), - }; - - PlutusData::Constr(BigInt::from(tag), singleton(field)) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let (tag, fields) = parse_constr(plutus_data)?; - let [field] = parse_fixed_len_constr_fields(fields)?; - - match tag { - 0 => IsPlutusData::from_plutus_data(field).map(Self::Minting), - 1 => IsPlutusData::from_plutus_data(field).map(Self::Spending), - 2 => IsPlutusData::from_plutus_data(field).map(Self::Rewarding), - 3 => IsPlutusData::from_plutus_data(field).map(Self::Certifying), - bad_tag => Err(PlutusDataError::UnexpectedPlutusInvariant { - got: bad_tag.to_string(), - wanted: "Constr tag to be 0, 1, 2 or 3".to_string(), - }), - } - } -} - ///////////////////// // TransactionInfo // ///////////////////// /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInfo { @@ -506,73 +263,15 @@ pub struct TransactionInfo { pub id: TransactionHash, } -impl IsPlutusData for TransactionInfo { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.inputs.to_plutus_data(), - self.outputs.to_plutus_data(), - self.fee.to_plutus_data(), - self.mint.to_plutus_data(), - self.d_cert.to_plutus_data(), - self.wdrl.to_plutus_data(), - self.valid_range.to_plutus_data(), - self.signatories.to_plutus_data(), - self.datums.to_plutus_data(), - self.id.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(data, 0)?; - let [inputs, outputs, fee, mint, d_cert, wdrl, valid_range, signatories, datums, id] = - parse_fixed_len_constr_fields(fields)?; - - Ok(Self { - inputs: IsPlutusData::from_plutus_data(inputs)?, - outputs: IsPlutusData::from_plutus_data(outputs)?, - fee: IsPlutusData::from_plutus_data(fee)?, - mint: IsPlutusData::from_plutus_data(mint)?, - d_cert: IsPlutusData::from_plutus_data(d_cert)?, - wdrl: IsPlutusData::from_plutus_data(wdrl)?, - valid_range: IsPlutusData::from_plutus_data(valid_range)?, - signatories: IsPlutusData::from_plutus_data(signatories)?, - datums: IsPlutusData::from_plutus_data(datums)?, - id: IsPlutusData::from_plutus_data(id)?, - }) - } -} - /////////////////// // ScriptContext // /////////////////// /// The context that is presented to the currently-executing script. -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptContext { pub tx_info: TransactionInfo, pub purpose: ScriptPurpose, } - -impl IsPlutusData for ScriptContext { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![self.tx_info.to_plutus_data(), self.purpose.to_plutus_data()], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(data, 0)?; - let [tx_info, purpose] = parse_fixed_len_constr_fields(fields)?; - - Ok(Self { - tx_info: IsPlutusData::from_plutus_data(tx_info)?, - purpose: IsPlutusData::from_plutus_data(purpose)?, - }) - } -} diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 7c02681..88ce277 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -20,9 +20,7 @@ use serde_json; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, -}; +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; use crate::utils::aux::{singleton, union_b_tree_maps_with, union_btree_maps_with}; use crate::v1::crypto::LedgerBytes; use crate::v1::script::{MintingPolicyHash, ScriptHash}; @@ -643,7 +641,7 @@ impl TryFromPLA for csl::AssetName { //////////////// /// AssetClass is uniquely identifying a specific asset -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct AssetClass { @@ -661,41 +659,6 @@ impl fmt::Display for AssetClass { } } -impl IsPlutusData for AssetClass { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.currency_symbol.to_plutus_data(), - self.token_name.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(AssetClass { - currency_symbol: CurrencySymbol::from_plutus_data(&fields[0])?, - token_name: TokenName::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field between 0 and 1".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - #[cfg(test)] mod test { use super::*; diff --git a/plutus-ledger-api/src/v2/datum.rs b/plutus-ledger-api/src/v2/datum.rs index a870811..e247d7d 100644 --- a/plutus-ledger-api/src/v2/datum.rs +++ b/plutus-ledger-api/src/v2/datum.rs @@ -3,7 +3,6 @@ use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::{self, Error, Json}; -use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -14,7 +13,7 @@ use crate::{ csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}, pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}, }, - plutus_data::{verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType}, + plutus_data::IsPlutusData, }; ///////////////// @@ -26,7 +25,7 @@ use crate::{ /// In case an inline datum is used, the data is embedded inside the transaction body, so it can be /// directly retrieved. In case of a datum hash, an off-chain indexer is required to find the /// associated datum by its hash. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum OutputDatum { None, @@ -34,52 +33,6 @@ pub enum OutputDatum { InlineDatum(Datum), } -impl IsPlutusData for OutputDatum { - fn to_plutus_data(&self) -> PlutusData { - match self { - OutputDatum::None => PlutusData::Constr(BigInt::from(0), vec![]), - OutputDatum::DatumHash(dat_hash) => { - PlutusData::Constr(BigInt::from(1), vec![dat_hash.to_plutus_data()]) - } - OutputDatum::InlineDatum(datum) => { - PlutusData::Constr(BigInt::from(2), vec![datum.to_plutus_data()]) - } - } - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 0)?; - Ok(OutputDatum::None) - } - Ok(1) => { - verify_constr_fields(fields, 1)?; - Ok(OutputDatum::DatumHash(DatumHash::from_plutus_data( - &fields[0], - )?)) - } - Ok(2) => { - verify_constr_fields(fields, 1)?; - Ok(OutputDatum::InlineDatum(Datum::from_plutus_data( - &fields[0], - )?)) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be between 0..2".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - #[cfg(feature = "lbf")] impl Json for OutputDatum { fn to_json(&self) -> serde_json::Value { diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index 9374256..65335e4 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -11,10 +11,7 @@ use serde::{Deserialize, Serialize}; use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{parse_constr_with_tag, parse_fixed_len_constr_fields}; -use crate::plutus_data::{ - verify_constr_fields, IsPlutusData, PlutusData, PlutusDataError, PlutusType, -}; +use crate::plutus_data::IsPlutusData; #[cfg(feature = "chrono")] pub use crate::v1::transaction::POSIXTimeConversionError; pub use crate::v1::transaction::{ @@ -40,7 +37,7 @@ use super::{ /// /// This must include the target address, an optional datum, an optional reference script, and the /// amount of output tokens -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionOutput { @@ -50,45 +47,6 @@ pub struct TransactionOutput { pub reference_script: Option, } -impl IsPlutusData for TransactionOutput { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.address.to_plutus_data(), - self.value.to_plutus_data(), - self.datum.to_plutus_data(), - self.reference_script.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 4)?; - Ok(TransactionOutput { - address: Address::from_plutus_data(&fields[0])?, - value: Value::from_plutus_data(&fields[1])?, - datum: OutputDatum::from_plutus_data(&fields[2])?, - reference_script: >::from_plutus_data(&fields[3])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - impl TryFromCSL for TransactionOutput { fn try_from_csl(value: &csl::TransactionOutput) -> Result { Ok(TransactionOutput { @@ -205,7 +163,7 @@ impl TryFromPLA> for csl::TransactionOutput { ////////////// /// An input of a pending transaction. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TxInInfo { @@ -219,47 +177,11 @@ impl From<(TransactionInput, TransactionOutput)> for TxInInfo { } } -impl IsPlutusData for TxInInfo { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.reference.to_plutus_data(), - self.output.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - match data { - PlutusData::Constr(flag, fields) => match u32::try_from(flag) { - Ok(0) => { - verify_constr_fields(fields, 2)?; - Ok(TxInInfo { - reference: TransactionInput::from_plutus_data(&fields[0])?, - output: TransactionOutput::from_plutus_data(&fields[1])?, - }) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: "Constr field to be 0".to_owned(), - got: flag.to_string(), - }), - }, - - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } - } -} - -///////////////////// // TransactionInfo // ///////////////////// /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInfo { @@ -277,49 +199,6 @@ pub struct TransactionInfo { pub id: TransactionHash, } -impl IsPlutusData for TransactionInfo { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![ - self.inputs.to_plutus_data(), - self.reference_inputs.to_plutus_data(), - self.outputs.to_plutus_data(), - self.fee.to_plutus_data(), - self.mint.to_plutus_data(), - self.d_cert.to_plutus_data(), - self.wdrl.to_plutus_data(), - self.valid_range.to_plutus_data(), - self.signatories.to_plutus_data(), - self.redeemers.to_plutus_data(), - self.datums.to_plutus_data(), - self.id.to_plutus_data(), - ], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(data, 0)?; - let [inputs, reference_inputs, outputs, fee, mint, d_cert, wdrl, valid_range, signatories, redeemers, datums, id] = - parse_fixed_len_constr_fields(fields)?; - - Ok(Self { - inputs: IsPlutusData::from_plutus_data(inputs)?, - reference_inputs: IsPlutusData::from_plutus_data(reference_inputs)?, - outputs: IsPlutusData::from_plutus_data(outputs)?, - fee: IsPlutusData::from_plutus_data(fee)?, - mint: IsPlutusData::from_plutus_data(mint)?, - d_cert: IsPlutusData::from_plutus_data(d_cert)?, - wdrl: IsPlutusData::from_plutus_data(wdrl)?, - valid_range: IsPlutusData::from_plutus_data(valid_range)?, - signatories: IsPlutusData::from_plutus_data(signatories)?, - redeemers: IsPlutusData::from_plutus_data(redeemers)?, - datums: IsPlutusData::from_plutus_data(datums)?, - id: IsPlutusData::from_plutus_data(id)?, - }) - } -} - #[derive(Clone, Debug)] pub struct WithdrawalsWithExtraInfo<'a> { pub withdrawals: &'a AssocMap, @@ -350,29 +229,10 @@ impl TryFromPLA> for csl::Withdrawals { /////////////////// /// The context that is presented to the currently-executing script. -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptContext { pub tx_info: TransactionInfo, pub purpose: ScriptPurpose, } - -impl IsPlutusData for ScriptContext { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(0), - vec![self.tx_info.to_plutus_data(), self.purpose.to_plutus_data()], - ) - } - - fn from_plutus_data(data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(data, 0)?; - let [tx_info, purpose] = parse_fixed_len_constr_fields(fields)?; - - Ok(Self { - tx_info: IsPlutusData::from_plutus_data(tx_info)?, - purpose: IsPlutusData::from_plutus_data(purpose)?, - }) - } -} From b4351b77c7272a2ea2bcc845b3a7dd4ec9e4b7fe Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 23:52:08 +0800 Subject: [PATCH 16/38] explicitly mark derive strategies --- plutus-ledger-api/src/v1/address.rs | 7 ++++--- plutus-ledger-api/src/v1/transaction.rs | 8 ++++++++ plutus-ledger-api/src/v2/datum.rs | 1 + plutus-ledger-api/src/v2/transaction.rs | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index 9230518..f3c1aba 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -13,20 +13,20 @@ use crate::v1::script::ValidatorHash; #[cfg(feature = "lbf")] use lbr_prelude::json::{self, Error, Json}; use num_bigint::BigInt; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; ///////////// // Address // ///////////// -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - /// Shelley Address for wallets or validators /// /// An address consists of a payment part (credential) and a delegation part (staking_credential). /// In order to serialize an address to `bech32`, the network kind must be known. /// For a better understanding of all the Cardano address types, read [CIP 19](https://cips.cardano.org/cips/cip19/) #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Address { @@ -125,6 +125,7 @@ impl std::fmt::Display for AddressWithExtraInfo<'_> { /// A public key hash or validator hash credential (used as a payment or a staking credential) #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Credential { PubKey(Ed25519PubKeyHash), diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index efe574b..44c4533 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -31,6 +31,7 @@ use crate::{ /// Also know as `TxOutRef` from Plutus, this identifies a UTxO by its transacton hash and index /// inside the transaction #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInput { @@ -89,6 +90,7 @@ impl TryFromPLA> for csl::TransactionInputs { /// Also known as Transaction ID or `TxID`. /// Note: Plutus docs might incorrectly state that it uses SHA256. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionHash(pub LedgerBytes); @@ -121,6 +123,7 @@ impl TryFromPLA for csl::TransactionHash { /// This must include the target address, the hash of the datum attached, and the amount of output /// tokens #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionOutput { @@ -181,6 +184,7 @@ pub type POSIXTimeRange = PlutusInterval; /// An input of a pending transaction. #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TxInInfo { @@ -200,6 +204,7 @@ impl From<(TransactionInput, TransactionOutput)> for TxInInfo { /// Partial representation of digests of certificates on the ledger. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum DCert { @@ -233,6 +238,7 @@ pub enum DCert { /// The purpose of the script that's currently running. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum ScriptPurpose { @@ -248,6 +254,7 @@ pub enum ScriptPurpose { /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus #[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInfo { @@ -269,6 +276,7 @@ pub struct TransactionInfo { /// The context that is presented to the currently-executing script. #[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptContext { diff --git a/plutus-ledger-api/src/v2/datum.rs b/plutus-ledger-api/src/v2/datum.rs index e247d7d..9a3ec6c 100644 --- a/plutus-ledger-api/src/v2/datum.rs +++ b/plutus-ledger-api/src/v2/datum.rs @@ -26,6 +26,7 @@ use crate::{ /// directly retrieved. In case of a datum hash, an off-chain indexer is required to find the /// associated datum by its hash. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum OutputDatum { None, diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index 65335e4..2b2fab0 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -38,6 +38,7 @@ use super::{ /// This must include the target address, an optional datum, an optional reference script, and the /// amount of output tokens #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionOutput { @@ -164,6 +165,7 @@ impl TryFromPLA> for csl::TransactionOutput { /// An input of a pending transaction. #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TxInInfo { @@ -182,6 +184,7 @@ impl From<(TransactionInput, TransactionOutput)> for TxInInfo { /// A pending transaction as seen by validator scripts, also known as TxInfo in Plutus #[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInfo { @@ -230,6 +233,7 @@ impl TryFromPLA> for csl::Withdrawals { /// The context that is presented to the currently-executing script. #[derive(Debug, PartialEq, Eq, Clone, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptContext { From 3e6428164a7eb46075ea7bcdd2f31b8cd620956c Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 20:27:57 +0800 Subject: [PATCH 17/38] move plutus-data back to where it was --- is-plutus-data-derive/src/derive_impl.rs | 52 +- plutus-ledger-api/Cargo.lock | 15 +- plutus-ledger-api/Cargo.toml | 6 +- plutus-ledger-api/src/lamval.rs | 4 +- plutus-ledger-api/src/plutus_data.rs | 588 ++++++++++++++++++++++- plutus-ledger-api/src/v1/address.rs | 15 +- plutus-ledger-api/src/v1/crypto.rs | 11 +- plutus-ledger-api/src/v1/datum.rs | 2 +- plutus-ledger-api/src/v1/interval.rs | 9 +- plutus-ledger-api/src/v1/redeemer.rs | 1 + plutus-ledger-api/src/v1/script.rs | 1 + plutus-ledger-api/src/v1/transaction.rs | 1 + plutus-ledger-api/src/v1/value.rs | 1 + plutus-ledger-api/src/v2/datum.rs | 2 + plutus-ledger-api/src/v2/transaction.rs | 1 + 15 files changed, 635 insertions(+), 74 deletions(-) diff --git a/is-plutus-data-derive/src/derive_impl.rs b/is-plutus-data-derive/src/derive_impl.rs index 0b0886c..7195196 100644 --- a/is-plutus-data-derive/src/derive_impl.rs +++ b/is-plutus-data-derive/src/derive_impl.rs @@ -32,12 +32,12 @@ pub(crate) fn get_is_plutus_data_instance(input: DeriveInput) -> Result plutus_data::PlutusData { + impl #impl_generics plutus_ledger_api::plutus_data::IsPlutusData for #type_name #type_generics #where_clause { + fn to_plutus_data(&self) -> plutus_ledger_api::plutus_data::PlutusData { #encoder } - fn from_plutus_data(plutus_data: &plutus_data::PlutusData) -> Result + fn from_plutus_data(plutus_data: &plutus_ledger_api::plutus_data::PlutusData) -> Result where Self: Sized { #decoder } @@ -170,15 +170,15 @@ fn get_newtype_encoder_decoder(input: &DeriveInput) -> Result<(Block, Block)> { Some(field_name) => { parse_quote!({ Ok(Self { - #field_name: plutus_data::IsPlutusData::from_plutus_data(plutus_data)? + #field_name: plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)? }) }) } None => { parse_quote!({ - Ok(Self(plutus_data::IsPlutusData::from_plutus_data( - plutus_data, - )?)) + Ok(Self( + plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(plutus_data)?, + )) }) } }; @@ -310,11 +310,11 @@ fn enum_from_plutus_data_constr(e: &DataEnum, plutus_data_input_var: &Ident) -> parse_quote!( { - let (tag, #plutus_data_list_var) = plutus_data::is_plutus_data::aux::parse_constr(#plutus_data_input_var)?; + let (tag, #plutus_data_list_var) = plutus_ledger_api::plutus_data::parse_constr(#plutus_data_input_var)?; match tag { #(#arms),* - tag => Err(plutus_data::PlutusDataError::UnexpectedPlutusInvariant { + tag => Err(plutus_ledger_api::plutus_data::PlutusDataError::UnexpectedPlutusInvariant { wanted: format!(#expected_tags_str), got: tag.to_string(), }), @@ -380,7 +380,7 @@ fn variant_with_named_fields_to_plutus_data( let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); parse_quote!( - #constructor{ #(#field_names),* } => plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + #constructor{ #(#field_names),* } => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) ) } @@ -407,7 +407,7 @@ fn variant_with_unnamed_field_to_plutus_data( let plutus_data_list = data_fields_to_list_of_plutus_data(&field_accessors); parse_quote!( - #constructor(#(#field_names),*) => plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) + #constructor(#(#field_names),*) => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), #plutus_data_list) ) } @@ -425,7 +425,7 @@ fn variant_with_unnamed_fields_from_plutus_data_list( fn variant_with_no_field_to_plutus_data(constructor: &Path, tag: usize) -> Arm { parse_quote!( - #constructor => plutus_data::PlutusData::Constr(#tag.into(), vec![]) + #constructor => plutus_ledger_api::plutus_data::PlutusData::Constr(#tag.into(), vec![]) ) } @@ -463,7 +463,7 @@ fn struct_with_named_fields_to_plutus_data_list(fields: &FieldsNamed) -> Block { let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_data::PlutusData::List(#to_list_of_plutus_data) + plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) }) } @@ -477,7 +477,7 @@ fn struct_with_named_fields_from_plutus_data_list( struct_with_named_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) @@ -487,7 +487,7 @@ fn struct_with_named_fields_to_plutus_data_constr(fields: &FieldsNamed) -> Block let to_list_of_plutus_data = struct_with_named_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) }) } @@ -501,7 +501,7 @@ fn struct_with_named_fields_from_plutus_data_constr( struct_with_named_fields_from_list_of_plutus_data(fields, &plutus_data_list_var); parse_quote!({ - let #plutus_data_list_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #plutus_data_list_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; #from_plutus_data_list }) @@ -537,7 +537,7 @@ fn struct_with_unnamed_fields_to_plutus_data_list(fields: &FieldsUnnamed) -> Blo let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_data::PlutusData::List(#to_list_of_plutus_data) + plutus_ledger_api::plutus_data::PlutusData::List(#to_list_of_plutus_data) }) } @@ -551,7 +551,7 @@ fn struct_with_unnamed_fields_from_plutus_data_list( struct_with_unnamed_fields_from_list_of_plutus_data(fields, &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) @@ -561,7 +561,7 @@ fn struct_with_unnamed_fields_to_plutus_data_constr(fields: &FieldsUnnamed) -> B let to_list_of_plutus_data = struct_with_unnamed_fields_to_list_of_plutus_data(fields); parse_quote!({ - plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) + plutus_ledger_api::plutus_data::PlutusData::Constr(0.into(), #to_list_of_plutus_data) }) } @@ -574,7 +574,7 @@ fn struct_with_unnamed_fields_from_plutus_data_constr( let from_fields = struct_with_unnamed_fields_from_list_of_plutus_data(fields, &fields_var); parse_quote!({ - let #fields_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #fields_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; #from_fields }) @@ -591,7 +591,7 @@ fn struct_with_no_field_from_plutus_data_list(plutus_data_input_var: &Ident) -> data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &list_of_plutus_data_var); parse_quote!({ - let #list_of_plutus_data_var = plutus_data::is_plutus_data::aux::parse_list(#plutus_data_input_var)?; + let #list_of_plutus_data_var = plutus_ledger_api::plutus_data::parse_list(#plutus_data_input_var)?; #from_list_of_plutus_data }) @@ -608,7 +608,7 @@ fn struct_with_no_field_from_plutus_data_constr(plutus_data_input_var: &Ident) - data_with_no_fields_from_list_of_plutus_data(&parse_quote!(Self), &fields_var); parse_quote!({ - let #fields_var = plutus_data::is_plutus_data::aux::parse_constr_with_tag(#plutus_data_input_var, 0)?; + let #fields_var = plutus_ledger_api::plutus_data::parse_constr_with_tag(#plutus_data_input_var, 0)?; #from_fields }) @@ -641,14 +641,14 @@ fn data_with_named_fields_from_list_of_plutus_data( let field_decoded_stmts = field_idents.clone().zip(unparsed_field_idents.clone()).map( |(field_ident, unparsed_field_ident)| -> Stmt { parse_quote!( - let #field_ident = plutus_data::IsPlutusData::from_plutus_data(#unparsed_field_ident)?; + let #field_ident = plutus_ledger_api::plutus_data::IsPlutusData::from_plutus_data(#unparsed_field_ident)?; ) }, ); parse_quote!( { - let [ #(#unparsed_field_idents),* ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; + let [ #(#unparsed_field_idents),* ] = plutus_ledger_api::plutus_data::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; #(#field_decoded_stmts)* Ok(#constructor{ #(#field_idents),* }) } @@ -678,7 +678,7 @@ fn data_with_unnamed_fields_from_list_of_plutus_data( }); parse_quote!({ - let [ #(#unparsed_field_idents),* ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; + let [ #(#unparsed_field_idents),* ] = plutus_ledger_api::plutus_data::parse_fixed_len_constr_fields::<#field_count>(#plutus_data_list_var)?; #(#field_decoded_stmts)* Ok(#constructor(#(#parsed_field_idents),*)) }) @@ -689,7 +689,7 @@ fn data_with_no_fields_from_list_of_plutus_data( list_of_plutus_data_var: &Ident, ) -> Block { parse_quote!({ - let [ ] = plutus_data::is_plutus_data::aux::parse_fixed_len_constr_fields::<0>(#list_of_plutus_data_var)?; + let [ ] = plutus_ledger_api::plutus_data::parse_fixed_len_constr_fields::<0>(#list_of_plutus_data_var)?; Ok(#constructor) }) } diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index e2f7fa2..79fed43 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -608,19 +608,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "plutus-data" -version = "0.1.0" -dependencies = [ - "data-encoding", - "is-plutus-data-derive", - "lbr-prelude", - "num-bigint", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "plutus-ledger-api" version = "2.0.0-beta.1" @@ -631,11 +618,11 @@ dependencies = [ "data-encoding", "goldie", "impl_ops", + "is-plutus-data-derive", "lbr-prelude", "linked-hash-map", "num-bigint", "num-traits", - "plutus-data", "proptest", "serde", "serde_json", diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index d09b07f..1ece481 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -22,13 +22,13 @@ num-traits = "~0.2.17" impl_ops = "0.1.1" chrono = { version = "0.4.34", optional = true } cardano-serialization-lib = "12.1.0" +is-plutus-data-derive = { path = ".extras/is-plutus-data-derive-0" } anyhow = "1.0.86" -plutus-data = { path = ".extras/plutus-data-0", features = [ "derive" ]} [features] default = [] -serde = ["dep:serde", "num-bigint/serde", "dep:serde_json", "plutus-data/serde"] -lbf = ["dep:lbr-prelude", "dep:serde_json", "plutus-data/lbf"] +serde = ["dep:serde", "num-bigint/serde", "dep:serde_json"] +lbf = ["dep:lbr-prelude", "dep:serde_json"] chrono = ["dep:chrono"] [dev-dependencies] diff --git a/plutus-ledger-api/src/lamval.rs b/plutus-ledger-api/src/lamval.rs index 366e3b7..7a3459b 100644 --- a/plutus-ledger-api/src/lamval.rs +++ b/plutus-ledger-api/src/lamval.rs @@ -1,4 +1,6 @@ -use crate::plutus_data::{self, PlutusData, PlutusDataError}; +use crate::plutus_data::PlutusDataError; +use crate::plutus_data::{self, PlutusData}; + use num_bigint::BigInt; pub fn case_plutus_data<'a, T: 'a>( diff --git a/plutus-ledger-api/src/plutus_data.rs b/plutus-ledger-api/src/plutus_data.rs index e446ed7..0be189b 100644 --- a/plutus-ledger-api/src/plutus_data.rs +++ b/plutus-ledger-api/src/plutus_data.rs @@ -1,27 +1,109 @@ //! Plutus Data related types and traits + +use std::collections::{BTreeMap, BTreeSet}; + use cardano_serialization_lib as csl; use num_bigint::BigInt; use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -pub use plutus_data::{ - is_plutus_data::aux::*, IsPlutusData, PlutusData, PlutusDataError, PlutusType, +pub use is_plutus_data_derive::IsPlutusData; + +#[cfg(feature = "lbf")] +use data_encoding::HEXLOWER; +#[cfg(feature = "lbf")] +use lbr_prelude::error::Error; +#[cfg(feature = "lbf")] +use lbr_prelude::json::{ + case_json_constructor, case_json_object, json_constructor, json_object, Json, }; -/// Deserialise a Plutus data using parsers for each variant -pub fn case_plutus_data<'a, T>( - ctor_case: impl FnOnce(&'a BigInt) -> Box) -> T>, - list_case: impl FnOnce(&'a Vec) -> T, - int_case: impl FnOnce(&'a BigInt) -> T, - other_case: impl FnOnce(&'a PlutusData) -> T, - pd: &'a PlutusData, -) -> T { - match pd { - PlutusData::Constr(tag, args) => ctor_case(&tag)(&args), - PlutusData::List(args) => list_case(&args), - PlutusData::Integer(i) => int_case(&i), - other => other_case(&other), +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// Data representation of on-chain data such as Datums and Redeemers +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum PlutusData { + Constr(BigInt, Vec), + Map(Vec<(PlutusData, PlutusData)>), + List(Vec), + Integer(BigInt), + Bytes(Vec), +} + +#[derive(Clone, Debug)] +pub enum PlutusType { + Constr, + Map, + List, + Integer, + Bytes, +} + +pub trait IsPlutusData { + fn to_plutus_data(&self) -> PlutusData; + + fn from_plutus_data(plutus_data: &PlutusData) -> Result + where + Self: Sized; +} + +// TODO(chfanghr): improve error reporting +#[derive(Clone, Debug, thiserror::Error)] +pub enum PlutusDataError { + #[error("Expected a PlutusData type {wanted:?}, but got {got:?}")] + UnexpectedPlutusType { got: PlutusType, wanted: PlutusType }, + #[error("Expected a PlutusData type as {wanted:?}, but got {got:?}")] + UnexpectedPlutusInvariant { got: String, wanted: String }, + #[error("Expected a Plutus List with {wanted:?} elements, but got {got:?} elements")] + UnexpectedListLength { got: usize, wanted: usize }, + #[error("Some internal error happened: {0}")] + InternalError(String), +} + +impl From<&PlutusData> for PlutusType { + fn from(plutus_data: &PlutusData) -> Self { + match plutus_data { + PlutusData::Constr(_, _) => PlutusType::Constr, + PlutusData::Map(_) => PlutusType::Map, + PlutusData::List(_) => PlutusType::List, + PlutusData::Integer(_) => PlutusType::Integer, + PlutusData::Bytes(_) => PlutusType::Bytes, + } + } +} + +impl PlutusData { + pub fn constr(tag: u32, fields: Vec) -> Self { + PlutusData::Constr(BigInt::from(tag), fields) + } + + pub fn map(fields: Vec<(PlutusData, PlutusData)>) -> Self { + PlutusData::Map(fields) + } + + pub fn list(fields: Vec) -> Self { + PlutusData::List(fields) + } + + pub fn integer(value: u32) -> Self { + PlutusData::Integer(BigInt::from(value)) + } + + pub fn bytes(value: Vec) -> Self { + PlutusData::Bytes(value) + } +} + +impl IsPlutusData for PlutusData { + fn to_plutus_data(&self) -> PlutusData { + self.clone() + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + Ok(plutus_data.clone()) } } @@ -44,6 +126,399 @@ impl TryFromCSL for PlutusData { } } +#[cfg(feature = "lbf")] +impl Json for PlutusData { + fn to_json(&self) -> serde_json::Value { + match self { + PlutusData::Constr(index, fields) => json_constructor( + "Constr", + vec![json_object(vec![ + ("index".to_string(), index.to_json()), + ("fields".to_string(), fields.to_json()), + ])], + ), + PlutusData::Map(map) => json_constructor("Map", vec![map.to_json()]), + PlutusData::List(list) => json_constructor("List", vec![list.to_json()]), + PlutusData::Integer(int) => json_constructor("Integer", vec![int.to_json()]), + PlutusData::Bytes(bytes) => { + json_constructor("Bytes", vec![String::to_json(&HEXLOWER.encode(bytes))]) + } + } + } + + fn from_json(value: &serde_json::Value) -> Result { + case_json_constructor( + "PlutusV1.PlutusData", + vec![ + ( + "Constr", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => case_json_object( + |obj| { + let index = obj.get("index").ok_or(Error::UnexpectedFieldName { + wanted: "index".to_owned(), + got: obj.keys().cloned().collect(), + parser: "PlutusV1.PlutusData".to_owned(), + })?; + + let fields = + obj.get("fields").ok_or(Error::UnexpectedFieldName { + wanted: "fields".to_owned(), + got: obj.keys().cloned().collect(), + parser: "PlutusV1.PlutusData".to_owned(), + })?; + Ok(PlutusData::Constr( + BigInt::from_json(index)?, + >::from_json(fields)?, + )) + }, + val, + ), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Map", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::Map(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "List", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::List(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Integer", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => Ok(PlutusData::Integer(Json::from_json(val)?)), + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ( + "Bytes", + Box::new(|ctor_fields| match &ctor_fields[..] { + [val] => { + let bytes = String::from_json(val).and_then(|str| { + HEXLOWER.decode(&str.into_bytes()).map_err(|_| { + Error::UnexpectedJsonInvariant { + wanted: "base16 string".to_owned(), + got: "unexpected string".to_owned(), + parser: "Plutus.V1.Bytes".to_owned(), + } + }) + })?; + Ok(PlutusData::Bytes(bytes)) + } + _ => Err(Error::UnexpectedArrayLength { + wanted: 1, + got: ctor_fields.len(), + parser: "PlutusV1.PlutusData".to_owned(), + }), + }), + ), + ], + value, + ) + } +} + +// MARK: Orphan IsPlutusData Instances + +impl IsPlutusData for BigInt { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Integer(self.clone()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Integer(int) => Ok(int.clone()), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Integer, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for Vec { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Bytes(self.clone()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Bytes(bytes) => Ok(bytes.clone()), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Bytes, + got: PlutusType::from(plutus_data), + }), + } + } +} + +const BOOL_FALSE_TAG: u32 = 0; +const BOOL_TRUE_TAG: u32 = 1; + +impl IsPlutusData for bool { + fn to_plutus_data(&self) -> PlutusData { + if *self { + PlutusData::Constr(BOOL_TRUE_TAG.into(), vec![]) + } else { + PlutusData::Constr(BOOL_FALSE_TAG.into(), vec![]) + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + match tag { + BOOL_TRUE_TAG => Ok(true), + BOOL_FALSE_TAG => Ok(false), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {BOOL_TRUE_TAG} or {BOOL_FALSE_TAG}"), + got: tag.to_string(), + }), + } + } +} + +impl IsPlutusData for String { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Bytes(self.as_bytes().into()) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Bytes(bytes) => String::from_utf8(bytes.clone()).map_err(|err| { + PlutusDataError::InternalError(format!( + "Couldn't convert Plutus bytes to String: {:?}", + err + )) + }), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Bytes, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for char { + fn to_plutus_data(&self) -> PlutusData { + String::from(*self).to_plutus_data() + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + String::from_plutus_data(plutus_data).and_then(|str| { + let mut chars = str.chars(); + let ch = chars.next(); + let rest = chars.next(); + match (ch, rest) { + (Some(ch), None) => Ok(ch), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + got: "string".to_owned(), + wanted: "char".to_owned(), + }), + } + }) + } +} + +const OPTION_SOME_TAG: u32 = 0; +const OPTION_NONE_TAG: u32 = 1; + +impl IsPlutusData for Option +where + T: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + match self { + Some(val) => PlutusData::Constr(OPTION_SOME_TAG.into(), vec![val.to_plutus_data()]), + None => PlutusData::Constr(OPTION_NONE_TAG.into(), vec![]), + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + + match tag { + OPTION_SOME_TAG => { + let [data] = parse_fixed_len_constr_fields::<1>(fields)?; + Ok(Some(T::from_plutus_data(data)?)) + } + OPTION_NONE_TAG => { + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(None) + } + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {OPTION_SOME_TAG} or {OPTION_NONE_TAG}"), + got: tag.to_string(), + }), + } + } +} + +const RESULT_ERR_TAG: u32 = 0; +const RESULT_OK_TAG: u32 = 1; + +impl IsPlutusData for Result +where + T: IsPlutusData, + E: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + match self { + Err(err) => PlutusData::Constr(RESULT_ERR_TAG.into(), vec![err.to_plutus_data()]), + Ok(val) => PlutusData::Constr(RESULT_OK_TAG.into(), vec![val.to_plutus_data()]), + } + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let (tag, fields) = parse_constr(plutus_data)?; + let [field] = parse_fixed_len_constr_fields::<1>(fields)?; + + match tag { + RESULT_ERR_TAG => Ok(Err(E::from_plutus_data(field)?)), + RESULT_OK_TAG => Ok(Ok(T::from_plutus_data(field)?)), + _ => Err(PlutusDataError::UnexpectedPlutusInvariant { + wanted: format!("Constr with tag {RESULT_ERR_TAG} or {RESULT_OK_TAG}"), + got: tag.to_string(), + }), + } + } +} + +impl IsPlutusData for Vec +where + T: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + let values = self + .iter() + .map(|val| val.to_plutus_data()) + .collect::>(); + + PlutusData::List(values) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let list = parse_list(plutus_data)?; + list.iter().map(T::from_plutus_data).collect() + } +} + +impl IsPlutusData for BTreeSet +where + T: IsPlutusData + Eq + Ord, +{ + fn to_plutus_data(&self) -> PlutusData { + let set = self + .iter() + .map(|val| val.to_plutus_data()) + .collect::>(); + + PlutusData::List(set) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::List(vec) => vec + .iter() + .map(|val| T::from_plutus_data(val)) + .collect::>(), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::List, + got: PlutusType::from(plutus_data), + }), + } + } +} + +impl IsPlutusData for BTreeMap +where + K: IsPlutusData + Eq + Ord, + V: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + let assoc_map = self + .iter() + .map(|(key, val)| (key.to_plutus_data(), val.to_plutus_data())) + .collect::>(); + + PlutusData::Map(assoc_map) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + match plutus_data { + PlutusData::Map(dict) => dict + .iter() + .map(|(key, val)| Ok((K::from_plutus_data(key)?, V::from_plutus_data(val)?))) + .collect::>(), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Map, + got: PlutusType::from(plutus_data), + }), + } + } +} + +const UNIT_TAG: u32 = 0; + +impl IsPlutusData for () { + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Constr(UNIT_TAG.into(), vec![]) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let fields = parse_constr_with_tag(plutus_data, UNIT_TAG)?; + let [] = parse_fixed_len_constr_fields::<0>(fields)?; + Ok(()) + } +} + +const PAIR_TAG: u32 = 0; + +impl IsPlutusData for (A, B) +where + A: IsPlutusData, + B: IsPlutusData, +{ + fn to_plutus_data(&self) -> PlutusData { + PlutusData::Constr( + BigInt::from(PAIR_TAG), + vec![self.0.to_plutus_data(), self.1.to_plutus_data()], + ) + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result { + let fields = parse_constr_with_tag(plutus_data, PAIR_TAG)?; + let [a, b] = parse_fixed_len_constr_fields::<2>(fields)?; + Ok((A::from_plutus_data(a)?, B::from_plutus_data(b)?)) + } +} + +// MARK: Orphan TryFromCSL instances + impl TryFromCSL for Vec { fn try_from_csl(value: &csl::PlutusList) -> Result { (0..value.len()) @@ -109,3 +584,86 @@ impl TryFromPLA> for csl::PlutusMap { }) } } + +// MARK: Aux functions + +/// Deserialise a Plutus data using parsers for each variant +pub fn case_plutus_data<'a, T>( + ctor_case: impl FnOnce(&'a BigInt) -> Box) -> T>, + list_case: impl FnOnce(&'a Vec) -> T, + int_case: impl FnOnce(&'a BigInt) -> T, + other_case: impl FnOnce(&'a PlutusData) -> T, + pd: &'a PlutusData, +) -> T { + match pd { + PlutusData::Constr(tag, args) => ctor_case(&tag)(&args), + PlutusData::List(args) => list_case(&args), + PlutusData::Integer(i) => int_case(&i), + other => other_case(&other), + } +} + +/// Given a vector of PlutusData, parse it as an array whose length is known at +/// compile time. +/// +/// This function is used by the derive macro. +pub fn parse_fixed_len_constr_fields( + v: &[PlutusData], +) -> Result<&[PlutusData; LEN], PlutusDataError> { + v.try_into() + .map_err(|_| PlutusDataError::UnexpectedListLength { + got: v.len(), + wanted: LEN, + }) +} + +/// Given a PlutusData, parse it as PlutusData::Constr and its tag as u32. Return +/// the u32 tag and fields. +/// +/// This function is used by the derive macro. +pub fn parse_constr(data: &PlutusData) -> Result<(u32, &Vec), PlutusDataError> { + match data { + PlutusData::Constr(tag, fields) => u32::try_from(tag) + .map_err(|err| PlutusDataError::UnexpectedPlutusInvariant { + got: err.to_string(), + wanted: "Constr bigint tag within u32 range".into(), + }) + .map(|tag| (tag, fields)), + _ => Err(PlutusDataError::UnexpectedPlutusType { + wanted: PlutusType::Constr, + got: PlutusType::from(data), + }), + } +} + +/// Given a PlutusData, parse it as PlutusData::Constr and verify its tag. +/// +/// This function is used by the derive macro. +pub fn parse_constr_with_tag( + data: &PlutusData, + expected_tag: u32, +) -> Result<&Vec, PlutusDataError> { + let (tag, fields) = parse_constr(data)?; + + if tag != expected_tag { + Err(PlutusDataError::UnexpectedPlutusInvariant { + got: tag.to_string(), + wanted: format!("Constr with tag {}", expected_tag), + }) + } else { + Ok(fields) + } +} + +/// Given a PlutusData, parse it as PlutusData::List. Return the plutus data list. +/// +/// This function is used by the derive macro. +pub fn parse_list(data: &PlutusData) -> Result<&Vec, PlutusDataError> { + match data { + PlutusData::List(list_of_plutus_data) => Ok(list_of_plutus_data), + _ => Err(PlutusDataError::UnexpectedPlutusType { + got: PlutusType::from(data), + wanted: PlutusType::List, + }), + } +} diff --git a/plutus-ledger-api/src/v1/address.rs b/plutus-ledger-api/src/v1/address.rs index f3c1aba..1da054c 100644 --- a/plutus-ledger-api/src/v1/address.rs +++ b/plutus-ledger-api/src/v1/address.rs @@ -3,19 +3,22 @@ use std::str::FromStr; use anyhow::anyhow; use cardano_serialization_lib as csl; -use plutus_data::is_plutus_data::aux::{parse_constr, parse_fixed_len_constr_fields}; -use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; -use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; -use crate::v1::crypto::Ed25519PubKeyHash; -use crate::v1::script::ValidatorHash; #[cfg(feature = "lbf")] use lbr_prelude::json::{self, Error, Json}; use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate as plutus_ledger_api; +use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; +use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::plutus_data::{ + parse_constr, parse_fixed_len_constr_fields, IsPlutusData, PlutusData, PlutusDataError, +}; +use crate::v1::crypto::Ed25519PubKeyHash; +use crate::v1::script::ValidatorHash; + ///////////// // Address // ///////////// diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index 4555ff9..6565e1a 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -3,13 +3,16 @@ use cardano_serialization_lib as csl; use data_encoding::HEXLOWER; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json}; -use plutus_data::IsPlutusData; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::csl::{ - csl_to_pla::FromCSL, - pla_to_csl::{TryFromPLA, TryFromPLAError}, +use crate as plutus_ledger_api; +use crate::{ + csl::{ + csl_to_pla::FromCSL, + pla_to_csl::{TryFromPLA, TryFromPLAError}, + }, + plutus_data::IsPlutusData, }; /////////////////////// diff --git a/plutus-ledger-api/src/v1/datum.rs b/plutus-ledger-api/src/v1/datum.rs index 49901ab..c74fbbc 100644 --- a/plutus-ledger-api/src/v1/datum.rs +++ b/plutus-ledger-api/src/v1/datum.rs @@ -2,13 +2,13 @@ use cardano_serialization_lib as csl; +use crate as plutus_ledger_api; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{IsPlutusData, PlutusData}; use crate::v1::crypto::LedgerBytes; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; - #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; diff --git a/plutus-ledger-api/src/v1/interval.rs b/plutus-ledger-api/src/v1/interval.rs index eb78927..db827f8 100644 --- a/plutus-ledger-api/src/v1/interval.rs +++ b/plutus-ledger-api/src/v1/interval.rs @@ -1,12 +1,13 @@ //! Types related to PlutusInterval + use crate::feature_traits::FeatureTraits; -use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; +use crate::plutus_data::{ + parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, IsPlutusData, PlutusData, + PlutusDataError, +}; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; use num_bigint::BigInt; -use plutus_data::is_plutus_data::aux::{ - parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, -}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::cmp; diff --git a/plutus-ledger-api/src/v1/redeemer.rs b/plutus-ledger-api/src/v1/redeemer.rs index c46e39a..beeb616 100644 --- a/plutus-ledger-api/src/v1/redeemer.rs +++ b/plutus-ledger-api/src/v1/redeemer.rs @@ -7,6 +7,7 @@ use lbr_prelude::json::Json; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate as plutus_ledger_api; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{IsPlutusData, PlutusData}; use crate::v1::crypto::LedgerBytes; diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index 5afcf2a..e3f73b9 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -7,6 +7,7 @@ use lbr_prelude::json::Json; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate as plutus_ledger_api; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::IsPlutusData; diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 44c4533..2ef775e 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -16,6 +16,7 @@ use super::{ value::{CurrencySymbol, Value}, }; +use crate as plutus_ledger_api; use crate::csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}; use crate::{ csl::pla_to_csl::{TryFromPLAError, TryToCSL}, diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 88ce277..4c34c0c 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "lbf")] use serde_json; +use crate as plutus_ledger_api; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; diff --git a/plutus-ledger-api/src/v2/datum.rs b/plutus-ledger-api/src/v2/datum.rs index 9a3ec6c..2afce83 100644 --- a/plutus-ledger-api/src/v2/datum.rs +++ b/plutus-ledger-api/src/v2/datum.rs @@ -7,6 +7,7 @@ use lbr_prelude::json::{self, Error, Json}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate as plutus_ledger_api; pub use crate::v1::datum::{Datum, DatumHash}; use crate::{ csl::{ @@ -16,6 +17,7 @@ use crate::{ plutus_data::IsPlutusData, }; +// use crate as plutus_data/ ///////////////// // OutputDatum // ///////////////// diff --git a/plutus-ledger-api/src/v2/transaction.rs b/plutus-ledger-api/src/v2/transaction.rs index 2b2fab0..45c1c5e 100644 --- a/plutus-ledger-api/src/v2/transaction.rs +++ b/plutus-ledger-api/src/v2/transaction.rs @@ -9,6 +9,7 @@ use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate as plutus_ledger_api; use crate::csl::csl_to_pla::{FromCSL, TryFromCSL, TryFromCSLError, TryToPLA}; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; use crate::plutus_data::IsPlutusData; From 84f92b6a7920e2dddfca37c0a156273f1bccd401 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 20:29:32 +0800 Subject: [PATCH 18/38] remove plutus-data --- flake.nix | 1 - plutus-data/.envrc | 1 - plutus-data/Cargo.lock | 657 ------------------ plutus-data/Cargo.toml | 19 - plutus-data/build.nix | 19 - plutus-data/src/is_plutus_data/aux.rs | 66 -- plutus-data/src/is_plutus_data/instances.rs | 292 -------- .../src/is_plutus_data/is_plutus_data.rs | 22 - plutus-data/src/is_plutus_data/mod.rs | 3 - plutus-data/src/lib.rs | 8 - plutus-data/src/plutus_data.rs | 183 ----- plutus-ledger-api/build.nix | 1 - 12 files changed, 1272 deletions(-) delete mode 100644 plutus-data/.envrc delete mode 100644 plutus-data/Cargo.lock delete mode 100644 plutus-data/Cargo.toml delete mode 100644 plutus-data/build.nix delete mode 100644 plutus-data/src/is_plutus_data/aux.rs delete mode 100644 plutus-data/src/is_plutus_data/instances.rs delete mode 100644 plutus-data/src/is_plutus_data/is_plutus_data.rs delete mode 100644 plutus-data/src/is_plutus_data/mod.rs delete mode 100644 plutus-data/src/lib.rs delete mode 100644 plutus-data/src/plutus_data.rs diff --git a/flake.nix b/flake.nix index 29f46ea..8d68e4d 100644 --- a/flake.nix +++ b/flake.nix @@ -24,7 +24,6 @@ ./plutus-ledger-api/build.nix ./is-plutus-data-derive/build.nix - ./plutus-data/build.nix ]; debug = true; systems = [ "x86_64-linux" "x86_64-darwin" ]; diff --git a/plutus-data/.envrc b/plutus-data/.envrc deleted file mode 100644 index 6841e87..0000000 --- a/plutus-data/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake .#dev-plutus-data-rust diff --git a/plutus-data/Cargo.lock b/plutus-data/Cargo.lock deleted file mode 100644 index 690b993..0000000 --- a/plutus-data/Cargo.lock +++ /dev/null @@ -1,657 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "dissimilar" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "hashbrown" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "is-plutus-data-derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "thiserror", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lbr-prelude" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21471892874c4667636a067ed7a158b9691178988a4c5988585e1010e9b5817d" -dependencies = [ - "data-encoding", - "lbr-prelude-derive", - "num-bigint", - "proptest", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "lbr-prelude-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370d0aa0809ee84ccf7c6d84ae2d6ac97b84cb1337b3d145101bcf6a7319deac" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "trybuild", -] - -[[package]] -name = "libc" -version = "0.2.160" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "plutus-data" -version = "0.1.0" -dependencies = [ - "data-encoding", - "is-plutus-data-derive", - "lbr-prelude", - "num-bigint", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proptest" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - -[[package]] -name = "syn" -version = "2.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" -dependencies = [ - "cfg-if", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "trybuild" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8923cde76a6329058a86f04d033f0945a2c6df8b94093512e4ab188b3e3a8950" -dependencies = [ - "dissimilar", - "glob", - "serde", - "serde_derive", - "serde_json", - "termcolor", - "toml", -] - -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/plutus-data/Cargo.toml b/plutus-data/Cargo.toml deleted file mode 100644 index ade6890..0000000 --- a/plutus-data/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "plutus-data" -version = "0.1.0" -edition = "2021" - -[dependencies] -serde = { version = "^1.0.189", features = ["derive"], optional = true } -serde_json = { version = "1.0.128", optional = true } -num-bigint = "~0.4" -is-plutus-data-derive = { path = ".extras/is-plutus-data-derive-0", optional = true } -lbr-prelude = { version = "0.1.1", optional = true } -data-encoding = { version = "2.6.0", optional = true } -thiserror = "1.0.64" - -[features] -default = [] -serde = ["dep:serde", "num-bigint/serde", "dep:serde_json"] -lbf = ["dep:lbr-prelude", "dep:serde_json", "dep:data-encoding"] -derive = ["dep:is-plutus-data-derive"] diff --git a/plutus-data/build.nix b/plutus-data/build.nix deleted file mode 100644 index 33b0093..0000000 --- a/plutus-data/build.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ inputs, ... }: { - perSystem = { config, system, ... }: - let - rustFlake = - inputs.flake-lang.lib.${system}.rustFlake { - src = ./.; - version = "0"; - crateName = "plutus-data"; - devShellHook = config.settings.shell.hook; - cargoNextestExtraArgs = "--all-features"; - extraSources = [ - config.packages.is-plutus-data-derive-rust-src - ]; - }; - in - { - inherit (rustFlake) packages checks devShells; - }; -} diff --git a/plutus-data/src/is_plutus_data/aux.rs b/plutus-data/src/is_plutus_data/aux.rs deleted file mode 100644 index b793f7f..0000000 --- a/plutus-data/src/is_plutus_data/aux.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::{PlutusData, PlutusDataError, PlutusType}; - -/// Given a vector of PlutusData, parse it as an array whose length is known at -/// compile time. -/// -/// This function is used by the derive macro. -pub fn parse_fixed_len_constr_fields( - v: &[PlutusData], -) -> Result<&[PlutusData; LEN], PlutusDataError> { - v.try_into() - .map_err(|_| PlutusDataError::UnexpectedListLength { - got: v.len(), - wanted: LEN, - }) -} - -/// Given a PlutusData, parse it as PlutusData::Constr and its tag as u32. Return -/// the u32 tag and fields. -/// -/// This function is used by the derive macro. -pub fn parse_constr(data: &PlutusData) -> Result<(u32, &Vec), PlutusDataError> { - match data { - PlutusData::Constr(tag, fields) => u32::try_from(tag) - .map_err(|err| PlutusDataError::UnexpectedPlutusInvariant { - got: err.to_string(), - wanted: "Constr bigint tag within u32 range".into(), - }) - .map(|tag| (tag, fields)), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Constr, - got: PlutusType::from(data), - }), - } -} - -/// Given a PlutusData, parse it as PlutusData::Constr and verify its tag. -/// -/// This function is used by the derive macro. -pub fn parse_constr_with_tag( - data: &PlutusData, - expected_tag: u32, -) -> Result<&Vec, PlutusDataError> { - let (tag, fields) = parse_constr(data)?; - - if tag != expected_tag { - Err(PlutusDataError::UnexpectedPlutusInvariant { - got: tag.to_string(), - wanted: format!("Constr with tag {}", expected_tag), - }) - } else { - Ok(fields) - } -} - -/// Given a PlutusData, parse it as PlutusData::List. Return the plutus data list. -/// -/// This function is used by the derive macro. -pub fn parse_list(data: &PlutusData) -> Result<&Vec, PlutusDataError> { - match data { - PlutusData::List(list_of_plutus_data) => Ok(list_of_plutus_data), - _ => Err(PlutusDataError::UnexpectedPlutusType { - got: PlutusType::from(data), - wanted: PlutusType::List, - }), - } -} diff --git a/plutus-data/src/is_plutus_data/instances.rs b/plutus-data/src/is_plutus_data/instances.rs deleted file mode 100644 index 5c7838a..0000000 --- a/plutus-data/src/is_plutus_data/instances.rs +++ /dev/null @@ -1,292 +0,0 @@ -use std::collections::{BTreeMap, BTreeSet}; - -use num_bigint::BigInt; - -use crate::{IsPlutusData, PlutusData, PlutusDataError, PlutusType}; - -use super::aux::{parse_constr, parse_constr_with_tag, parse_fixed_len_constr_fields, parse_list}; - -impl IsPlutusData for PlutusData { - fn to_plutus_data(&self) -> PlutusData { - self.clone() - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - Ok(plutus_data.clone()) - } -} - -// MARK: Orphan Instances - -impl IsPlutusData for BigInt { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Integer(self.clone()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Integer(int) => Ok(int.clone()), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Integer, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for Vec { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Bytes(self.clone()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Bytes(bytes) => Ok(bytes.clone()), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(plutus_data), - }), - } - } -} - -const BOOL_FALSE_TAG: u32 = 0; -const BOOL_TRUE_TAG: u32 = 1; - -impl IsPlutusData for bool { - fn to_plutus_data(&self) -> PlutusData { - if *self { - PlutusData::Constr(BOOL_TRUE_TAG.into(), vec![]) - } else { - PlutusData::Constr(BOOL_FALSE_TAG.into(), vec![]) - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let (tag, fields) = parse_constr(plutus_data)?; - let [] = parse_fixed_len_constr_fields::<0>(fields)?; - match tag { - BOOL_TRUE_TAG => Ok(true), - BOOL_FALSE_TAG => Ok(false), - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: format!("Constr with tag {BOOL_TRUE_TAG} or {BOOL_FALSE_TAG}"), - got: tag.to_string(), - }), - } - } -} - -impl IsPlutusData for String { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Bytes(self.as_bytes().into()) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Bytes(bytes) => String::from_utf8(bytes.clone()).map_err(|err| { - PlutusDataError::InternalError(format!( - "Couldn't convert Plutus bytes to String: {:?}", - err - )) - }), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Bytes, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for char { - fn to_plutus_data(&self) -> PlutusData { - String::from(*self).to_plutus_data() - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - String::from_plutus_data(plutus_data).and_then(|str| { - let mut chars = str.chars(); - let ch = chars.next(); - let rest = chars.next(); - match (ch, rest) { - (Some(ch), None) => Ok(ch), - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - got: "string".to_owned(), - wanted: "char".to_owned(), - }), - } - }) - } -} - -const OPTION_SOME_TAG: u32 = 0; -const OPTION_NONE_TAG: u32 = 1; - -impl IsPlutusData for Option -where - T: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - match self { - Some(val) => PlutusData::Constr(OPTION_SOME_TAG.into(), vec![val.to_plutus_data()]), - None => PlutusData::Constr(OPTION_NONE_TAG.into(), vec![]), - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let (tag, fields) = parse_constr(plutus_data)?; - - match tag { - OPTION_SOME_TAG => { - let [data] = parse_fixed_len_constr_fields::<1>(fields)?; - Ok(Some(T::from_plutus_data(data)?)) - } - OPTION_NONE_TAG => { - let [] = parse_fixed_len_constr_fields::<0>(fields)?; - Ok(None) - } - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: format!("Constr with tag {OPTION_SOME_TAG} or {OPTION_NONE_TAG}"), - got: tag.to_string(), - }), - } - } -} - -const RESULT_ERR_TAG: u32 = 0; -const RESULT_OK_TAG: u32 = 1; - -impl IsPlutusData for Result -where - T: IsPlutusData, - E: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - match self { - Err(err) => PlutusData::Constr(RESULT_ERR_TAG.into(), vec![err.to_plutus_data()]), - Ok(val) => PlutusData::Constr(RESULT_OK_TAG.into(), vec![val.to_plutus_data()]), - } - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let (tag, fields) = parse_constr(plutus_data)?; - let [field] = parse_fixed_len_constr_fields::<1>(fields)?; - - match tag { - RESULT_ERR_TAG => Ok(Err(E::from_plutus_data(field)?)), - RESULT_OK_TAG => Ok(Ok(T::from_plutus_data(field)?)), - _ => Err(PlutusDataError::UnexpectedPlutusInvariant { - wanted: format!("Constr with tag {RESULT_ERR_TAG} or {RESULT_OK_TAG}"), - got: tag.to_string(), - }), - } - } -} - -impl IsPlutusData for Vec -where - T: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - let values = self - .iter() - .map(|val| val.to_plutus_data()) - .collect::>(); - - PlutusData::List(values) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let list = parse_list(plutus_data)?; - list.iter().map(T::from_plutus_data).collect() - } -} - -impl IsPlutusData for BTreeSet -where - T: IsPlutusData + Eq + Ord, -{ - fn to_plutus_data(&self) -> PlutusData { - let set = self - .iter() - .map(|val| val.to_plutus_data()) - .collect::>(); - - PlutusData::List(set) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::List(vec) => vec - .iter() - .map(|val| T::from_plutus_data(val)) - .collect::>(), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::List, - got: PlutusType::from(plutus_data), - }), - } - } -} - -impl IsPlutusData for BTreeMap -where - K: IsPlutusData + Eq + Ord, - V: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - let assoc_map = self - .iter() - .map(|(key, val)| (key.to_plutus_data(), val.to_plutus_data())) - .collect::>(); - - PlutusData::Map(assoc_map) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - match plutus_data { - PlutusData::Map(dict) => dict - .iter() - .map(|(key, val)| Ok((K::from_plutus_data(key)?, V::from_plutus_data(val)?))) - .collect::>(), - _ => Err(PlutusDataError::UnexpectedPlutusType { - wanted: PlutusType::Map, - got: PlutusType::from(plutus_data), - }), - } - } -} - -const UNIT_TAG: u32 = 0; - -impl IsPlutusData for () { - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr(UNIT_TAG.into(), vec![]) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(plutus_data, UNIT_TAG)?; - let [] = parse_fixed_len_constr_fields::<0>(fields)?; - Ok(()) - } -} - -const PAIR_TAG: u32 = 0; - -impl IsPlutusData for (A, B) -where - A: IsPlutusData, - B: IsPlutusData, -{ - fn to_plutus_data(&self) -> PlutusData { - PlutusData::Constr( - BigInt::from(PAIR_TAG), - vec![self.0.to_plutus_data(), self.1.to_plutus_data()], - ) - } - - fn from_plutus_data(plutus_data: &PlutusData) -> Result { - let fields = parse_constr_with_tag(plutus_data, PAIR_TAG)?; - let [a, b] = parse_fixed_len_constr_fields::<2>(fields)?; - Ok((A::from_plutus_data(a)?, B::from_plutus_data(b)?)) - } -} diff --git a/plutus-data/src/is_plutus_data/is_plutus_data.rs b/plutus-data/src/is_plutus_data/is_plutus_data.rs deleted file mode 100644 index 4f73c15..0000000 --- a/plutus-data/src/is_plutus_data/is_plutus_data.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::{PlutusData, PlutusType}; - -pub trait IsPlutusData { - fn to_plutus_data(&self) -> PlutusData; - - fn from_plutus_data(plutus_data: &PlutusData) -> Result - where - Self: Sized; -} - -// TODO(chfanghr): improve error reporting -#[derive(Clone, Debug, thiserror::Error)] -pub enum PlutusDataError { - #[error("Expected a PlutusData type {wanted:?}, but got {got:?}")] - UnexpectedPlutusType { got: PlutusType, wanted: PlutusType }, - #[error("Expected a PlutusData type as {wanted:?}, but got {got:?}")] - UnexpectedPlutusInvariant { got: String, wanted: String }, - #[error("Expected a Plutus List with {wanted:?} elements, but got {got:?} elements")] - UnexpectedListLength { got: usize, wanted: usize }, - #[error("Some internal error happened: {0}")] - InternalError(String), -} diff --git a/plutus-data/src/is_plutus_data/mod.rs b/plutus-data/src/is_plutus_data/mod.rs deleted file mode 100644 index 526bebf..0000000 --- a/plutus-data/src/is_plutus_data/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod aux; -mod instances; -pub mod is_plutus_data; diff --git a/plutus-data/src/lib.rs b/plutus-data/src/lib.rs deleted file mode 100644 index c2c607a..0000000 --- a/plutus-data/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod is_plutus_data; -pub mod plutus_data; - -#[cfg(feature = "derive")] -pub use is_plutus_data_derive::IsPlutusData; - -pub use is_plutus_data::is_plutus_data::{IsPlutusData, PlutusDataError}; -pub use plutus_data::{PlutusData, PlutusType}; diff --git a/plutus-data/src/plutus_data.rs b/plutus-data/src/plutus_data.rs deleted file mode 100644 index 9c3cbfc..0000000 --- a/plutus-data/src/plutus_data.rs +++ /dev/null @@ -1,183 +0,0 @@ -use num_bigint::BigInt; - -#[cfg(feature = "lbf")] -use data_encoding::HEXLOWER; -#[cfg(feature = "lbf")] -use lbr_prelude::error::Error; -#[cfg(feature = "lbf")] -use lbr_prelude::json::{ - case_json_constructor, case_json_object, json_constructor, json_object, Json, -}; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -/// Data representation of on-chain data such as Datums and Redeemers -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum PlutusData { - Constr(BigInt, Vec), - Map(Vec<(PlutusData, PlutusData)>), - List(Vec), - Integer(BigInt), - Bytes(Vec), -} - -#[derive(Clone, Debug)] -pub enum PlutusType { - Constr, - Map, - List, - Integer, - Bytes, -} - -impl From<&PlutusData> for PlutusType { - fn from(plutus_data: &PlutusData) -> Self { - match plutus_data { - PlutusData::Constr(_, _) => PlutusType::Constr, - PlutusData::Map(_) => PlutusType::Map, - PlutusData::List(_) => PlutusType::List, - PlutusData::Integer(_) => PlutusType::Integer, - PlutusData::Bytes(_) => PlutusType::Bytes, - } - } -} - -impl PlutusData { - pub fn constr(tag: u32, fields: Vec) -> Self { - PlutusData::Constr(BigInt::from(tag), fields) - } - - pub fn map(fields: Vec<(PlutusData, PlutusData)>) -> Self { - PlutusData::Map(fields) - } - - pub fn list(fields: Vec) -> Self { - PlutusData::List(fields) - } - - pub fn integer(value: u32) -> Self { - PlutusData::Integer(BigInt::from(value)) - } - - pub fn bytes(value: Vec) -> Self { - PlutusData::Bytes(value) - } -} - -#[cfg(feature = "lbf")] -impl Json for PlutusData { - fn to_json(&self) -> serde_json::Value { - match self { - PlutusData::Constr(index, fields) => json_constructor( - "Constr", - vec![json_object(vec![ - ("index".to_string(), index.to_json()), - ("fields".to_string(), fields.to_json()), - ])], - ), - PlutusData::Map(map) => json_constructor("Map", vec![map.to_json()]), - PlutusData::List(list) => json_constructor("List", vec![list.to_json()]), - PlutusData::Integer(int) => json_constructor("Integer", vec![int.to_json()]), - PlutusData::Bytes(bytes) => { - json_constructor("Bytes", vec![String::to_json(&HEXLOWER.encode(bytes))]) - } - } - } - - fn from_json(value: &serde_json::Value) -> Result { - case_json_constructor( - "PlutusV1.PlutusData", - vec![ - ( - "Constr", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => case_json_object( - |obj| { - let index = obj.get("index").ok_or(Error::UnexpectedFieldName { - wanted: "index".to_owned(), - got: obj.keys().cloned().collect(), - parser: "PlutusV1.PlutusData".to_owned(), - })?; - - let fields = - obj.get("fields").ok_or(Error::UnexpectedFieldName { - wanted: "fields".to_owned(), - got: obj.keys().cloned().collect(), - parser: "PlutusV1.PlutusData".to_owned(), - })?; - Ok(PlutusData::Constr( - BigInt::from_json(index)?, - >::from_json(fields)?, - )) - }, - val, - ), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Map", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::Map(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "List", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::List(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Integer", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => Ok(PlutusData::Integer(Json::from_json(val)?)), - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ( - "Bytes", - Box::new(|ctor_fields| match &ctor_fields[..] { - [val] => { - let bytes = String::from_json(val).and_then(|str| { - HEXLOWER.decode(&str.into_bytes()).map_err(|_| { - Error::UnexpectedJsonInvariant { - wanted: "base16 string".to_owned(), - got: "unexpected string".to_owned(), - parser: "Plutus.V1.Bytes".to_owned(), - } - }) - })?; - Ok(PlutusData::Bytes(bytes)) - } - _ => Err(Error::UnexpectedArrayLength { - wanted: 1, - got: ctor_fields.len(), - parser: "PlutusV1.PlutusData".to_owned(), - }), - }), - ), - ], - value, - ) - } -} diff --git a/plutus-ledger-api/build.nix b/plutus-ledger-api/build.nix index 4fa2517..67602f5 100644 --- a/plutus-ledger-api/build.nix +++ b/plutus-ledger-api/build.nix @@ -13,7 +13,6 @@ ]; extraSources = [ config.packages.is-plutus-data-derive-rust-src - config.packages.plutus-data-rust-src ]; }; From e84bbb02284e27f4af2dc955632ce89f495da692 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 20:40:02 +0800 Subject: [PATCH 19/38] fogot to commit .envrc --- is-plutus-data-derive/.envrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 is-plutus-data-derive/.envrc diff --git a/is-plutus-data-derive/.envrc b/is-plutus-data-derive/.envrc new file mode 100644 index 0000000..f7f6ae5 --- /dev/null +++ b/is-plutus-data-derive/.envrc @@ -0,0 +1 @@ +use flake ../#dev-is-plutus-data-derive-rust From 32b00e6c6630b59ea3d95dc319de3b76ee8ae13f Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 20:44:41 +0800 Subject: [PATCH 20/38] update changelog --- plutus-ledger-api/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index 385b92b..325603b 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -8,6 +8,8 @@ Changelog](https://keepachangelog.com/en/1.1.0). ### Added +- Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) + ### Changed ### Removed From 2fd89e1bcf3d0fa7a239ce14b5f261e274250473 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 17:07:51 +0800 Subject: [PATCH 21/38] add v3 types --- plutus-ledger-api/src/lib.rs | 1 + plutus-ledger-api/src/v1/value.rs | 10 ++ plutus-ledger-api/src/v3/mod.rs | 2 + plutus-ledger-api/src/v3/ratio.rs | 29 ++++ plutus-ledger-api/src/v3/transaction.rs | 217 ++++++++++++++++++++++++ 5 files changed, 259 insertions(+) create mode 100644 plutus-ledger-api/src/v3/mod.rs create mode 100644 plutus-ledger-api/src/v3/ratio.rs create mode 100644 plutus-ledger-api/src/v3/transaction.rs diff --git a/plutus-ledger-api/src/lib.rs b/plutus-ledger-api/src/lib.rs index ac37079..e788cad 100644 --- a/plutus-ledger-api/src/lib.rs +++ b/plutus-ledger-api/src/lib.rs @@ -6,6 +6,7 @@ pub mod lamval; pub mod plutus_data; pub mod v1; pub mod v2; +pub mod v3; #[cfg(feature = "lbf")] pub use lbr_prelude::json; pub mod csl; diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 4c34c0c..045d49d 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -672,3 +672,13 @@ mod test { assert_eq!(token_name.try_into_string().unwrap(), name); } } + +//////////////// +// Lovelace // +//////////////// + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct Lovelace(pub BigInt); diff --git a/plutus-ledger-api/src/v3/mod.rs b/plutus-ledger-api/src/v3/mod.rs new file mode 100644 index 0000000..8c73a0c --- /dev/null +++ b/plutus-ledger-api/src/v3/mod.rs @@ -0,0 +1,2 @@ +pub mod ratio; +pub mod transaction; diff --git a/plutus-ledger-api/src/v3/ratio.rs b/plutus-ledger-api/src/v3/ratio.rs new file mode 100644 index 0000000..1433d52 --- /dev/null +++ b/plutus-ledger-api/src/v3/ratio.rs @@ -0,0 +1,29 @@ +#[cfg(feature = "lbf")] +use lbr_prelude::json::Json; +use num_bigint::BigInt; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; + +// TODO(chfanghr): maintain the invariants mentioned here: https://github.com/IntersectMBO/plutus/blob/master/plutus-tx/src/PlutusTx/Ratio.hs#L65-L68 +/// Represents an arbitrary-precision ratio. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct Rational(pub BigInt, pub BigInt); + +impl IsPlutusData for Rational { + fn to_plutus_data(&self) -> PlutusData { + (self.0.clone(), self.1.clone()).to_plutus_data() + } + + fn from_plutus_data(plutus_data: &PlutusData) -> Result + where + Self: Sized, + { + let (n, d) = IsPlutusData::from_plutus_data(plutus_data)?; + + Ok(Self(n, d)) + } +} diff --git a/plutus-ledger-api/src/v3/transaction.rs b/plutus-ledger-api/src/v3/transaction.rs new file mode 100644 index 0000000..cb54fb4 --- /dev/null +++ b/plutus-ledger-api/src/v3/transaction.rs @@ -0,0 +1,217 @@ +#[cfg(feature = "lbf")] +use lbr_prelude::json::Json; +use num_bigint::BigInt; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +use crate::{ + self as plutus_ledger_api, + plutus_data::{IsPlutusData, PlutusData}, + v1::{ + address::{Credential, StakingCredential}, + assoc_map::AssocMap, + crypto::{PaymentPubKeyHash, StakePubKeyHash}, + datum::{Datum, DatumHash}, + redeemer::Redeemer, + script::ScriptHash, + transaction::{POSIXTimeRange, TransactionHash, TransactionInput}, + value::{CurrencySymbol, Lovelace, Value}, + }, + v2::transaction::{TransactionOutput, TxInInfo}, +}; + +use super::ratio::Rational; + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct ColdCommitteeCredential(pub Credential); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct HotCommitteeCredential(pub Credential); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct DRepCredential(pub Credential); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum DRep { + DRep(DRepCredential), + AlwaysAbstain, + AlwaysNoConfidence, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum Delegatee { + Stake(StakePubKeyHash), + Vote(DRep), + StakeVote(StakePubKeyHash, DRep), +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum TxCert { + RegStaking(StakingCredential, Option), + UnRegStaking(StakingCredential, Option), + DelegStaking(StakingCredential, Delegatee), + RegDeleg(StakingCredential, Delegatee, Lovelace), + RegDRep(DRepCredential, Lovelace), + UpdateDRep(DRepCredential), + UnRegDRep(DRepCredential, Lovelace), + PoolRegister(PaymentPubKeyHash, PaymentPubKeyHash), + PoolRetire(PaymentPubKeyHash, BigInt), + AuthHotCommittee(ColdCommitteeCredential, HotCommitteeCredential), + ResignColdCommittee(ColdCommitteeCredential), +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum Voter { + CommitteeVoter(HotCommitteeCredential), + DRepVoter(DRepCredential), + StakePoolVoter(PaymentPubKeyHash), +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum Vote { + VoteNo, + VoteYes, + Abstain, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct GovernanceActionId { + pub tx_id: TransactionHash, + pub gov_action_id: BigInt, +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct Committee { + pub members: AssocMap, + pub quorum: Rational, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct Constitution { + pub constitution_script: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct ProtocolVersion { + pub major: BigInt, + pub minor: BigInt, +} + +// TODO(chfanghr): check invariant according to https://github.com/IntersectMBO/plutus/blob/bb33f082d26f8b6576d3f0d423be53eddfb6abd8/plutus-ledger-api/src/PlutusLedgerApi/V3/Contexts.hs#L338-L364 +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Newtype"] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct ChangeParameters(pub PlutusData); + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum GovernanceAction { + ParameterChange( + Option, + ChangeParameters, + Option, + ), + HardForkInitiation(Option, ProtocolVersion), + TreasuryWithdrawals(AssocMap, Option), + NoConfidence(Option), + UpdateCommittee( + Option, + Vec, + AssocMap, + ), + NewConstitution(Option, Constitution), + InfoAction, +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct ProtocolProcedure { + pub deposit: Lovelace, + pub return_addr: Credential, + pub governance_action: GovernanceAction, +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum ScriptPurpose { + Minting(CurrencySymbol), + Spending(TransactionInput), + Rewarding(Credential), + Certifying(BigInt, TxCert), + Voting(Voter), + Proposing(BigInt, ProtocolProcedure), +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub enum ScriptInfo { + Minting(CurrencySymbol), + Spending(TransactionInput, Option), + Rewarding(Credential), + Certifying(BigInt, TxCert), + Voting(Voter), + Proposing(BigInt, ProtocolProcedure), +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct TransactionInfo { + pub inputs: Vec, + pub reference_inputs: Vec, + pub outputs: Vec, + pub fee: Lovelace, + pub mint: Value, + pub tx_certs: Vec, + pub wdrl: AssocMap, + pub valid_range: POSIXTimeRange, + pub signatories: Vec, + pub redeemers: AssocMap, + pub datums: AssocMap, + pub id: TransactionHash, + pub votes: AssocMap>, + pub protocol_procedures: Vec, + pub current_treasury_amount: Option, + pub treasury_donation: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "lbf", derive(Json))] +pub struct ScriptContext { + pub tx_info: TransactionInfo, + pub redeemer: Redeemer, + pub script_info: ScriptInfo, +} From 98953669d1581a2d12841a87494e7e9f383ab878 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 18:20:42 +0800 Subject: [PATCH 22/38] implement generators for v3 types --- .../src/generators/correct/mod.rs | 1 + .../src/generators/correct/v1.rs | 11 +- .../src/generators/correct/v3.rs | 266 ++++++++++++++++++ 3 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 plutus-ledger-api/src/generators/correct/v3.rs diff --git a/plutus-ledger-api/src/generators/correct/mod.rs b/plutus-ledger-api/src/generators/correct/mod.rs index db042bf..6903246 100644 --- a/plutus-ledger-api/src/generators/correct/mod.rs +++ b/plutus-ledger-api/src/generators/correct/mod.rs @@ -2,3 +2,4 @@ pub mod primitive; pub mod v1; pub mod v2; +pub mod v3; diff --git a/plutus-ledger-api/src/generators/correct/v1.rs b/plutus-ledger-api/src/generators/correct/v1.rs index 85b6c66..37d08a6 100644 --- a/plutus-ledger-api/src/generators/correct/v1.rs +++ b/plutus-ledger-api/src/generators/correct/v1.rs @@ -8,7 +8,7 @@ use crate::v1::address::{ Address, CertificateIndex, ChainPointer, Credential, Slot, StakingCredential, TransactionIndex, }; use crate::v1::assoc_map::AssocMap; -use crate::v1::crypto::{Ed25519PubKeyHash, LedgerBytes, PaymentPubKeyHash}; +use crate::v1::crypto::{Ed25519PubKeyHash, LedgerBytes, PaymentPubKeyHash, StakePubKeyHash}; use crate::v1::datum::{Datum, DatumHash}; use crate::v1::interval::{Extended, Interval, LowerBound, PlutusInterval, UpperBound}; use crate::v1::redeemer::{Redeemer, RedeemerHash}; @@ -17,6 +17,7 @@ use crate::v1::transaction::{ DCert, POSIXTime, ScriptContext, ScriptPurpose, TransactionHash, TransactionInfo, TransactionInput, TransactionOutput, TxInInfo, }; +use crate::v1::value::Lovelace; use crate::v2::value::{AssetClass, CurrencySymbol, TokenName, Value}; use num_bigint::BigInt; use proptest::collection::btree_map; @@ -402,3 +403,11 @@ pub fn arb_script_context() -> impl Strategy { (arb_script_purpose(), arb_transaction_info()) .prop_map(|(purpose, tx_info)| ScriptContext { purpose, tx_info }) } + +pub fn arb_lovelace() -> impl Strategy { + arb_natural(1).prop_map(Lovelace) +} + +pub fn arb_stake_pub_key_hash() -> impl Strategy { + arb_ed25519_pub_key_hash().prop_map(StakePubKeyHash) +} diff --git a/plutus-ledger-api/src/generators/correct/v3.rs b/plutus-ledger-api/src/generators/correct/v3.rs new file mode 100644 index 0000000..d5afb49 --- /dev/null +++ b/plutus-ledger-api/src/generators/correct/v3.rs @@ -0,0 +1,266 @@ +use lbr_prelude::generators::correct::arb_integer; +use proptest::{ + collection::vec, + option, + prelude::{Just, Strategy}, + prop_oneof, +}; + +use crate::{ + generators::correct::v1::{ + arb_currency_symbol, arb_datum, arb_lovelace, arb_payment_pub_key_hash, + arb_stake_pub_key_hash, arb_staking_credential, arb_transaction_input, + }, + v3::{ + ratio::Rational, + transaction::{ + ChangeParameters, ColdCommitteeCredential, Committee, Constitution, DRep, + DRepCredential, Delegatee, GovernanceAction, GovernanceActionId, + HotCommitteeCredential, ProtocolProcedure, ProtocolVersion, ScriptContext, ScriptInfo, + ScriptPurpose, TransactionInfo, TxCert, Vote, Voter, + }, + }, +}; + +use super::{ + primitive::arb_natural, + v1::{ + arb_assoc_map, arb_credential, arb_datum_hash, arb_plutus_data, + arb_plutus_interval_posix_time, arb_redeemer, arb_script_hash, arb_transaction_hash, + arb_value, + }, + v2::{arb_transaction_output, arb_tx_in_info}, +}; + +pub fn arb_cold_committee_credential() -> impl Strategy { + arb_credential().prop_map(ColdCommitteeCredential) +} + +pub fn arb_hot_committee_credential() -> impl Strategy { + arb_credential().prop_map(HotCommitteeCredential) +} + +pub fn arb_d_rep_credential() -> impl Strategy { + arb_credential().prop_map(DRepCredential) +} + +pub fn arb_d_rep() -> impl Strategy { + prop_oneof![ + arb_d_rep_credential().prop_map(DRep::DRep), + Just(DRep::AlwaysAbstain), + Just(DRep::AlwaysNoConfidence) + ] +} + +pub fn arb_delegatee() -> impl Strategy { + prop_oneof![ + arb_stake_pub_key_hash().prop_map(Delegatee::Stake), + arb_d_rep().prop_map(Delegatee::Vote), + (arb_stake_pub_key_hash(), arb_d_rep()).prop_map(|(h, r)| Delegatee::StakeVote(h, r)) + ] +} + +pub fn arb_tx_cert() -> impl Strategy { + prop_oneof![ + (arb_staking_credential(), option::of(arb_lovelace())) + .prop_map(|(c, l)| TxCert::RegStaking(c, l)), + (arb_staking_credential(), option::of(arb_lovelace())) + .prop_map(|(c, l)| TxCert::UnRegStaking(c, l)), + (arb_staking_credential(), arb_delegatee()).prop_map(|(c, d)| TxCert::DelegStaking(c, d)), + (arb_staking_credential(), arb_delegatee(), arb_lovelace()) + .prop_map(|(c, d, l)| TxCert::RegDeleg(c, d, l)), + (arb_d_rep_credential(), arb_lovelace()).prop_map(|(d, l)| TxCert::RegDRep(d, l)), + arb_d_rep_credential().prop_map(TxCert::UpdateDRep), + (arb_d_rep_credential(), arb_lovelace()).prop_map(|(d, l)| TxCert::UnRegDRep(d, l)), + (arb_payment_pub_key_hash(), arb_payment_pub_key_hash()) + .prop_map(|(pkh1, pkh2)| TxCert::PoolRegister(pkh1, pkh2)), + (arb_payment_pub_key_hash(), arb_integer()).prop_map(|(pkh, i)| TxCert::PoolRetire(pkh, i)), + ( + arb_cold_committee_credential(), + arb_hot_committee_credential() + ) + .prop_map(|(c, h)| TxCert::AuthHotCommittee(c, h)), + arb_cold_committee_credential().prop_map(TxCert::ResignColdCommittee) + ] +} + +pub fn arb_voter() -> impl Strategy { + prop_oneof![ + arb_hot_committee_credential().prop_map(Voter::CommitteeVoter), + arb_d_rep_credential().prop_map(Voter::DRepVoter), + arb_payment_pub_key_hash().prop_map(Voter::StakePoolVoter) + ] +} + +pub fn arb_vote() -> impl Strategy { + prop_oneof![Just(Vote::VoteNo), Just(Vote::VoteYes), Just(Vote::Abstain)] +} + +pub fn arb_governance_action_id() -> impl Strategy { + (arb_transaction_hash(), arb_integer()).prop_map(|(tx_id, gov_action_id)| GovernanceActionId { + tx_id, + gov_action_id, + }) +} + +pub fn arb_committee() -> impl Strategy { + ( + arb_assoc_map(arb_cold_committee_credential(), arb_integer()), + arb_rational(), + ) + .prop_map(|(members, quorum)| Committee { members, quorum }) +} + +pub fn arb_rational() -> impl Strategy { + (arb_integer(), arb_integer()).prop_map(|(n, d)| Rational(n, d)) +} + +pub fn arb_constitution() -> impl Strategy { + option::of(arb_script_hash()).prop_map(|constitution_script| Constitution { + constitution_script, + }) +} + +pub fn arb_protocol_version() -> impl Strategy { + (arb_integer(), arb_integer()).prop_map(|(major, minor)| ProtocolVersion { major, minor }) +} + +pub fn arb_change_parameters() -> impl Strategy { + arb_plutus_data().prop_map(ChangeParameters) +} + +pub fn arb_governance_action() -> impl Strategy { + prop_oneof![ + ( + option::of(arb_governance_action_id()), + arb_change_parameters(), + option::of(arb_script_hash()) + ) + .prop_map(|(g, c, s)| GovernanceAction::ParameterChange(g, c, s)), + ( + option::of(arb_governance_action_id()), + arb_protocol_version() + ) + .prop_map(|(g, p)| GovernanceAction::HardForkInitiation(g, p)), + ( + arb_assoc_map(arb_credential(), arb_lovelace()), + option::of(arb_script_hash()) + ) + .prop_map(|(a, s)| GovernanceAction::TreasuryWithdrawals(a, s)), + option::of(arb_governance_action_id()).prop_map(GovernanceAction::NoConfidence), + ( + option::of(arb_governance_action_id()), + vec(arb_cold_committee_credential(), 5), + arb_assoc_map(arb_cold_committee_credential(), arb_integer()) + ) + .prop_map(|(g, c, cm)| GovernanceAction::UpdateCommittee(g, c, cm)), + (option::of(arb_governance_action_id()), arb_constitution()) + .prop_map(|(g, c)| GovernanceAction::NewConstitution(g, c)), + Just(GovernanceAction::InfoAction) + ] +} + +pub fn arb_protocol_procedure() -> impl Strategy { + (arb_lovelace(), arb_credential(), arb_governance_action()).prop_map(|(l, c, g)| { + ProtocolProcedure { + deposit: l, + return_addr: c, + governance_action: g, + } + }) +} + +pub fn arb_script_purpose() -> impl Strategy { + prop_oneof![ + arb_currency_symbol().prop_map(ScriptPurpose::Minting), + arb_transaction_input().prop_map(ScriptPurpose::Spending), + arb_credential().prop_map(ScriptPurpose::Rewarding), + (arb_integer(), arb_tx_cert()).prop_map(|(i, c)| ScriptPurpose::Certifying(i, c)), + arb_voter().prop_map(ScriptPurpose::Voting), + (arb_integer(), arb_protocol_procedure()).prop_map(|(i, p)| ScriptPurpose::Proposing(i, p)) + ] +} + +pub fn arb_script_info() -> impl Strategy { + prop_oneof![ + arb_currency_symbol().prop_map(ScriptInfo::Minting), + (arb_transaction_input(), option::of(arb_datum())) + .prop_map(|(i, d)| ScriptInfo::Spending(i, d)), + arb_credential().prop_map(ScriptInfo::Rewarding), + (arb_integer(), arb_tx_cert()).prop_map(|(i, c)| ScriptInfo::Certifying(i, c)), + arb_voter().prop_map(ScriptInfo::Voting), + (arb_integer(), arb_protocol_procedure()).prop_map(|(i, p)| ScriptInfo::Proposing(i, p)) + ] +} + +pub fn arb_transaction_info() -> impl Strategy { + ( + vec(arb_tx_in_info(), 5), + vec(arb_tx_in_info(), 5), + vec(arb_transaction_output(), 5), + arb_lovelace(), + arb_value(), + vec(arb_tx_cert(), 5), + arb_assoc_map(arb_staking_credential(), arb_natural(1)), + arb_plutus_interval_posix_time(), + vec(arb_payment_pub_key_hash(), 5), + arb_assoc_map(arb_script_purpose(), arb_redeemer()), + arb_assoc_map(arb_datum_hash(), arb_datum()), + // HACK(chfanghr): Strategy is not implemented for longer tuples + ( + arb_transaction_hash(), + arb_assoc_map( + arb_voter(), + arb_assoc_map(arb_governance_action_id(), arb_vote()), + ), + vec(arb_protocol_procedure(), 5), + option::of(arb_lovelace()), + option::of(arb_lovelace()), + ), + ) + .prop_map( + |( + inputs, + reference_inputs, + outputs, + fee, + mint, + tx_certs, + wdrl, + valid_range, + signatories, + redeemers, + datums, + (id, votes, protocol_procedures, current_treasury_amount, treasury_donation), + )| { + TransactionInfo { + inputs, + reference_inputs, + outputs, + fee, + mint, + tx_certs, + wdrl, + valid_range, + signatories, + redeemers, + datums, + id, + votes, + protocol_procedures, + current_treasury_amount, + treasury_donation, + } + }, + ) +} + +pub fn arb_script_context() -> impl Strategy { + (arb_transaction_info(), arb_redeemer(), arb_script_info()).prop_map( + |(tx_info, redeemer, script_info)| ScriptContext { + tx_info, + redeemer, + script_info, + }, + ) +} From 688be1ce1b7fb300b5e3d1082af0dbaa6065d08f Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 18:42:55 +0800 Subject: [PATCH 23/38] add property tests for v3 types --- .../src/generators/correct/v3.rs | 10 +- plutus-ledger-api/tests/lbf.rs | 104 +++++++++++++++ plutus-ledger-api/tests/plutus_data.rs | 124 ++++++++++++++++++ .../tests/serde.proptest-regressions | 15 --- plutus-ledger-api/tests/serde.rs | 103 +++++++++++++++ 5 files changed, 337 insertions(+), 19 deletions(-) delete mode 100644 plutus-ledger-api/tests/serde.proptest-regressions diff --git a/plutus-ledger-api/src/generators/correct/v3.rs b/plutus-ledger-api/src/generators/correct/v3.rs index d5afb49..518da68 100644 --- a/plutus-ledger-api/src/generators/correct/v3.rs +++ b/plutus-ledger-api/src/generators/correct/v3.rs @@ -1,4 +1,3 @@ -use lbr_prelude::generators::correct::arb_integer; use proptest::{ collection::vec, option, @@ -7,9 +6,12 @@ use proptest::{ }; use crate::{ - generators::correct::v1::{ - arb_currency_symbol, arb_datum, arb_lovelace, arb_payment_pub_key_hash, - arb_stake_pub_key_hash, arb_staking_credential, arb_transaction_input, + generators::correct::{ + primitive::arb_integer, + v1::{ + arb_currency_symbol, arb_datum, arb_lovelace, arb_payment_pub_key_hash, + arb_stake_pub_key_hash, arb_staking_credential, arb_transaction_input, + }, }, v3::{ ratio::Rational, diff --git a/plutus-ledger-api/tests/lbf.rs b/plutus-ledger-api/tests/lbf.rs index a71ac3e..36e0410 100644 --- a/plutus-ledger-api/tests/lbf.rs +++ b/plutus-ledger-api/tests/lbf.rs @@ -159,4 +159,108 @@ mod lb_json_roundtrip_tests { } } } + + mod v3 { + use super::from_to_json; + use plutus_ledger_api::generators::correct::v3::*; + use proptest::prelude::*; + + proptest! { + #[test] + fn test_cold_committee_credential(val in arb_cold_committee_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_hot_committee_credential(val in arb_hot_committee_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_d_rep_credential(val in arb_d_rep_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_delegatee(val in arb_delegatee()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_tx_cert(val in arb_tx_cert()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_voter(val in arb_voter()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_vote(val in arb_vote()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_governance_action_id(val in arb_governance_action_id()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_committee(val in arb_committee()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_rational(val in arb_rational()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_constitution(val in arb_constitution()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_protocol_version(val in arb_protocol_version()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_change_parameters(val in arb_change_parameters()) { + assert_eq!(val, from_to_json(&val)?) + } + + + #[test] + fn test_governance_action(val in arb_governance_action()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_protocol_procedure(val in arb_protocol_procedure()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_purpose(val in arb_script_purpose()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_info(val in arb_script_info()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_transaction_info(val in arb_transaction_info()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_context(val in arb_script_context()) { + assert_eq!(val, from_to_json(&val)?) + } + } + } } diff --git a/plutus-ledger-api/tests/plutus_data.rs b/plutus-ledger-api/tests/plutus_data.rs index 5d53f42..6626089 100644 --- a/plutus-ledger-api/tests/plutus_data.rs +++ b/plutus-ledger-api/tests/plutus_data.rs @@ -338,6 +338,12 @@ mod plutusdata_roundtrip_tests { fn v1_script_context(val in arb_script_context()) { assert_eq!(val, from_to_plutus_data(&val)?) } + + + #[test] + fn v1_lovelace(val in arb_lovelace()) { + assert_eq!(val, from_to_plutus_data(&val)?) + } } } mod golden_v2 { @@ -406,4 +412,122 @@ mod plutusdata_roundtrip_tests { } } } + + mod prop_v3 { + use super::from_to_plutus_data; + use plutus_ledger_api::generators::correct::v3::*; + use proptest::prelude::*; + + proptest! { + #[test] + fn v3_cold_committee_credential(val in arb_cold_committee_credential()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_hot_committee_credential(val in arb_hot_committee_credential()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_d_rep_credential(val in arb_d_rep_credential()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_d_rep(val in arb_d_rep()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_delegatee(val in arb_delegatee()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_tx_cert(val in arb_tx_cert()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_voter(val in arb_voter()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_vote(val in arb_vote()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_governance_action_id(val in arb_governance_action_id()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_committee(val in arb_committee()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_rational(val in arb_rational()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_constitution(val in arb_constitution()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_protocol_version(val in arb_protocol_version()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_change_parameters(val in arb_change_parameters()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_governance_action(val in arb_governance_action()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_protocol_procedure(val in arb_protocol_procedure()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_script_purpose(val in arb_script_purpose()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_script_info(val in arb_script_info()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + + #[test] + fn v3_transaction_info(val in arb_transaction_info()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + + #[test] + fn v3_script_context(val in arb_script_context()) { + assert_eq!(val, from_to_plutus_data(&val)?); + } + } + } } diff --git a/plutus-ledger-api/tests/serde.proptest-regressions b/plutus-ledger-api/tests/serde.proptest-regressions deleted file mode 100644 index ef0ed42..0000000 --- a/plutus-ledger-api/tests/serde.proptest-regressions +++ /dev/null @@ -1,15 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc b1c17d89cb2c4087ca1f95b15b7f1312a37c33526bd37afc13254e8030ede155 # shrinks to val = TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(000000000000000000000001b3ac92cbb5c5386f63579aab8d275075)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1323a50422e1cefc776900417e9a2c65b7d62c3c69d773990eb55eed))): {TokenName(24e4a63b3550f034484bc3cdb4acd4e0f2ecaf9d92f804e6c35bf13d3cd06712): 4052692294, TokenName(62b4c5e42779e5f33f34884c0f747c6c8218016de3d3bc16aa53212fb57dca64): 806378676, TokenName(877f2c64113927b43e3174544dc03a14f318a0b341347e497bc599c54ab329d1): 1330682733, TokenName(e1665048fc1253c116fbdbd5274cd5831cd42c4a1e7866b3b347845303ce0a35): 3833112553, TokenName(fc96020ec9705256c2dd221c98f151b5bab9c6267e4815a04a5ced7cd0bc15a5): 2966980009}, NativeToken(MintingPolicyHash(ScriptHash(1a578eb605337e7975d3bfb7a499b7bf6c5dce67f5369bdd0c1b0204))): {TokenName(4fa6ea25c720b41ce50852f4c0f45714716f33761d34d0102d86912d1e31c448): 3970296511, TokenName(90d6b22e6dddec599e14280f3ca3ffce0d5e5e39125e2e71ad44d907f4c1a657): 3950474072, TokenName(94ed7a0cb19ec9e8e273b4ca593e96c58fd2ea426d85ec8f0fd10b4a34e0c3c4): 2568538332, TokenName(9b28aaca088d92bdadae12eea29f38f5a68b7b5394dc3f66d39eeaca18cba8ab): 1520145484, TokenName(a06be355b020fde56946bda558c5269a6b58e791ffc49616969ad6dbff2d449a): 1987977824}, NativeToken(MintingPolicyHash(ScriptHash(6bdd2b58833f83b83b63d4614fc519662d8d099351570f4397603307))): {TokenName(1dd469853e7868eb330d75bb018cca1a07c9da4d6add9eb250b84e6a5628c96d): 2144987589, TokenName(3a03221f8ef5c831853c598c6f025af529fd4fb3be46075c114be9512e0b5b1f): 3787481019, TokenName(793b8ea5d945b96f9223a2c2fc13f7fedeb68928aeee9724c240564351c7675c): 2478716803, TokenName(b743679afcc2fce2ba105f4d7029d4c9808a79fb95a7364ced89aa02288a76d7): 3505601434, TokenName(e77d85645a2a19dcdfe0201b33e77cec2785d8f93e70843fc5651f54a4024db1): 1813187621}, NativeToken(MintingPolicyHash(ScriptHash(770ecf6a777ee674b01d2fee75e086f381ec7ac3cf8fb372b3335614))): {TokenName(113f0b5ea9b6f4b886fe37e50cf7e9c1140dab723b444909fcdbe26481c9d6ee): 2174643095, TokenName(18ddc1bd38875cef3e85c309eeb6d3c542f5a08a59e2566b899e8a195021367a): 2966220028, TokenName(47545e0285fe6eb7b36e7d8bc9e10b28251056ae45898033d2c4904e9ee77e55): 2126438577, TokenName(5fd1ae3e2e71d5bc2ca6b63a91a3249bbc20bc1d02eace02187330dd37b62ca2): 585634295, TokenName(805294b21b804c232a573b26f4a68b025dffccf8a389bcbfccc9a1133fa949bb): 2574511089}, NativeToken(MintingPolicyHash(ScriptHash(aa5e20202d7ebcef3722640132058784312adbe1462de47de6476420))): {TokenName(83659f7546f8475b53ac412167261b41aa8fe39a840c0bb6640fb895e376405d): 1333949599, TokenName(d50096f8f220094cdc6bfcc09d4027b2c8d9aa76bc832135e3f759a79c1c8c21): 1139917772, TokenName(da48eb636c0f71f69265516ff18818a0abca6097d2b36d1941b96edd6fbd8f6b): 1795366150, TokenName(dea5d26f08da84f4d41c7bbdc80ebcd0ebda8529be91c633947707ada74d936e): 1440752344, TokenName(e81efb96588cfc9a3f39d05f2c5104be830832ba7ebcbfd7b8c360c84d74f534): 1487908621}}), datum: None, reference_script: None } } -cc 13e6892c12a0adb0a78d1574f42bda31a80466e9f11374a9dafa15c86cab2302 # shrinks to val = TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 3351355059690873586}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000c4a412e95f656d23a96328922a900d2ee5fc53f): 4007578882, TokenName(11a4f0f03e60e63d6d117f49ea2e9ad9da2c3035418335886be7219f9a3475cc): 3734091249, TokenName(14059d2a785e91a4de0fa379f6b692bb7ccec27f37fa7a94cbb52680be837267): 211916204, TokenName(16ec936c15c6efac15dc0a52edf49207429d581c5e81eb3c3c90715978771747): 813082854}, NativeToken(MintingPolicyHash(ScriptHash(1807c470904538fca75a8bef3c58477b6dc55e942d18ba7a77f7bbd9))): {TokenName(2ae27047fac788c1b510a203a57d9bdd18d990025f292e8cb1cd92376593b9a2): 3589724762, TokenName(2dfcc2f461b0fdaf1cf4d648674fda4882f84d87b013f3db8fb52863b40643a3): 2466834830, TokenName(59859fd60af5ea72e0ef60e81b6926ff3adf3ecddf7e70d864feaf81598e66b6): 3768615940, TokenName(91fae3ce742d4d6e474cbb5908718d07480938d5c4bf299fe3519f20fe5bdcf0): 3457482975, TokenName(a28cc6ec581dabaa93a22bcfff7e093b280dc03cb5d2c2d1f5abd93f4104c8de): 1750809165}, NativeToken(MintingPolicyHash(ScriptHash(6bac92a2a3351e841fd7ffc1f3b4198f1f47fe4e33ef96d2903569c4))): {TokenName(03edaff3b48cde1872af44ee6c92922cedc4411ee0338af1b171a21b21084d26): 991468614, TokenName(14b56c27a338c8b6b70ad4237c54ea412ff431593f43369eb8b494560c336572): 2996247931, TokenName(41d6bebf8662e7bab8f746e3bae279b7864ef7e0101454514a4962b7adf5957c): 2956570886, TokenName(51b4bf33fb1559d603262face6c4428d0d87945fdd682652bc8d7dd030ebab50): 2254790562, TokenName(624d2e1fb8df51befe3bf161ecc4cef0f77f706dc4e16aef853dc268904559ea): 1710855054}, NativeToken(MintingPolicyHash(ScriptHash(79a516785f9797629f9c2c32afec01bf422d2fb103e1f84aaa99326e))): {TokenName(127cc8a57b489b8aaaa254d27524c5ffdb98244864fdc99e10041e0c70b9e7bb): 2911123850, TokenName(26c7a7d0e6a64c4d28d5297f9d10bbc2c61f28482a4fa2c3125ffdf41075981e): 1533600818, TokenName(5e938908c855f0d5631501da422f9f6b24b79482cd3e4d7ad8c7d35717404ca9): 1158808136, TokenName(6bc88da6b280231b3648fe273be94f29bdb9cd8de23b2f3b5a93d8a7bce0ed32): 4220629354, TokenName(d912b414d54a571ef3d97d7818572f281a889160f906eac0159055c31d6ea72b): 2055194512}, NativeToken(MintingPolicyHash(ScriptHash(d7562bd106cc7fa0e674604afa71e913d2e801157f61e2a2c99cf4a3))): {TokenName(2b6fac61611a8c905e9b2c26862a67c4d07938692a627023a66e4adb0031bf83): 2124892851, TokenName(77b22426fd6e190fbcbc666f0412d896eff5b701b583f1b013c3fc7faf41b8c0): 2827264884, TokenName(d85fa013fcb417b5334c54dee99cefe8bf7ca8322f9bde074db675a6b939f701): 2233309242, TokenName(dd584dcedc92ae2baf2feb81349e5f696b6b9aa9e9f1fb58afae45a45b7335cf): 2360756438, TokenName(de403ae8065c27720e1f26fc9fe6b723a6268c5b092f23273c649795be99bd52): 1094933406}}), datum_hash: None } } -cc efb15ee8f6ff1c2694b1ad1eb4cf367aff3c071647f3e71ce13189757ece5224 # shrinks to val = TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 1943354996870588357}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000004): 474051645, TokenName(421f978c4ae0a4d161dc60fa8d7cd877511c57cdc806c1b5986deb4da430dfa7): 2488334975, TokenName(59a4c85bb911454672bcebe7310d375adf018772548276da34b975fedb2d0f8b): 4248903206, TokenName(e0df732440159f9ff19b6e9c8e77e1386e4a9aee48382e97fb6994e9e2056562): 741409653}, NativeToken(MintingPolicyHash(ScriptHash(46be1b75a4ce4ef920f10727da674b0204aacc63206d17949be033db))): {TokenName(1eac4f3046bb7931ae0b0c081a82fb1b8da200e975b82a168d17aff0fd83fc1f): 2085167816, TokenName(2b011d497091730c3b2d071a6eedafd5718bdb5bfb68f38020077ccba58eb0a8): 2371561513, TokenName(92907875642cc284c5ab15539232419c66924efc6d771e0a670dccaf18e3c781): 642398574, TokenName(a207c7f26b68b64fdd3e689635e804ebb83a81c8a702662a2263d55ee74935dd): 2426539045, TokenName(c9d904185fee6bfb95adb0c7a2830ecb11686817ecec7ec73d0c2dfb20a67eba): 2871074309}, NativeToken(MintingPolicyHash(ScriptHash(9815c5ed4fe164bd67cef3a2c3c1e205631eff1e1129a113a66b861a))): {TokenName(108397c797da52b1527f985bc4b2bfab81b8ac0d642dc85c359db03eaf918d9d): 298995140, TokenName(4fdf093700645828bf414ae34c5965832eaa415f24ff2ae94b960db3c21e9450): 397599212, TokenName(51723e9be351097934bcba1454bbe5fb56e93eb8c6a9974ee8534a04d319735c): 3375646872, TokenName(bb9c8cd43399152337b43c68923555a011ebf13772ad5db39e0f58bfa43bd118): 3516553824, TokenName(e074c7540f1cbf4424684374d6ff2eca7373201c384bffc055abe5ed95b3c340): 4233369511}, NativeToken(MintingPolicyHash(ScriptHash(bcc202ae2e4a8a7c8bac99cfdc7a95fe0cecb89abd6c58f8b5fa19fc))): {TokenName(36df927af2c2e9a241ca88303c3a3a8230f442229c263dc7a7a578d4a92a7902): 136786585, TokenName(3f464eeb4a907e94c68a5fd7c8ecfb94aa8aac39efb4717d7b473c88e31ecbad): 3425350380, TokenName(51b3a012475fe96a0eb494fd25b3956b6b6a6b22820dbeeae2812ef5b9e70ad5): 827307920, TokenName(5ab8ed6811129a7596182c90a0a655ce4ebc484dc46f6efc73412c6198672274): 901225683, TokenName(91433841d02999c7f0213617f82bb3876884bce04c8c784defc3634f0cfa6626): 3044386477}, NativeToken(MintingPolicyHash(ScriptHash(f825436d4f6be16c7323cf984f4aa271e77c4bc1fa677e8c3bcce61b))): {TokenName(311bed49fd59f549915fbd7d5dc084bcc18320157e680b76fc154d0bc4a548c6): 2380644840, TokenName(664ca0142210f54f7a7a717e0ee1024eed3f3e79831b52214206349811a4ffbb): 3567838447, TokenName(925bd975df9f7e47d6baa7dbb82dcc5a4c0be3e351334103503a51fbc69914f2): 974361472, TokenName(ab83002f92dad8b86c304e7f5b4ca546a82271c68fc8598ff913d3c7121aecc4): 2435923687, TokenName(c8c34606302581726ffef12ff4f51381796834d38292428ac7d55ecca2385ae1): 2493215310}}), datum: DatumHash(DatumHash(16ccc094024c712b49cf1c19730d8822604721ffc09dab0423f3cfe539c7a4f8)), reference_script: Some(ScriptHash(f8eaa89d7fb3767c920fc463cabc2be5409cd34f3d9ddea38e022da1)) } -cc 23e9ea394bb0feb9f097fcbe50e1c617ab693e281348967adecf030c32bf9d96 # shrinks to val = TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({Ada: {TokenName(): 11307790846066098720}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(00000000000000000000000000000164922cdcd23b8e8ba4570a33f8d41c321b): 1572532578, TokenName(98dcc17b144163371f67593dbd99919f8af1e4eeea262ee8ca22ffd48312a811): 4051480068, TokenName(b34394f9dbe0ef4c71502776a2cd2757937967d0a43fd687d0646ee0df046fbb): 1336019099}, NativeToken(MintingPolicyHash(ScriptHash(256b9ee71ab62a5faf06f4062012cdc740ef1395d0c433dcd7be01c7))): {TokenName(2a169c8050297a1c30551ec2772ef8d1e8b9d771d9523dceff7d7ade4e9b7012): 1796313873, TokenName(50de778b5c82dc5113d84c97bac82c2348e6e4a4a9510a91b979ef075e116ddd): 722992515, TokenName(a030f7592af2fbe6992a90ed642de3cb8c4ef0697ef3c2720360c2db66e851ea): 3391589749, TokenName(b89611b5951937e1d3de3bd9d012b6e193a5204cd2decd314703d737c5bd1573): 3746419003, TokenName(feef6c66a1a5ad207418108dfe9fc19136d977de6710bf4e154ca6970a5ffa10): 1788244832}, NativeToken(MintingPolicyHash(ScriptHash(779d9fe9e83cbb2909567f530a2ac9d3a2d6499d15b016121f0988c8))): {TokenName(1c65160f41a60a9039bc1c690e462a73a09953c926c0ae96a99e7934ec16eefb): 4206602492, TokenName(34760a4de83d356878951d56466b9ad69515a32c593ed87e79786254f8008de0): 3681013152, TokenName(473fa050cb5d36e2387958289294b250984e96b4775ab135ea7da523099eeaf0): 2635040445, TokenName(6e58bb62b49bedc75e29aaa03f0d0bbd7ff93bef7ffe65fc1f5d27532f68b0dd): 2245578388, TokenName(d218432f5a8c7d2a3dd12346bfa490e7fbe436c85445b2f01346a8d5542e731e): 963588298}, NativeToken(MintingPolicyHash(ScriptHash(aceaf9912f63b6ca6eaea4b4826189d2de6cc8bea808b3bb6d291527))): {TokenName(1fd79d7b69811162e4aa0986cb5327419b9470b2b5f72ef694e53d964838e458): 2111302467, TokenName(3e953c061fa00a1227226c11eee35f64f28b7dcd27c3737c8384984d47dd5fe6): 971503309, TokenName(54ddf4c6b1ef026116fc31c4d7a0566be4c2343997148e31031c316b8d10f153): 1492445650, TokenName(aa81e77e5415f608e37df77666506b8003a832b5b315ebcdf467f4ebd0afae67): 4271805958, TokenName(f84deba5e443ab5ba20e79c104061b7ed957b06a74025e901552c34f621ec60b): 770820613}, NativeToken(MintingPolicyHash(ScriptHash(d8df147ed8b9d38c064f9861203205505399a9111e96fcc9e7050a26))): {TokenName(6d39b06ee9fb5ac4d5069d2931c481396b5a1a1ac97d4e35148fc9b34252517e): 2549362015, TokenName(70858ce665aa73bceaa8c3f0880015f3d8f420b09164918aef4c6fd8e29bb462): 1916783923, TokenName(7413c1696410281fad993156d7df79ae2deb14e4aa61a4debf461fb1b5efad06): 2856706283, TokenName(7560669a950f1b8a24cf8dbd7ec0b9631f48a16c062740df3be00f1f12e578ac): 3487241612, TokenName(dcd392c34baf0b7e97cd35b4075162cb2530b8ff9fedcdf26cc47e4680e7314d): 253797432}}), datum_hash: Some(DatumHash(3156abae7adb8f67ea12ac36bf969dafe6ac5846329ff2163e35c65f6cd31ef4)) } -cc 543e956766923f668ce342e8ce383f28dd9e72231b64d13e4ceb7a71bb98a0d3 # shrinks to val = Value({Ada: {TokenName(): 14424837469395343527}, NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000002): 0, TokenName(0000000000010967b27594d209d7070e5a0249e42a094d95f948ee043439c25c): 1788463841, TokenName(30888ee8d51a9ed949b594f7a1f1a40e78da76bc7444504f1d911647ce8f9e63): 650020242}, NativeToken(MintingPolicyHash(ScriptHash(0ea196d3b8a562932397da7fb2c94f8082bd9e64283bab714e094ebd))): {TokenName(4d20c3abfb8f4b1bfdb8d242359a0d7957a19922db440ebad25d3c12a87e6e8f): 3304779373, TokenName(5a20e1e8dd1d4a7cf812f102cbb0de08581584861d8f629b67deb9de7f216026): 1842503113, TokenName(92d26c1737334d7e4fde203bf7c98b5b64834dd678e1150e5be0369b4e728e4d): 3651598782, TokenName(c29ce34659540f2c15969e476e3aea9bf24796afde8a7c0cc5005a029eedfffe): 1907117525, TokenName(e73f3f478aedb38b2f78527e3d56e1b1693f15e0e062f6e873b38bffaf0da284): 273641939}, NativeToken(MintingPolicyHash(ScriptHash(394528ab0076d0245ede5d7aa6ccf8b89e32a27b8055e2e54f6aacb2))): {TokenName(0ea975b7110055681aed9d579fb115ba5c716c6f2dcebf69320511e41b8ffc64): 1656666742, TokenName(68ceb85082724dd89fe00b2148ae1982d767eacbf6c468466030d7da3da5136d): 2137852647, TokenName(a44b0079b391a5c725e8972a9ca3e05e3631f9a2d7f754fe9c5e52e8ac0dbc2e): 4183214932, TokenName(ad8bad35c15d89c074b1aa70f6bc62ac10b489710e1dfe1a3df52cc503f3b7ff): 361263401, TokenName(f9ba51f47615c86af84e4a5c9e798244dbe28230498a2b9ef4b7a55630ae004f): 2929477375}, NativeToken(MintingPolicyHash(ScriptHash(97f25ec089dceedb7e4e47eba212a79d153e74e24446f48359a01c13))): {TokenName(66a14a5165c74437340c0161f9cbd3dc10b7d89992e1c96cbd0d0f0254b04545): 1726978085, TokenName(6c31dd856fafdabdc5250bc1d8f6c44615cd0429213748caa3ef6b93df3357fb): 192819734, TokenName(b34d6468a5043a1e1fe3691e1f345f25968c87d39b5cd6142bf526d9127c1309): 3572494951, TokenName(d7f1ae6f89bdb1c17c498e75cb3158c40e288171783c9cb032775edabe8a1bc7): 3350017561, TokenName(ec5ed545b36adaf6c1df0fa6acbefda2ad62221ba9cc38e37e3425a6415c0311): 2179161864}, NativeToken(MintingPolicyHash(ScriptHash(ff386873341b1bcaae8ab05ad80533ab4c4c4b6b884db97f59f968c3))): {TokenName(369f2ba9131db399e3b61838992581f68a4dbd4fb3aa06aa0e15041079447d4f): 1900606450, TokenName(6a76151ce50cf711d63c29c51b8f307b904bd1e412b90963f37ef83716de39dc): 4233782127, TokenName(8ee60f629af8e9fdb7f88009f5019bd14cfaf6230123d41a594a314c6cf0d91e): 3597316093, TokenName(cc4ef63ad384995a2416781166808ca8d51cdeb1ace960da440769edc7d29e12): 2153679071, TokenName(f503b52b34c5b9e621d3360038f55dc5242c1626821606aa11d19625875c3e21): 2091888762}}) -cc 52590d67b91538cc3fcd06d3e709aca62126f18b7363189db12383c4362fead2 # shrinks to val = TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(00000000000000000000000000000407edf8adb91cf89541e545e72496f07a20): 374039361, TokenName(1d0b453824ce557bf6fca45a77965a26f495bc7db5e70aa4bf403fe9c5e16303): 3558846317, TokenName(86bacc62b41afdea27a3ad67e2347e10655ce679e764a922394381ac19943919): 828865406, TokenName(a350897df7bac32ce8796e269191595ec98863b02b3537317d75681e84a8e429): 1731759626}, NativeToken(MintingPolicyHash(ScriptHash(110676327075ab343912349bb85ccb77019b8ae5b396e4cd416a3c0d))): {TokenName(32bc97530e7a592b2f8630e2a480118421275e58c196b5c3aa2889dfaef39e54): 4100972697, TokenName(49a899b2e5173fcf358ecf74bd9610b117d6bb75eaa6a002b431faa2c734665c): 1009551356, TokenName(91221cf10db922a1a209f75dda756b2e7df8a16318000456e4cb7c277bcf8f14): 2148844087, TokenName(cceab4a5173762e2c01973e1f5f1aec24418692a4797e0d01734877231b9258c): 1591908534, TokenName(e90f5d97fa42a95d2f7f69376fa00340245cd698a90cf200bfbc98f3e2dfc3fc): 1860292516}, NativeToken(MintingPolicyHash(ScriptHash(4bdcd1523ed412e4ab67035eb368ad1b759062c7a410ba1d209fdec8))): {TokenName(188fde12d24aaf8a7dc15aae14d3fffa150b888cbf14c8e182b21c092fcc4d59): 1244087303, TokenName(4edd8bfd264c0569408a288f86522ecf82c6515e487e62e3bddc7eb5916db2e8): 537602506, TokenName(55fb644db0c596e92bbc3c217e9a1394c3d007474209e2079baa1b5dca2eea0c): 673098567, TokenName(7652799c4712d9a009f7c5846f35efc8fcea5a45817428d6e4241c9fce120535): 2409979608, TokenName(c2d8d50e8b1319019b0deeeb9fa49c83b8322c23c82fa18b87f0f533706bc856): 1259902524}, NativeToken(MintingPolicyHash(ScriptHash(cc79a057808e4c804cd8304253deb5e21f0f58335d108a22d014d0d0))): {TokenName(5b87217cb1ff8ed33f592726e9be4256cded3f725aad00c2f8bae54de1aaea60): 1662572243, TokenName(624bbc52eca808726e6e76d4631e857472200e724363a77690c783bc9fdcfe17): 1857662724, TokenName(a390b7761fdd484ff1123e88ce732c064fc79eaa7de470b31fb5a6c3be75f12f): 630637122, TokenName(e295f370af39b67a23986955a776696000bd8e4e8604aa8a5530f238e82cc482): 3765641512, TokenName(ffcd7aa906d79906871384ac2b7b7147d0812417f30511793a4b88aa5c40788a): 4156446257}, NativeToken(MintingPolicyHash(ScriptHash(edf779b2d3812f0c4d84c6dd0c4ad7b8dc3438a93bb6081221b92024))): {TokenName(26d2c9596bcb2a6c2d75ea90a3049bb569d247286526a9b8251a2a6c011c5d73): 3986757752, TokenName(273a66461623a3e686eda206bcbba9df540c2cad7b4a4bd5bd7bbda79d4e9787): 422699215, TokenName(9ddab29f7066cc2261ab86de5a5dd75be3dd6fd25314f2232f2576bdd5bafa2d): 2898291720, TokenName(f7ff19017f0773b48a8ed759706a2dcb81c0a92f643a9e42c3ec6ead8271408e): 1872832045, TokenName(f89c670ba8b564019eb56d5625db89092f30d65c52b69d86b59235b6f84f6c24): 1227840929}}), datum_hash: Some(DatumHash(2b30dddbf7e4d84702f001d4cb2e44f1fdd265d349b62dd40db52545de220a29)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(3608caa8c9a441bdeb618bbc888410c67429df878a186df9c8d4667577437171), index: 2505034753 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(93ffdf43517f1d5fc59790532451ac5c5df8e740b939d3ada063ccc6))), staking_credential: Some(Hash(Script(ValidatorHash(ScriptHash(3e7260a6c88929d0a414fa09ddce0a82a85dd6250947b98d4fa4f16c))))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0a230b516f31a9b7e773c59b1df65b53d6f28fe040ee4f4ebff14c90))): {TokenName(3d167921ef314f97fd811237208dea5796376e54d2fca024f5931f4cba4beb70): 1706344604, TokenName(93d5d7d5137a2188f63b632b1324426bcc18783b229b90f40ae6e57a9c872d25): 3878789206, TokenName(a16898c99e4d0d3355b7929794c485b59c33c4167c2e700a70fa54e03c6bb381): 1316155636, TokenName(d3f5d06afa3a7a686636fbda3a995c4695ce993674dd9b91f2e8814edf8ee8d5): 98210038, TokenName(e44c49b9dcbe4061398269076cf0577bd1060bc6a5c41d9961e21c3c421fb536): 110055982}, NativeToken(MintingPolicyHash(ScriptHash(769b33031842dddae11463eb167e1cbd4b97a7cf6d9306d298d3af27))): {TokenName(43a6ce056b96ffab54133ef9a5ae732d40ecf89e56eb64137f326604634bdd84): 1169283178, TokenName(4b2b68721b75f00c82af508cc844d778718153f0bfa2f38d04897dd3d684109f): 2296085414, TokenName(d0d45e806140bd49ed236ebba7b5836e1dceb49bd7bfd87c66d0fa2e65cc7059): 4242343236, TokenName(d2bb9bbb0726ad1f41ce1d1431e5dcbebf033938a53ed147c81df0a96d75386c): 1548897659, TokenName(ff382d5bdef55129479c3e9a1829bfb783a426bc4cbb0c7d2c860707b3ebdbc8): 816548483}, NativeToken(MintingPolicyHash(ScriptHash(803dc93b340c00d17d3d734f37d15364e305edb314f1bd77e427229c))): {TokenName(80434afd415c5dcc31b26d9b33adc917fd05fc07bd4bac40b8e433cc917e14b8): 4036724512, TokenName(862c26cf7d50ec6b3e2cbfacef5f7003bcb1bc67d3b9667c879634967577c913): 3483301905, TokenName(bc928483ab6ddd4254a8dc0a35743ca403535a2de7b2f5b7db96b91d0f5cf36b): 2789696563, TokenName(c2365d912588993a20a7b7ad04ab12447110c0029871c2f8a9879d0052c1fce2): 3274018622, TokenName(caf7975d5fa73649574fc3dd143ecddac576f008599aa80c3c73cd0da38a4498): 495832125}, NativeToken(MintingPolicyHash(ScriptHash(892d1a24e3527b900968d75baefee5b234d39e26bd798f2987b4b718))): {TokenName(03b45d84ed114acb7f74db5d0b3b683631fe25ae954f96cba5d55cfed2d5eba5): 1637132504, TokenName(4e271d6bd9e3690da6a38f9952ef6111abc0f9cea1a9327f1c3af748abc6f53a): 2401555099, TokenName(a5537dfb34e7f25509c97d600fce489cecbf57d22e72f35f6a3fdf726121e7f3): 3356064449, TokenName(af969adba96fa98725c9c91b709348d18fd9aac47948c8da7293fa9ac2e92396): 4281688255, TokenName(ec94e85bdc9d175489a6cff2285a1f24d8fc378bca3b07cccf0baa7f274e320d): 4256109274}, NativeToken(MintingPolicyHash(ScriptHash(bcd2c9ad98f80a84ab431a5a9c22d40650a8aa2a03e4bdd2c1cd20bf))): {TokenName(0b082058d082a6bd98f66b8411ad9fea78518d9e03e36d28f8aa27dedbfdee70): 78234265, TokenName(0eeae96e6388083152ccec03087524cfcea79e6a875b87af2ccad1e687cd8e27): 216657798, TokenName(778c0c8ce081eb594c3c9ce1db4c605d42445e5ec43885609e4e18010626876f): 3507391797, TokenName(be767ff84f4639851a91f78a2ac29764e03c37921840e10a7cee90e24ee2a816): 701477366, TokenName(dc5c0fc93198fb3feba93c0ba69c0332aab4fd85a1d350febeaab7002a61f3af): 1752261894}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(d1b645658455c3134237115a3ab9400a4a0b1c710bc123bd554d01382c61b12e), index: 3115642705 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(080939e906e3622f3b6f617b0172a9729df1ba466aca07c9d5f210cf))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(77b8331a27e268833e2b7af865d07823696edea7ff672bd2b2bfa8bc)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(058ac06a37eb7510ad1cb9bcbae06d95a7ca57ce31b994cfb7ba0e28))): {TokenName(0982a4e2b9a6e499319e22d3a0fa20813f0c3994d8cf9fab1dfc79ff80612860): 436208616, TokenName(1c5db4a3484d72cadad51957c766273aafc050f970e4b531c2d888406768b90f): 2299825712, TokenName(33d5aac8a293c1791f7df32aa4b2fe1361f034b7d277f4836a7ad4590af5f805): 2609244847, TokenName(9a3f3005afd4dc7580ac8021309ff09846c80c48e9b6117e4bc5a98c0d9dc5ab): 1331037799, TokenName(cf77241468aa2453665300d280b2c94586c75546ab205c634c42b0234d852fbc): 2916744388}, NativeToken(MintingPolicyHash(ScriptHash(3fb8d00144adb2d2f63f61d4012b172c854cb675b43899a9a342f986))): {TokenName(41daa9c61e4d9de30265b4df35f0ecac7fea5b5664ef44649c1e3245132f93f9): 1119356175, TokenName(6fd515c51e30a3a6dae3d4e563a8e14d81208906c93ece49da73abe0559392e9): 3894143546, TokenName(83c0dcc9640b18c255272c421366d651f360c471f340426293132dbabfae5bf2): 1619325732, TokenName(9680687326d471f9335c494cb25eb51c0d2b8dfa143732e0b7cd8c8ecf7e78cf): 2412586278, TokenName(b6ee08e2981a46b92bfc6c2365978f116a2f1677126a38f31c3861f60d8f515d): 2042428623}, NativeToken(MintingPolicyHash(ScriptHash(66d3e927c9db5ac0983e81b47d3a61215e0210095179f739ff39e59d))): {TokenName(118dcbe5303078a367a24ec358e672b0132c3be07e608242f06ce9e0b9cb7fd2): 2650236921, TokenName(320db7f8a3e729bda48d3c044c2006fe59bc1fdee3eb55d5092059e94e0fb2be): 1054482504, TokenName(470f191908a1b3bc0b28a94176a99e2c6c8d2cb155ba9c79b48f1925d1915dad): 365539338, TokenName(b78b4782520720d8e19139ae80269bdb181bdb997567221d102a2aaa37c5e66c): 376692965, TokenName(f392a44b3bbe452ded1ff4f8e3abaa82c6d6a57fcfa89f9a5a22d504a4bbd6af): 2377338980}, NativeToken(MintingPolicyHash(ScriptHash(6c71a1a7c5c43fb2cbcb2e5c1d3fabc97da44d2432bcb2dbc998b6ae))): {TokenName(2f415a59dca91e067ee0e1063d78baa1737856e6e0a6a4db89fa35169efb0ab6): 1444969153, TokenName(bf2ba9c840adfc871b11366de3b98c47117a630bb9e9450f703b3774156e6ca6): 789595036, TokenName(c5917f94f3d44cce3ca2f57b9d96a5a479ee1e303aba0a8cdbe57d5b7b3ea5db): 3567555179, TokenName(dce3232c49a4d3eb10fa3d5805c2caab98d1edbfa01e050c1b4bb6a8baca6136): 636556504, TokenName(e3cb029eb81c9ed25781c011bcd2067a592fbffc5aa286f6e4869f493e61bbb0): 2229180782}, NativeToken(MintingPolicyHash(ScriptHash(8f6fa4dc5f3b3435b5dd5e46aba6a1332dda83d58bc4041e21d159ed))): {TokenName(2f8e26285f838f215da993196558056a72b38c14bc83a5c436452372beedde3b): 2084712920, TokenName(3545998c584076d85b9d3e04aa7dfe4ddee44cae8a9a496e0892d2fa1711074c): 1583163728, TokenName(3a3bbaee789440cc16880f11711c1cdd1840cb9930e4b4834a83dfc7099ca410): 875965494, TokenName(8802f5a073f2a567a9fcc558a5a10deb3ea61c853e6901fc9e0fb591144d214e): 2198651115, TokenName(9558b1aca92f7b6f4645bdba1b84e258f545d4f18b4bb1e34bfb19355ed266b3): 1818984028}}), datum_hash: Some(DatumHash(30e7bc4cecc08267735aa03b6503e91c33ae4218e5bfcd7c1db26dfb426e01c4)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(b788a2ba61e9680498536f8b28daf3ad323a47ed6044b636041e2272715ab17f), index: 2534781838 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(4b8950e75906d624ab2b1bd938a7730033fa710b80575d3cca9216a1))), staking_credential: None }, value: Value({Ada: {TokenName(): 710163555261585332}, NativeToken(MintingPolicyHash(ScriptHash(31f30fc21616a16366ef9aa79038b498c89bfddca46cd4b9898f3ba3))): {TokenName(336c9708249e632b51249a465da394eb4c7755eaa5345d2cb2e18b99a9883d29): 2736465276, TokenName(66de15d9ac8f220385059884c847f1ebe36b71fbcf026d8988c54c9b33ee8164): 1033802914, TokenName(a12988707cd40b76c73e20b1fccbdcd441a60a8b7101fa269780687ef40b3690): 4098961484, TokenName(c16a762291b6ea2ed16cd879edd2351fcb938d8e07e4d347e1845501a34d708a): 1942554846, TokenName(d926a03adcfabde2dc39b451c540d59f4cc01ab04a62cc39e6ea85cf8063b2bf): 2882376297}, NativeToken(MintingPolicyHash(ScriptHash(513997501d96c4e3d87e0d4c5484c73acfeaca8b22116dcfffba8e5b))): {TokenName(234413823848dd5724e87c58870c9916f83bf835cc83a65ae13d280b6b8cdc0e): 3912994292, TokenName(31a73843eaf00472ff4cabdf736351ba096c628c11903646a8fe770fe8d7791a): 1527714607, TokenName(a734cb2591a9751a69e3913d21ebc51449065bf735468c623593654b962f5b02): 2431254021, TokenName(e6af621e3940f1dc0b6005eeae3a410f6876c539aed2fed7a7602ae1da80f0b8): 1458257302, TokenName(f21ca9056cdd1863de155e2cd3facdbfd5372655d0b82710852ef4d51ec1947b): 3043983130}, NativeToken(MintingPolicyHash(ScriptHash(c6aeacfc700f1802b15c94de96facedde6c384eacfc9c3bc33d710e6))): {TokenName(0150f42a12d4ac7ca8193c8286ed0d72c26cd2808dd724973511ae8b9ff27e3f): 3680159812, TokenName(4998b6923dc0350f8f64963bc19d0664b29d448430a67fc42d40e162b35f61c9): 3257935214, TokenName(868b7622c4b934723dcad517c217e2581c6587025fd8948ffa57ef933297a4cb): 3842022460, TokenName(bc776864c4181d25a63bbec854732922a93d88c981c1963e6b1716c3f17792a4): 1580999213, TokenName(ed32637548c1b6dccbcb94f6bf7562221301500e9c028379a5dac8280afc2452): 1635662888}, NativeToken(MintingPolicyHash(ScriptHash(cb2df132bcbba5fe4ef4c37a58faeba72408095b6e5554376441c799))): {TokenName(6c81a116a383a027d608a6a1cce43177b48ab9be9c97568b52126351901a0e58): 980604308, TokenName(776f6232e0b982d48f7ca90a2d8cde32609fe02c38a06146a6f3874d2119d891): 2470546106, TokenName(780870ed9c222cd5897c26f2126b7ae90af045a881a82ab84ca55cabb1aecb1d): 3928169243, TokenName(d7f334bca02f48525e60784dd0d69945319cae5df431e583434cf6cc4e9c647b): 1087682919, TokenName(f6b37b15d15002ce4d6d810a10fd7a9dc213c78b6392639a3f3ca7f5e13e7d2d): 3319137902}, NativeToken(MintingPolicyHash(ScriptHash(fa9ab505768e962dfda560fd76233795b5e68ff6d7bf3230ff1dc237))): {TokenName(5f02262215086aaaafdeef624a81b6fc0b9d72dc839d30369126036d963b047a): 1297264053, TokenName(8e25287a0ab0575eb64dedfeb4b7e94d91bc193486ea1eafbe5152ace98e8eb7): 2436422543, TokenName(9585a430900c1155782abc26ac10a1d4e8da9b3cc12c3d04eb0987e7f42a62ad): 24027131, TokenName(a8a3dd1f763b8ceefe4f828b6acb69833127cd49f1945c25e907999aa4d5f5f0): 4078987097, TokenName(e9000da8709aa255c9119a1b913a04d6fc90d149936eb938988abe3bba6dbaa3): 1463922281}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(4a58917cb81a66bd673b31f0725985620676f7342dc40c57621f5dd5ddef0cdb), index: 2237120378 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(dc6adc7152a569a1e6dfc6ea8f7de5663acb00b9a916ee26773fde5e)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(07f3ada2f3cbaed53e74da54502d785beece52f456887289c36b01c5)))) }, value: Value({Ada: {TokenName(): 2187420690785327395}, NativeToken(MintingPolicyHash(ScriptHash(0f1f0bfe953adca264f10d0f36b98bc7c0e3549da5f3355b2ebb1f90))): {TokenName(2f5c5e1da40a7c4f5911f3b87fe5b534b5e9442caa4750362e26d3a940cd7ad9): 1749869049, TokenName(4e34cff6cc2c1e294990ee06385aa2d87feef581c4c0d18b5441d958af529857): 3386749994, TokenName(6dfa637c9edf7f237a7531d3eb097083c95655aa2bc74136dc863669f1dc7f8e): 3424902970, TokenName(96ea480d56abf56c4dda47713b1c90d1225b4d00cecc104e4dd8db51a5121699): 120786680, TokenName(eeaaffcc1c1113116cffd9c89b1c839cdd6dadb83660046b1f58bc5aeae42c13): 1935378831}, NativeToken(MintingPolicyHash(ScriptHash(416961201c75acdf68f31c44af7b0554b5472a90f512282e09d8d952))): {TokenName(43c11832e5f18a7844b82d95b5b050df3d38b41fd74a5f0f1947e479d1dbfd5e): 2308196071, TokenName(5a790a21d4b34e56a031c7bf91dd3347dd9e8f0e7142c21385bcf176617ba1e0): 2762092532, TokenName(5e1428a96f901496627a35371821057f6b1197bacc6968500788f1ca667f7de5): 1786463607, TokenName(9b8297349851f9282f4fcd613be37d77188d19a2c8e9573df52910030761dc67): 2644675782, TokenName(f4c7bd912e86616df00638c4e8bec5da29a9e30c7d2beec1b93fe2470cc536a6): 4029499366}, NativeToken(MintingPolicyHash(ScriptHash(42a4921232c02536a092966b7e1f7e844cfb8d2d6d6d109c74efb801))): {TokenName(084b6abede319fe531033d514a51211dd13f3b1fd2bd2c1ac463a314979babe4): 1031801373, TokenName(3caad7cc2a7ae5831de551a8b5df1ef5375a4505c0563c3e81fa69d11ea08ba1): 1340469765, TokenName(7cd76fbb5e86aff6f3bca788b308b7fcbbda7e6b6975f6dce8857c4f0ae574a2): 813064888, TokenName(c195267200a0ddd3d157df366b68a38d8bbce29e26a420d2a3731bf8115c5748): 665272959, TokenName(dc0e6c374d47a156f53b4be95d50935db6912557d7bdd05037eae16581f8bbea): 1921030566}, NativeToken(MintingPolicyHash(ScriptHash(8b7aebc7fe45bb6fb781710a83d38187da62ade2ad3f53ee909ffff6))): {TokenName(2d84c91747ddb380cdafd7eebe9d46d221dc7c94d2afb620a5a66bf9d575fea4): 49037436, TokenName(6fa872799f3408ff0d4d42cd62c9ea6554a09521517bcf33f0b8be988f2a3253): 3271104944, TokenName(97adba75d68e15a7407644beeaedcd8f63b5884c962e8b0eb34a819ce83ae154): 233593306, TokenName(bbe31681e67fe34142121e601f5e2b9644bf8f728a6f6a7026290f2dd82952db): 1750148926, TokenName(cbae3a183bc5ae195ecc652ddcd3b188f284bbdec219c031be824beb656d40fc): 3238415812}, NativeToken(MintingPolicyHash(ScriptHash(c9e14350262805ec43aff9e7d55b32ca41846b0ce0ab2300c5c675ba))): {TokenName(5c9b3e8e3e2b1a4ea0525101e9767947129ef90fbddc6a05622d05badf2738fb): 2427201629, TokenName(739c8bc0c52f2bfbda95110b524168863218f3835692bcac78c11400dbb93214): 3091824608, TokenName(bc573f5d85e3e0c1feaa6d806361d1ec7c45075c9c29d6f1523a1b265c070a80): 2339288559, TokenName(f094e25d97a677fb29e5da08a8c406a26bb84a82f6623e159fa08f6ff20cd5e0): 3772179716, TokenName(fcde86156ebb0a156c28b144aecc6a78222550a751ac7ae7e0539496db4ea770): 2816272552}}), datum_hash: None } }], outputs: [TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(14ce7cefdb3ffd53fb230b760dbce0ebe19bb48097de17dc3369e402))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(e64a7a19755505e403bf9ba623f3004d156daded23758e5e6597df76)))) }, value: Value({Ada: {TokenName(): 3204140381163145128}, NativeToken(MintingPolicyHash(ScriptHash(be06e679e27b762534f97a4a615fa6af8881833e159ae0cdc701d3aa))): {TokenName(5577d1cf8ce79d631922e020751334ae728616cde48563583e167916b8fe6ba6): 80422922, TokenName(a8e7f8c425a21fdaf9762b631438719d492020586337853be7f14636b0715d85): 1994695392, TokenName(b25ac4f1492b0642dfd5cacf0c424e54210e5a7f50307c7e56641b563d5b8e65): 4132953472, TokenName(c79c9bb99b410689217b7b03cb6c0c852c6532d494a417977a850cec1a5de666): 2925597833, TokenName(f7832185435abd19f1a39742376c292f4011ce0f90ea5edcc6cf52fc3a70d859): 1708481710}, NativeToken(MintingPolicyHash(ScriptHash(c1aeacdb9717886401d576c5db4ed7e39934a348d0fd34c9505774da))): {TokenName(47ea055512efb5a13c235e8eab36996f4cee8c26eb451162f721a2a82b161843): 3072137652, TokenName(5d162452b4d41ad2847d8140fdb3bbac45bbeddbad03cca2ef5b5accd75dd90c): 3139757021, TokenName(ae90d22adf87f70dc7f4f2f7e5a1c390355a0051886965358b9a5ebd0f732f80): 3717552077, TokenName(bf00a996eb8799484b37a699aaa4f17eaee0a6c31b42c4c72aae2bc6e39260e9): 781313480, TokenName(cf4ec8aa9e5374b7f69dbecde5c1086fa74200bc62672daf62022d33990209a3): 3278215950}, NativeToken(MintingPolicyHash(ScriptHash(c3b726543b9a3c64b9f1424f92cae3347b2b619063eb445f526352dd))): {TokenName(196942fc8fb02984afd653fbc389b5099e739915ebdc45ad5e77367dd425c550): 1852062128, TokenName(38d4203a5324de3b8c320b42e577a59563f469f510a92d953fa81e58abd3cc5d): 2566486165, TokenName(39e389a962dcd308d67cde5a32cea16385980336ca851be16c44fdf0b7e928a7): 413787175, TokenName(4bcb5b53b8a530bcd77776e97fe622b5f78db97c90ab801e4002ba237213a923): 1445582470, TokenName(fbf9db6e9878215925c303119aef35221db420ac43835ba17c539f9c538ac870): 2854834655}, NativeToken(MintingPolicyHash(ScriptHash(c8f52c2542aeb46959372de09adeaa83910059fdf6aa79791787e4be))): {TokenName(1362e2cb1b42cf5f247144df06dc7935c60fa91c451bcce69c512b981846cb23): 1234526972, TokenName(2fca898a35a43a85a9c9378c6c7a33e6e097b2eaedea11004f3c777a10d2ac62): 904175189, TokenName(7f1f9be4d46fd601b8a051ce503f2c19f5ce1ee0ed04eb1c724cbc399572a428): 3707513607, TokenName(877ad2da29efd6086b62ca5487c50147940cf9b44b5c35d7f505b39c0c8e48c8): 4102078761, TokenName(95d3031a95dfc9dba9027f6f9fcd6d8d2dad16a4b2a4d66702a123d38586c288): 254174447}, NativeToken(MintingPolicyHash(ScriptHash(cff14a45d976e85a1a8383ec5c945aa01ac47c8bbb22938539fcc306))): {TokenName(152ac3c0b6f871fcb493b84b9c200de7a0e4cbbf63c9c2ff471ff1b8d2dce339): 2115577256, TokenName(35dd497aec2fd036b1a94622d7d991ac6cffd492521424d9746bb985c65ebba1): 245872665, TokenName(6c32d1dada638009f2cc44102c43f9a02011e9ed5660692f3bd0908908d0d3d4): 2101072084, TokenName(89952bde248e770a36c839ed08bbe60011d502778037ddf12ebf662ebd896284): 2334605192, TokenName(9a3e9cc8a4c5f2931d23f0bb7ff2157912f85c47de221a1301288ec79450b84a): 892292307}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(1bd6451ac3423f9199ba899886fa2858b37127935c66173140b38b4b)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2127fa9639ee45983358cb96beda3695bf98d62937793363d6c87b7b))): {TokenName(0440bc1fceafed5cb7fe218fda89311fc5f776b22886ba601758ffa155cdecd7): 2977875133, TokenName(864d6359fb3e30a135fafaa3a9f382ce4ae3353daf0d6fb8eef2aff9b06fcf93): 1987814508, TokenName(9df46bb33bc4e64dc49d68f967bcb7cdc24049fc543eaecd5f6c72d72ece35e9): 698488157, TokenName(c6b83b83d7da52833579eb92b302a92d4bf9f797fc7c73ce0c8451609f800ffe): 776047550, TokenName(feb81145f36a5db83955f1a0d9cd948ba194eeff2eb788dbe35db6b563db65ba): 2185584919}, NativeToken(MintingPolicyHash(ScriptHash(5d7f0f90bfc04135763bd67cc5d095aa485cc6ba5e28c1536c7f1f23))): {TokenName(4164556b03af8ce62b77dff178fabf79c5872d307eb7ae3b21e5b8318c47ccc4): 2436169930, TokenName(822fda798db60d45f9b1e8a2f1883a26396b1a3f789478f3cc874b05e092cefc): 1815487654, TokenName(8743900397f1434ff96f72f2c0149647707fa7a9de4ae1e97a21d4be8bc56efe): 405332397, TokenName(aefa2f3b87dafe90952ba15769b170196286124ca5a545e2d02713cf61033d3b): 373101445, TokenName(d69e8a200a8f1c3eb3f4d1c2d5df008614c57da2c5e4be42c1370df66b119dbb): 3675765993}, NativeToken(MintingPolicyHash(ScriptHash(73614882564e717e8a410b3f450f4a867cf392e38874e85a3c0cc11b))): {TokenName(15f27bf0e9ccd4380f7d04a2b41cb4ea9620ee6cd1832e4287c3c2865504aefe): 2990546610, TokenName(778d5f9f2038e5317303a339632c964485aa01a8f049281cdd395012d895b3e7): 2828286019, TokenName(a480b6b257de7d65544689429bd3685c94e4b3d4f02d4e6c2af8a30c7a9d96a3): 2960566335, TokenName(b5e5ef445306a87c68ad16b13db2cb11a43c9cbead8fa6d273a4db6bf21979ad): 2003513283, TokenName(cb0837dee220176f304d6c27fc2132b47d5051bd7de5135a4a1a668f0f72d1d5): 728382953}, NativeToken(MintingPolicyHash(ScriptHash(ed5ec393f4eb319aca49968d0252c036ffd2756c0a1cd6193bc55c8f))): {TokenName(05ed240a69d035eba26e6ec044f1e8c8ebbe7dc53946c1e653e92aa287c6ec2d): 855436172, TokenName(7d9b08efebc14a5b6b53b61b7d95ef5ac2ef93f8c011309b60ab82a3a3135b79): 2841148457, TokenName(91723f81c7fa60a343bf75316864e2e96b92b7cbb780d5418a266e3ae4926df1): 1751292367, TokenName(edeb6b562a1db406bb6c5061a8fe33db9788a81603f98358a55ccb7d85ee5407): 1261153895, TokenName(fb066e91e81ee821a9b65147971e9a5e0fdbe232ace09bf2589eb407051dd90c): 1058727688}, NativeToken(MintingPolicyHash(ScriptHash(f0e52737544c0b422de1f403f69af968ee9eed4246a5b14c282d8fb5))): {TokenName(203e46596645d1a7a4141708d351e374a10d9a7e43af147b6ed63600989cf304): 1552260197, TokenName(7859a7e9c2abcc99c35b556204ca58d5b0667d7dca41f52116685f137e4d2992): 3661700872, TokenName(9cd8a5d5c1ea8d06f0d0e668bfdaf9d0314d4e6e0f166a3c9a987989febd2e9c): 3261841714, TokenName(aba4d7563c0c020759bb0d6cc64ab5895aae74940c13e8b43d3709e8f8fe2e52): 168222759, TokenName(f38f7d8a057a07f22878680c79fea54fb49cddb18ace4903e11d2b0eff10c61f): 1154769142}}), datum_hash: Some(DatumHash(f7daced41605156921f79b3f24626dcd73a44e055f1e211413101fc1df5617e9)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a81191d7bb7ac16c9debe0843fc64bc9e25c5bc8cce600025d8628af))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3511d437e44f5356364f24ffe1f8e9a3aa730317cb025d17bbf295fe))): {TokenName(34947371e5e098ec2030200a6b28c2a98720f0a9f3909ddad928f746c2e3b854): 4279030183, TokenName(4f59be7434a1bde2bdfaa5c99a3508f4ed60be02a112bcf7abf242aa85535f68): 2924357960, TokenName(9ac2fb572ee7673e9ec2cec0aae9ce3cd48bdde86662f9d8fefdea63fcb8bfbc): 1959595321, TokenName(c0af18379d7fd92561c7d60bca085bfbc3b5d942977c5b558d7105dcd834fef2): 3426883453, TokenName(f1858ee761571c36310108e946be719819b1827c30ebb1d482efaba8c25d7d75): 1657981309}, NativeToken(MintingPolicyHash(ScriptHash(52970355790060b77a1cc3fd46d7ecbaa2c91f10e5ba540b04ac4033))): {TokenName(0f28b2cd94631e1fc01f160c5fe7a728b689eed4516947e67452bce812dac2d9): 2912791554, TokenName(6c49c40da0821b8eab4a04262b389c1e8264819019e47b55ba10ba5eab12f788): 2004867540, TokenName(9648245b6d266c4484be7428a2ddedf31858af9e87f20eb3b11124afee8beacb): 497951342, TokenName(98fd3d501999a99b13c18a348e985516e71a437f19b6e6a52b435aa41c252655): 2647984422, TokenName(ee1f8ec07346c0c7abc29fe40160b76f43087e533fb65239f80016aee530a804): 2109310571}, NativeToken(MintingPolicyHash(ScriptHash(5936fe5cbf098e413db3d568db0c06665bab351a81058289376ef3fb))): {TokenName(00e4dfee874175678ff80fad99fb214753b3da0e0db7786df2c37253f2b6ae79): 3236125097, TokenName(2f2f522fa03885411cb23fd253f35c6834093afade46738da410fa2395771bce): 4246110326, TokenName(47b94183753e7eb7fd1bd09e28e2f12a8b3243067dbe15c8c8f7347050a27d97): 1554141356, TokenName(add3e8fb43d9d2ab4c7c9715bb86a680bebe22ff74ef3dfb0b293d3506c9ae37): 3188851922, TokenName(ef4cf276a25bc90a45e2c9126749f903d1cbb7f5f29e997eeb9c33c8c25425f6): 2831608162}, NativeToken(MintingPolicyHash(ScriptHash(d0f5da3e947b351534e1f62b7badaccfa9f564bf3becd4d600ec6d96))): {TokenName(29c0b978d88ea88f66ae632307f106121713eac900ff1c47f297e71058428201): 687422574, TokenName(7354bf72a2bc0b8eff89329d09cec4cdfc94db652068ad1ba8cd4ad3c1ecdece): 1889761630, TokenName(9306f02f943900c6a8af5858dda798204d637deb94f01c10b8d04e041c768c95): 1894987416, TokenName(aa3dccbd0029e01e72c9e8e0c074285e687548823c11c8173a940a3d097bf781): 1383955432, TokenName(b5818124ad743b4c585e07e835c353272ec009c322be1f92481ff88ac197035b): 1848236160}, NativeToken(MintingPolicyHash(ScriptHash(ef9c81fb293691f601959f875c274e7d991524c7084b65162ad8cc0e))): {TokenName(2e8d7363b28abb48b2aa1148b1d53baf69ff88d57edb957bd216ebe9dd476143): 3675083634, TokenName(5ee27d43d0a024728484d479467e2ac7da2365740d750fef37ab9474bb3eed86): 3545813450, TokenName(7c7607597ac9b0a863e6fe7d14c28882291f4c36886ddc5947069cd5f997b1b5): 4171611603, TokenName(80a12802a489ffc9c9961e3669ea18baf650369b26cb81727a05348673381859): 3351283778, TokenName(cfab13d81c0262e698530e522a69a979f8f7afad97c4e272743fe120201e3151): 3574590105}}), datum_hash: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(1366944a0dc97d42df4b5ef692da0b50d364b157596854224549310b))), staking_credential: None }, value: Value({Ada: {TokenName(): 13351802756234715509}, NativeToken(MintingPolicyHash(ScriptHash(3333493a6a0157506c83e5cbc9eb143af73e261ebc1da2e7b6ca4658))): {TokenName(04b52fc497106ff6332109b2695f6ca120d322475d948f150a5cdfa27ca4fd74): 3492284099, TokenName(1236a2f81af40e3459ef7519ced218c599fd4b0ea10e5763cc2f75ce3347cbb3): 4047643179, TokenName(1bf54142556d10216306606dd0017a42e32bcb5d8a0de7fa9852b36f6dacb0cd): 1683687412, TokenName(57eb0883f6678dbfbb4cbeea135f459ff288f7318c8e42c36fa62b0bd9c30d47): 4289493069, TokenName(a1f86dea69bfdee6bc21ba3b7c2c09e9fc60c9fdcd8c42365b51cd4540f42019): 2995685947}, NativeToken(MintingPolicyHash(ScriptHash(9ac99cf97e2cde774e506eddd63986fdcd865e0c9de39b1e3c9e5a4c))): {TokenName(37bb89ba393b3e5bb675deb498fc172e4d1648b44b7ef506e63a808fe753772d): 3129145689, TokenName(3c4568114829f9b232f1f9d956170107f29b8b0c5e8019330bfae84cadb7c193): 1156157674, TokenName(cfe957c3c20d32c87b45c9f88aa7d30e92b1dcf7d41b4db1fe2f40525b4ebd25): 1223547497, TokenName(d41ea6e7d657fa623551aacb2f8efafd9afc4dcc37e8081428bdef7691a9611e): 2198119818, TokenName(d5384a89b0e366d4c400de9d0e5b12e2393b8caf118a0c2b459d83e280ca4f59): 805613717}, NativeToken(MintingPolicyHash(ScriptHash(a26a00aa6e9f2117f9138c2a9ff5f76ee2656163b7118db1786ae38c))): {TokenName(4afed342390256dee5d3d9b5c47155873dbe02075749ddbedc599343b2fc34ab): 2929375856, TokenName(50d6046903bce5a7fbff220459139702f1ec2c8a57aeeb4e76b67379b6743efd): 2409147650, TokenName(70d35321ce9dd1b41711ae1b326241da331a35a6ccc464c727922068a67fbd4c): 1766121644, TokenName(808217e1ac34641897a824d1f6769fe55a1ee4fda6a59bd3f1f255edf1448f80): 1248412111, TokenName(a6dd643fbeb6d5a9cc8c318115ef704de77b11fbc6acaa06030937b216096f9c): 582545510}, NativeToken(MintingPolicyHash(ScriptHash(dda30ea82e162802f2c91c65ed47afaab607af9c4a8a5a1219400604))): {TokenName(5b41ac71275861ff2ec5dfa1de2990c19b417511ae4478d9e89ff7b483067172): 3449412633, TokenName(a3da564c457a2435006659f191f8b2c21b767fa8ada7f44fcea28708151aebc4): 3439364834, TokenName(b52601702a31b72c6fa6184f97e1618e6edc802096c30ec7a43273f82e83546e): 1845099946, TokenName(b81594580ed31cca2d5d2983743c2ef3cd467feb798cf9125bde3a1e54c9ffbb): 2233546504, TokenName(de7a95404a66c0064191243f052add40850b9d41b362a9a67209467d6cce1af0): 1194625508}, NativeToken(MintingPolicyHash(ScriptHash(f6af65a78fbbdae33ffa1dc33a7d00fc9d55fc9c31a57b595ac21f73))): {TokenName(199ae885b98c11ce28a6aa0abc2fc4301438ef1e5e2adf9a9dd2c65eae8bc25b): 1672237215, TokenName(28b5c3af3d1956aebeca97354c6c5f1fea5bc4cdb96306cfe42cd8b8a3834e02): 2522397673, TokenName(840c246ee8e65971214b2ce1842a83fdfe9dfccc2f6ebbaee6382afd0d548d7f): 3508342103, TokenName(a7e5d3b09cfa389972fcf38cf5c9b4669bf3d8ac8ebedc8f93188cf8bb102202): 1316451132, TokenName(e11fdedccb9d317851c500be87e44ccd447d335a8587413b372cd27e5c9f7511): 2841616680}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(247ec5924a2e8d049a1ed1a7c030b7b945f77481fb4b4e905017d562)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2450805533), transaction_index: TransactionIndex(3725415279), certificate_index: CertificateIndex(992538979) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3097ab6b9f11ac41b2b62a2b187376bdb749894df054363cf85091fe))): {TokenName(00652e47ade1743699fd5b1653446d5f1a1feba494061001f85f78d66b6461d1): 1911922049, TokenName(4ee8a0136cacff3b1b911ef1ffef30296fc068829bf2baa77467f15c03164e16): 1242398632, TokenName(5b9ad3b1912c0bab37be2e540abcbf3f2ccc0b03ed815db3afbe66d1f646f631): 4054076827, TokenName(cd32139a69d6b6325de16431451cca2b91e574e7c8178d0e09d5fd99031eb492): 4287503836, TokenName(e1c9456c964d607e97926955eaaba6c741212527e1aef265f723a485cac705ca): 1886959299}, NativeToken(MintingPolicyHash(ScriptHash(5ee25ce0cac04974b19bb292e6125bacb4745f01cade2a38f2fcddcd))): {TokenName(40106f4e64081437699085ab258ad8cb7caab53c0bdbf1d3c4d26b626ed1cabf): 1982887309, TokenName(84f985f8d580c7e5fb8ebfcf846596871490e5d7cfbcd7e3ccc2120d305b76ad): 2169968749, TokenName(8dba0028dd4d76f77fda3ab995c10060320015a5d60e783f2a08bc46b6dc0413): 4127905617, TokenName(99c65e7a82bd3d31b90bc08417bbf1dd5d9792ca23665cc19956d7d20e05efd4): 770108781, TokenName(9b0c9da4b82f393883b6a1acaec32469c887a16f9c53cbae086c6ed5cc18d30e): 3974021517}, NativeToken(MintingPolicyHash(ScriptHash(6e24ebf6513091773ebd4294fda9bd6b83e64c2a0353376dec8127d7))): {TokenName(0e695a2befebae2598cc133574f4c82e9f90e9e3aa78a3ecc97bc7e36a18ed71): 3082909143, TokenName(770727d6f3e76fb630db24f10305e3bb455f6c8375f5f6c39002b9bb9cf502d7): 2029396459, TokenName(88010c000289f7dbbe362b895b698f3a0b61cf43a3f01d681c122797e30d7fc4): 525582582, TokenName(88d3306e41a945c166df7a4e76593f614fd48eb034f2cd4ba8355220b223e264): 354710608, TokenName(c9bd4cbe78d3c0a251480c0449029b3dc6de569e9df872fb3829953abba97485): 4143978965}, NativeToken(MintingPolicyHash(ScriptHash(87689a7b197a246ff4933f38181eb1a772a051356fc9f16c21fcf4dd))): {TokenName(99861eecd1fb25e288bbc4eea32469478d11707fabe67998a28f969fafe6145f): 4004005865, TokenName(9a7c48fc20693b162e4f3f2e274567b2ccb4e538f4a88b3fb88d9b5635253e8c): 1034688184, TokenName(cd916da66c003e332443a3c64cd79aa142abea71d8bfe2e2de4993ed41a77f0a): 3233870665, TokenName(f69d57f73c6f35b14fcfeb0d75183db23e64ceae817984509b83537554673aed): 3999837128, TokenName(f844611c343db68f6d9bc7e8d927de6af6837fc6bb1c94d9502a4b8b72537644): 2503352227}, NativeToken(MintingPolicyHash(ScriptHash(d317388e192a34f51df8eec430e2d53aca7d04ad315e0e3074af3fe1))): {TokenName(10666a619d5c83a471e786f9b81c9ed1a7a573334c4667169f01211e1ca0b58b): 314137795, TokenName(11851deaaee3721c83ed53b211e63356dc7afa3f9f1dc9ebfe75e98f9eead160): 3135406278, TokenName(8d2a1bfc081a54fcdf59523de72bee9512b4392c07d61377fb984204e1ad82f8): 1963530350, TokenName(a00d6bbc3b0fe894277ffa8d0e23d9a23d5463e8d8c426a8ff45b29a3528a5b0): 1440594174, TokenName(eb7daf04a6aaf9b17ae0e21436c3c694b2531f31d176f8fb0878f115757352ec): 1860614444}}), datum_hash: None }], fee: Value({NativeToken(MintingPolicyHash(ScriptHash(4f4ed647979104581198f38cc33bf18dc9d39eccc4c7847ea67be5f2))): {TokenName(b277a337e0f7c277dbb940662f774374d0cd4fc412e1c82f75da3111527ff50e): 2712245377, TokenName(b73f41ff0bf0fd19f4b91687b0146b48074634cbf18429d8104f0f0e806c47cf): 2724470942, TokenName(d6d0537b727c896b09eec212320aa1326488a794c446bb4218145803866cc1ca): 204951555, TokenName(e5fdba2517c9236f6727ea47f6269686e7159ef08c1376f18145331d7272b16f): 2946639197, TokenName(ea8f9bd188f63366fd4b36751fd19400e1c57b78a43ce9795b57b64b7c13b9b6): 1514162206}, NativeToken(MintingPolicyHash(ScriptHash(5c7fd335b0394b5b2fbf0894beda0a21f0db530ee5df4825222da8b6))): {TokenName(1d2eecaee62e606b2b409f07344c89249aa96f2f5648df7fc1bd1a2f7e1f0abe): 3149830167, TokenName(4640b5aa19c9467a8e2b882cbfd05568a123ea28523cd49071baa3e0aa240234): 1114408917, TokenName(5c29ed6d0c1270e719022fa598a198daf6cf61443d0fbf381949426102a0acca): 418466267, TokenName(bf86fad3ceacf34cbac8250997970e1eddf0c80c37447f41a0d81559026e6da3): 3114176567, TokenName(d487d6d1f2f03e7d5088ce48f660c92a1eb9b233b7a5f583229691e5037a9636): 371392486}, NativeToken(MintingPolicyHash(ScriptHash(96e7a3aacfcc19415ac2dd90d7ce6d66427ba594379d42f3b5b4e375))): {TokenName(17216189aca3503be5fb66d78f3b73839cb2bbc6fd9d9b281c9b9c7901bf102b): 2512001971, TokenName(18bd046901ab530e298d0ba093abd80e227e7b1fbc466c95d35d7030eea9a286): 3202447959, TokenName(2f02812f7bb3eaecdbc92fad8258f5d6b3db66d3080427517a8554050347a9e9): 2603671614, TokenName(66301a2107d40924082226d0f22e7b795009900f7a3a0328899435d439da6286): 403207560, TokenName(85fd2679f45d1d6b50cb36f5d64b85b65dee962d5be1bff4f57b377a8f35e7ec): 397536103}, NativeToken(MintingPolicyHash(ScriptHash(a978ad1fbfa0f0754fe1e3264ad0e7c92d4d23aac03f2ae51ce83057))): {TokenName(8ab36cea5ef850b0ce53f382c68c621ea705d5495f86db0cf55078f656b3ac23): 3764521872, TokenName(c98797bb1838a97368c48e0c601f437ab8ae4822c38f93403be750a123c5a1a3): 2621956, TokenName(e178df31fde9c97f1228734be022968f16f7fe4d78c9a92f966b50e679c9a72c): 235299451, TokenName(e74032fb845768d55c40a00ab97900a863d7e406f5baf84a349ac4e84beb38f9): 2784055924, TokenName(fdd46af0d5d1310646186a959be3b1b317b92922110841501c8c18420babc19d): 108793125}, NativeToken(MintingPolicyHash(ScriptHash(c7d0db00c2d19e9eba8c3b9f619fcfe0e43046cd8117eefad382e389))): {TokenName(30df48f1d8bb627bb182a2da47677c29674baaecc70d1e80db35f3bb7a40aafc): 3190993488, TokenName(9421c103289b7f6c602ef2ec25d041cc7015dd05d741997aeb30238043f7a424): 767833255, TokenName(ad475eb7e695eaddf149b7bf2ee885456b046dfa6838b446d888c9ef8782df8e): 2424177239, TokenName(f55ea0beddfd731499ae4dc3018046918aeeb3d461cb2a1309ebf87903d31c4b): 827024207, TokenName(fea6a093d67c81f8161c51bcc0d9e137cd97042bb4f35629fe7c96558b085a7e): 3082106472}}), mint: Value({Ada: {TokenName(): 4484255954812903887}, NativeToken(MintingPolicyHash(ScriptHash(16c6230f2f56186845dc2008bfa823db71539a5ed563f176250edc06))): {TokenName(35a0d926f60cbec1e088955fbbeb5aeec5203e3612dee4a880bfa997e17a684f): 2465735697, TokenName(6267b28a797103321be91df5a3b7c199e16d279dce457f8a856f4b2517313ba2): 251472862, TokenName(7caeb6eb3b2e9b7c902821836e4c101d49747799c9b79d8d5cc582afbaf6ea34): 2418753347, TokenName(9cd555aafc3e8fd7b91ba539f952cf1624b746af7216b7ec661dcbce62b3f284): 1685614024, TokenName(f831a804a92fe5bc468aef8db7482d967763d1c0ebe41b1ced5f4aa5f69e5692): 2725077761}, NativeToken(MintingPolicyHash(ScriptHash(4af71503e23015e31ff35994b1cd2c820b484baeb21fec7360392b1c))): {TokenName(26a82b25adc3982dfb2e1b9e9ecd78db0a428768ffa6304b6bdee9ca7809c947): 2509698740, TokenName(544b3d47be42de0880c70db985bccdf4368e7875d2f655f20d721363307b63d6): 4111962369, TokenName(54c885afb2f13b7aec9ed0effbbc81662ae2a0053f56f8807aa62e09d537ff24): 4044612435, TokenName(87dbe312baf0d7feac7548f9a155a55569ba7aa6c13d78b84eb09032ed60ffe7): 1674068454, TokenName(bfb1a81ac798b327de792926e337cb4899c4668a8031ec408d0cb98af0134564): 2932569205}, NativeToken(MintingPolicyHash(ScriptHash(506554a77c0bc35df1947eb3250fbd9e292f4432a4a2ff74128a397f))): {TokenName(439d05f17c19d161244fa33839aee5a99bd0d1d96ef3ab76df7030e52c45c774): 267031124, TokenName(b78a7e2d0b8f0f0c2d681890b1993e4d07475ece09b8299b338a59d5e34ef741): 26262469, TokenName(be5d2c2298065f139f51271c2152185f1439918931e2a01fad8ca4679903bdba): 3444892365, TokenName(dba75da7e05379972a38b0bcc662964b2c54c90d64c4827248ff7401f23faab9): 1821064483, TokenName(dbe5b65491100fa42fe74d95699d52141d711578ceb72e76e80b3ee6126ba736): 938105178}, NativeToken(MintingPolicyHash(ScriptHash(c52708db8b7bf379da28b854585b9e41e1ef4ddf280637242234c7c3))): {TokenName(39304d824080db9a5f92393396fadb520caf77b59005cdab0e7577fa3302175e): 1358842347, TokenName(9625a14dec1bdd9c5213a0bdfa94b1f2c1a0b7df4ecb242793c14a3b31372a31): 1058507408, TokenName(b0138894459709be46c58cb72296528b733914a9180fa065276c9b0d6e3903ae): 357692970, TokenName(c8758a70c8f7c460a6b8ae7abfdfd1ca71ee6b3ba1ad0715ff4e73ee185c2fb8): 1430671755, TokenName(d1c16ca432c4c1cc92ab405a97187a95004a3fd080124fde773bad74ace36b5c): 1799919870}, NativeToken(MintingPolicyHash(ScriptHash(d5094112526dc3c02d9b13f9b413d6cff40fd5c49b7d527ed6c77f41))): {TokenName(16ea7c5ba3b66835508e420048d0dd8d41dc2738491eca2c3abb90e44288e86e): 99281503, TokenName(1f993c4e33549663b914e109b07febe0a75720cd4960868b2cdf0a5d5843f22f): 1347731095, TokenName(2139f3b6f0f5a9e72ae394625f74e1a12ef8532cbc0ac071d67fbb3b95ff9698): 3585489705, TokenName(6afa274e6ffb96915d6db3194efecd2dde12f27aa9c5c34df9696bb502175d17): 3202351991, TokenName(a84e820c2e895166915d731acf01b890a13e90cfe15270276c6a3768fe0d1544): 3632298943}}), d_cert: [DelegRegKey(Hash(PubKey(Ed25519PubKeyHash(79a0ba43c4dc29215aaa34288b7b224ae89601f3fc5389d20766f02f)))), PoolRegister(PaymentPubKeyHash(Ed25519PubKeyHash(b95b9f24ec9eefc8844d44457aaef71f3e8423fa97bc73fdd8eaf96f)), PaymentPubKeyHash(Ed25519PubKeyHash(f54ab714fa6c5a7cae872c8cdb41c775bda9884f584a167ece55bfad))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(3263202212), transaction_index: TransactionIndex(1615444231), certificate_index: CertificateIndex(3527070464) })), DelegDeRegKey(Hash(PubKey(Ed25519PubKeyHash(8615ab504d3c130a55f6a0df284c7567b4a364d7f3cf84f7a198b4a1)))), PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(f8230b5a2e33017dc500b50a4d6ca2e972684a1a4ea702f02847fa35)), 233332572)], wdrl: [(Pointer(ChainPointer { slot_number: Slot(1937832358), transaction_index: TransactionIndex(1604387045), certificate_index: CertificateIndex(2991349637) }), 3602438527), (Hash(Script(ValidatorHash(ScriptHash(f80da816a225e3d053edb7c0a4359ff32b912a281520270d46198cd2)))), 2565874968), (Hash(Script(ValidatorHash(ScriptHash(648918be182456922c4fb9b12bc741aa21d65671a89bae866e4a9b22)))), 537790796), (Hash(Script(ValidatorHash(ScriptHash(78068cdbff32a36b7e5cba9020908329833f1f4429b661fb50aa4b32)))), 1854272316), (Pointer(ChainPointer { slot_number: Slot(60968441), transaction_index: TransactionIndex(139981048), certificate_index: CertificateIndex(3245224625) }), 3908710790)], valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(27131238)), closed: false }, to: UpperBound { bound: Finite(POSIXTime(706034310)), closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(ad36d045a57bf97ee7bf174af25891d8353250891086da213b593038)), PaymentPubKeyHash(Ed25519PubKeyHash(963567c0e649c14a9a382c29c9dce945685d117d6d1925e142b23585)), PaymentPubKeyHash(Ed25519PubKeyHash(ecbdcd8fcaaf29f36fd1bcd6bd10adc07058e101096d7ceee5679218)), PaymentPubKeyHash(Ed25519PubKeyHash(62c7695cafb6cedaa6d472ea0a940c61be92e94fe9c16ac2120746f2)), PaymentPubKeyHash(Ed25519PubKeyHash(b48e241660b29965fbe69fe7715ba77da52b44b7718193d6e62c8876))], datums: [(DatumHash(07c4afac8aa4febb64542fbcacd4302ffa63b4e839c2afd30e1f67fdfa6573de), Datum(Bytes([155, 31, 63, 241, 225, 191, 146, 49, 122, 27, 155, 59, 207, 177, 102, 7, 227, 113, 176, 183, 38, 44, 146, 16, 184, 183, 224, 244, 49, 179, 141, 252, 227, 31, 107, 159, 204, 75, 37, 33, 230, 81, 148, 155, 105, 192, 129, 255, 178, 64, 48, 55, 214, 70, 87, 226, 70, 79, 147, 223, 60, 247, 33, 212, 193, 70, 115]))), (DatumHash(5721a5f6c687c22b7c570d6aed4fffb594152802ea233d3d40f7e2165e6a1e64), Datum(Integer(-12882160068102115190))), (DatumHash(edf391db47922f85345ad6d6a2b4b6b3127e3cf3b7dc3606a0e7c906536af5f3), Datum(List([Integer(3907966504468315242), Bytes([39, 242, 75, 167, 202, 196, 13, 129, 184, 13, 32]), Integer(6525451893793250397), Integer(16764816957189074843), Bytes([245, 208, 254, 72, 135, 209, 189, 179, 20, 1, 43, 244, 216, 38, 21, 7, 126, 228, 245, 110, 165, 170, 198, 223, 176, 165, 229, 12, 38, 174, 117, 217, 27, 24, 203, 254, 189, 198, 33, 102, 154, 74, 72, 183, 186, 228, 67, 225, 143, 174, 63, 161, 81, 221, 188, 139, 227, 111, 43, 6, 80, 79, 73, 28, 203, 137, 46, 118, 37, 139, 249, 32, 89, 129, 50, 112, 39, 212, 208, 182, 211])]))), (DatumHash(c480643d03944212c448a34b299112f4c5a413ac456d2187d7085aea1fd7540c), Datum(Constr(3887588070, [Bytes([15, 124, 53, 171, 89, 35, 14, 221, 6, 253, 13, 15, 211, 61, 118, 42, 152, 184, 133, 131, 153, 99, 214, 173, 163, 85, 5, 92, 129, 247, 170, 69, 3, 248, 43, 108, 139, 24, 176, 6, 112, 115, 220, 6, 136, 103, 184, 64, 35, 72, 163, 232, 42, 166, 150, 140, 69, 230, 152, 230, 175, 178, 187, 154, 42, 135, 179, 103, 159, 67, 177, 52, 243, 20, 216, 235, 235, 215, 209, 60, 197, 44, 103, 10, 210, 91, 97, 24, 184, 73]), Integer(4317692085593261322), Bytes([24, 52, 41, 140, 0, 221, 148, 139, 145, 76, 209, 48, 197, 219, 62, 18, 128, 191, 62, 48, 19, 212, 113, 181, 225, 186, 0, 153, 64, 136, 32, 142, 234, 231, 156, 97, 220, 124, 133, 7, 18, 28, 144, 194, 60, 34, 42, 155, 151, 65, 34, 15, 54, 121, 97, 60, 95, 127, 169, 73, 247, 202, 125, 59, 120, 164, 36, 86, 149, 191, 216, 61, 237, 100, 155, 130, 195, 42, 86, 114, 207, 124, 131, 153, 4, 201, 152, 11, 47]), Bytes([188, 95, 116, 198, 186, 117, 13, 98, 227, 200, 223, 87, 163, 7, 168, 229, 216, 128, 12, 168, 243, 170, 57, 78, 108, 124, 24, 229, 141, 222, 120, 34, 65, 225, 73, 22, 58, 84, 155, 153, 13, 219, 47, 183, 55, 37, 53, 20, 113, 215, 239, 175, 148, 237, 27, 137, 111, 213, 124, 182, 18, 42, 145, 221, 124, 82, 24, 193, 62, 156, 159, 136, 187, 183, 56, 36, 19, 91, 250, 53, 186, 67, 182, 152]), Integer(2739006915478014080)]))), (DatumHash(5ecfd3be33d50f1700eaf26bc89b5321440da25da6a6b3cd28239dc2ee862c14), Datum(Integer(-5478635978075832525)))], id: TransactionHash(10070c59ae8c54e6a55f5fd485be722f2188813a2d4ee85b967c1dabb8844024) } -cc 5b67775395d00084146293e9c736691f6b9d7e7c02bd598321e92dbe73e96092 # shrinks to val = ScriptContext { tx_info: TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(000000000000000000000000000191474a76853450311e459ea0bcbf))): {TokenName(02b8261c1a919c2a4edc1336f3f800f7d3ce205b855b663715ee419987f88bd9): 3741398057, TokenName(122e280b426bc6440c4914bbab64f6716c473cd7a834e69121531a5fafb8601f): 654288552, TokenName(1ef9add2aa5b5e0398f77271c961698672d4d5fa325e6d013ff5c56bdfcf7cd3): 3559370096, TokenName(5fb8fd82d40a6718a99e9dfbec998930d8bbcae694172c5fda599c34109186a4): 2326038209, TokenName(f29f9fb017cf64c52e99aa6f929a69a338ce851fefecbec0de399dc7c17eca2f): 420951512}, NativeToken(MintingPolicyHash(ScriptHash(09ad47fb5d427c06ead6c080704c5b54db22f8839e5d3dd3d9f3be7b))): {TokenName(0cbb0b58cc8fe06f68f1a051bd9b01139e29f9df94c41af7e9e613ca3f24d167): 3210002966, TokenName(1bfe601a6acbcb51b1ddb78f72c513d2bf675f083f2a9cb11b6271c23ef88303): 2878634423, TokenName(68c65ad36070cb103054fe517afc32f834795cfb7b396e1f81294f3c8ce0a7fd): 3424265698, TokenName(77cdaac6df8e71fbdfabdf10c59a8ab916d164f6f47962e1fcdf4a4fdb08fe57): 186575199, TokenName(89c7383b9b247ff0dc033db43bfa07e41643607d4ef1f723a9042aa20f97628f): 3027129771}, NativeToken(MintingPolicyHash(ScriptHash(5c6028075971111bb7d5a311620a9f9598a55012b17fcc9bf34d8e51))): {TokenName(0a4881d8358303a6783dff3d3a73e595e5f8c01fab43cab26b5cc9a5a2adae59): 2460376216, TokenName(2345badbe25dc64f27c6d95aba4765b2c8f296f5e289ecdb90682206f6cc9359): 406994353, TokenName(a49de8d5803e9b560ce09a8af3f35eb350bbe87c8fd05e5ab07d1346bbd1059d): 3808232177, TokenName(c01e87fef3a79fd3341efbd3f18ee3d7823871582944fb9f21554a2ae9c2dc03): 3723094029, TokenName(e1757f18a06e8f4d074b922cb8df6a2be2efcb009808683347a8556521f07065): 820504965}, NativeToken(MintingPolicyHash(ScriptHash(7c6669cdc6f244e73658891d9b1e325f86d93d90a9e7502c797f2365))): {TokenName(155b07443913def1ffc7519d09512b79cccfe7ddf41f88f03b40e75a018b4a50): 638751769, TokenName(1e70a74aabf7e7ffc1971ca0729f393f0ed1c62350688e19d6c3a0315bf5a1a2): 3770825174, TokenName(a0465ffbd5acce57dc044b1268690c8fda0b913138145471e5d6e0fb3f15adf0): 1179534545, TokenName(be97d351b0dafe427bccf0f681c003c0bc89b06df02f9f3189195da954b7de01): 1552631648, TokenName(c0dfc617ed50ddb1e558474e6279c9e04ddb7a7c86067263b2aca5723a24687b): 1913074831}, NativeToken(MintingPolicyHash(ScriptHash(a3d435f2e7c8994929ba4e35d582110837cfca86e09ad3fa3a211bcc))): {TokenName(00a5d2f993fb2f2b9e81bade8ab3bf17401ace6d37620dbad95b34dfb864fad4): 964051070, TokenName(0259879921cf5b941f55f2c39a89ebd0588fd001e5eda5850c64f9389e1ec74e): 4066364501, TokenName(12121d337fbc5df3c61ff51a6eda2b32a635a141767f37ecb598711960a74398): 200844655, TokenName(421e4dec5dcd04567fb0722a1e22f09be6347d842c0549f5764629c9e20d6214): 1508702313, TokenName(661d5e817282516b0bf2de71b7da3bf3f31eb02b25e973e147cbdd9659f7a3aa): 3223840276}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(90968a9f232f9a4040c212665057fe487e28ce184d4306d903f0e34f7c224096), index: 3641377350 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(6553dc7078f97704252e42ea40751c8722fc88941100d5565d696f84))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(35443bf673c7b6e9a4d9bdc516d651a5d70c9c5e5c57cb9b7140baf5))): {TokenName(0d6c266b803c69c8cf7abcf12f009f3317f141e4e0e8640bc3f63bccbfbad126): 3220666971, TokenName(0e3ade09e2a305d4404ff0e66dd8d8e12afa6a7d31ec6a71636d9efcd45896f1): 3258366934, TokenName(456627e2f2ee9feb907f47d18c372fb02a305af3793eb53db91fe832e41e4444): 310994589, TokenName(68104a07401575ef47973cb5fa1e99c202b0da1734a34a0e59c7b9f093a59575): 1709980727, TokenName(df4a24784f4580939d8572d82996fd0c4c7ca5e8c266feddbf7b45f960075a1b): 1789775407}, NativeToken(MintingPolicyHash(ScriptHash(58596adbd52059eb96a87b60716545d064e07958131652dabd266ec5))): {TokenName(20867789de37754aee286df02b2d990ba7f6269fa9000ce35f8b4cf0fb5dea34): 3812777250, TokenName(6412c6875897a645fe2897e359e636334a2e9e1371292c09a132c64f7cd4f0ff): 1539272861, TokenName(662cc9ab8cf6df0f65069b86911e3ee924ba3cdd9e39e422d61c77032da139e5): 799707873, TokenName(b7f3fb70a4cd95836612de6334d68bd4316f357aff00d39b28e380b9f26cb2fd): 1299895896, TokenName(fd4d076e65e99ed503be37ba9c4601c11ed4b4bc8d04e6db25af4d5e4b7a3f81): 2058427791}, NativeToken(MintingPolicyHash(ScriptHash(6cfbfda004d5bf6c151a42c5346a964593497dead12cd96af9eb3eea))): {TokenName(2caf6a41e297f15c679cc92b87889c248fc443e86c9ebf4984dbb2760305fb99): 2039368744, TokenName(4699c6cf992949d42e66b83ef85ea3e97013954367e81bb0f312e7ad8c5effec): 822612872, TokenName(b803b6de56c16a077dbcfffddd6244a272e3e145e92d3764f59eb3dea01629c2): 4243055907, TokenName(bb1d53625c876b46bcd5318e00a74fff66a73baeb5f76a22ad7e72751f67d97d): 1460137028, TokenName(e5d3b3e8d61b256b5bacab98b24d63adc043260a48c90e57b5cf42c28e6d85f3): 624435344}, NativeToken(MintingPolicyHash(ScriptHash(7563f3d45817170b9d62bf297011c8e97673742663f717501c8c2d65))): {TokenName(4189bbf0935681c636c80b1d7174fa72fea56b8134b37700f5ffd281a17ca51e): 842749751, TokenName(7bae52f99dbf9370e82919e2559076784048ebccfab2666969b6d14c6c8a9fc0): 3797446519, TokenName(bdf8a0ba95bb1a9163b899eb36885da0fbab28fec4bfa33f0c7f8220d2f08b23): 34063203, TokenName(bf1471aee72a680fc44a61c367d54329011f96518e3f9f9499c2544d0ff9cc73): 1140296512, TokenName(efdde985c6e67c42b2dbb265ac37de2367f534c5c41d092ce6ccebd27f602416): 3103884496}, NativeToken(MintingPolicyHash(ScriptHash(bfae0e5f766ada3d5f465826372272f0bc04ceb787a72dfaa2a0b7af))): {TokenName(0804e35e6de2c11f269a8fdbb1a140a6202d1572f6694f9d31343250ba6262b5): 1800349224, TokenName(1bfb03fca76bbe5649070c25c428cd471d630a1034368b9666657d241d25427a): 2875064961, TokenName(4350135b9fb0839afad76923a1619f7625b799f8d6b930f22a6144c28e61f3ec): 2290497488, TokenName(6ef334575535fe2171fe3c73b0924c3819221f1755a15f118ec7c8a41fb2ea46): 900110570, TokenName(b0dc8a3f410328a6594cfcf03fb41dea7da07242865d5613123c88387423f7e7): 2605534417}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(6a17f19622e54a4aa37b064ee4e24a20dfdcb07b3de6f47fb3c371b6f8613749), index: 100036086 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(f9760bab71336319d2f2bb914f6b6d330a23d1506a487669766aa7d4)), staking_credential: Some(Hash(Script(ValidatorHash(ScriptHash(f3a9529dcaf233c0fd0adab1b69e37fe644c6d4abb992d6392b34777))))) }, value: Value({Ada: {TokenName(): 11066297076483743775}, NativeToken(MintingPolicyHash(ScriptHash(031d9bb3d1411830b73ba1fc049615e9f45fa540eacde49571f7c301))): {TokenName(3f1d1b0282cd4fba8702f11fa55b09d992e71e91105dc8921361be00b1e8cec9): 1574137814, TokenName(a3d6f82f057ecfe85e84598adf4f65f45785e2f9be068eb50723dd6c0db7888d): 1938268472, TokenName(b5cc2ecf75a2c0b216fb3d8205646ea0b0e927b64610b3bd55a570d1f005f0e3): 676331517, TokenName(c5e3402a575a7c6ae3e212cf095049be55803c89dd9dc3d91b22bc555e33234f): 2841681065, TokenName(e046b40f7eee648cffe0626d3e2a8f7ac604fce6d45e60ef5f1c269d4ae6973d): 1431309354}, NativeToken(MintingPolicyHash(ScriptHash(1967a4a232cc3759fe999a7dd98ae362e4a40fc39a8aae762b6fe684))): {TokenName(3605b2c90af1caae18eb81ffbb2b368b175a884531fd3dc9bae80e362395351b): 4060630825, TokenName(417870f35c6e30e5f3a4d851627b6130ddf0499ad40efc555fb831000c7af841): 4124959856, TokenName(484975a0f681a225d3385a10f2d65e6284049c73dc40db5f6f2779f3d2e4252c): 3927739254, TokenName(4c3e7b6caaa12a52a6ba46b497f3179c2ad56964f2157112156f73284ae06be8): 2891551242, TokenName(664d4d2357681f8194918bba9065deba4c259dbbc5a884df79decc6865d2334f): 4068940355}, NativeToken(MintingPolicyHash(ScriptHash(5d44c88feb6fd0af06f7771634c378184f55ae4bec36d1514757c70e))): {TokenName(0141ef48409c65b88ee9e4915072dc70fb0807c1d5a2edf872594db7efa5d451): 1863090885, TokenName(28ec4004b285b5ea031ab117b7ba8c861c4c0e87224e25a3779013862dd1a54e): 2618154546, TokenName(3d78cb6af48805c0629ed76522b460fce1c67a029653e5ae0d28a6f35a1675ee): 3906139411, TokenName(df643c48efe37d66bdf259d3e089600094e1eb74a0627a51adc0001b13c4b2d0): 915052555, TokenName(e7175a657466a47834e5d7588c9299afde82db686fab8e1d9eb8c5c5c2cf99cd): 3407814322}, NativeToken(MintingPolicyHash(ScriptHash(cc8714a53e1f4dcba661b80fad7070c3fc90b76986a89e51752cf98b))): {TokenName(a7f41f959a06fe70f6220f5b97522d48053a72e7917c1553ed915ef84f66704f): 1973847202, TokenName(a8ae516b2cf4e515ffb674529e6f2258a36829b19fd3fd92ae71e2cf783bc156): 896623724, TokenName(c6568a357f6df7853a1e06ad5bd141cb0de9776e7b0094fefe9241dd53777878): 268506596, TokenName(cab7c2316939386ce4b949ccb600a2bf42c5245b03fe48384e5b4b887881a95c): 123529537, TokenName(dce1f1f8bef90320a2e5cbae9229febf8ee19430bcb0b588aa98c3cd626eecd2): 3870790961}, NativeToken(MintingPolicyHash(ScriptHash(d94a89403fa59a90d30e24d4fa2d3016d11c7d54225b6d15a6dfa362))): {TokenName(50bf6d1415b195fda1639e70a69ae25bb8afc4a76fcedd55e2a9aa6813736f97): 1884504357, TokenName(58214e0e88dd2b118a788fe10bf71420cda84bf0e45d3e6e20e109a5fd1ba53c): 1968034309, TokenName(5f0764733b323a02bb0c92cce9fb830c068d689d30da5813b36ce733cdc14b84): 3976413660, TokenName(9744f243b0e341e18a308a1df8b476ebe076f1f30e7201b918ea9052ad17d400): 1491965510, TokenName(b0fcf171cb061ff37d359d337d3a8926edf3a051e00fc2c647b00d18a6208d49): 1195040897}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(f4c9da0c2f11149a84b29d8b029dc6845e4404626cf09c9f19840b831f6e1fd3), index: 3471291294 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(6a5536fd7cbcd6d15e3f36f291cead975171e36a9382d2cd5651d268)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1892659501f0b262889f4333e1b06f3e29c093822f1b62946bae97d1))): {TokenName(221f39f94ca6e001b5067384db616b6a7acfad993652d5841a08e3c4d30ff024): 2435908946, TokenName(28874851aae59945689b4f67424cbefe463a083bc974077d7697db2f25a4c8d1): 983369265, TokenName(70fc9dbdf7cd3c5c91c23266f33d7074c2bc7a8f1da436241fc0b633f5ff855c): 3942208370, TokenName(7fab7dd506ae6b9b4206545d41f2f78d851acc80a9087f8e53959d185ed5900a): 2836654077, TokenName(dd5d410d8e0ad8189f1b6538559a214a04fe38d987157de9c50e40f7046192a6): 2545022988}, NativeToken(MintingPolicyHash(ScriptHash(2f47f0226f42521492880e6e943cf101db929cd2c3df834177504300))): {TokenName(361ddc1bded66001064ee3ca623b2e456a93a572897eceddb1c7b4bc7e346c58): 785013788, TokenName(6bded178d1d759bebadbd549155540a5afbf88807434ce4e6b50086ed011440d): 2613671219, TokenName(772b8c64b3ab50676580a9ecb60d3545307e4d5a6ba97c667e67e1c10dfeec5d): 1809722074, TokenName(7bee84902cacce82806302cab231771d0d545876782500aab5639e1eaf443900): 2950267549, TokenName(cf9a694d089c3d25fc23ebb4aee9cb0f49629fe92d4aea823aac3ca22696060b): 2670860841}, NativeToken(MintingPolicyHash(ScriptHash(b3388ed819850cdf2e2d912502ac2abb28e5d70a9eff6bd82b74361d))): {TokenName(2e9c3e991caa2158f2737271414d1cc721a797c793b47bce36e9eada8fa58ce9): 263107722, TokenName(8c8e5656a2f9d4a3ef583ad9cbb1782b93b87a879222613b37a0409fcb95d7fd): 3215128855, TokenName(c724c4ae0635fbd270064643ccf1a8cf9f6ae91e66cfeff0d7be3281ceabe5e8): 4168052425, TokenName(ce9d4a1748fcfc074f0685cdbf4e319ded7b5bcdad0ebd52189bcf9b16a588cb): 2351570092, TokenName(d4efe360d4d1d6741c8efd2b69905a389cd0207b14c8185290318bfe63ca3ad5): 3724700142}, NativeToken(MintingPolicyHash(ScriptHash(cba1beb2925fa51eb87b6b65056021353dd5b7449db7c7b944facbfc))): {TokenName(466fb1ee99b1bc4588a62ff02f1d1cfc1e87c5f2a5ce323237994983967163e2): 1657790938, TokenName(ac1c04610899fe8bdb6ddf0e50359268c9e70ece93f0989f1574a8f592d40a25): 1032818888, TokenName(b24b23a373a1b04e93dec3da52e8d39ed80a215b724ae9f4deb35191c6427490): 2572413570, TokenName(b5c7725559b6c2056c7f3836d9f318f0ba04a785e2948a683e03e5e479dd9c27): 3435926259, TokenName(ee8ee91703a3653b45403e5f5291ee77e9d1b101ba8c2ff1e0a1548993ca12f1): 1118399916}, NativeToken(MintingPolicyHash(ScriptHash(da17ce0dd9fc880a89e1729304018f458db72abd131036b33573f259))): {TokenName(48a966713ab5b07d7d73fb48c605c3c3be66a51244f10220827c9207d778936b): 1773930055, TokenName(4d3fa0536f5564719d1de1923eac9643870284f1b8d97c6ceee834531d5af347): 1604427068, TokenName(790e51d1aec36d087a862bb9e3cad7ac523f8d151fb5e6d42aeb8408c68fee13): 4257658286, TokenName(dc6639db2c3ffd56ec090984d0ead105d845f25290f6ddb4f443bff69dd31451): 3146067101, TokenName(dd125c092d4c63b702ea569114f15c41ab4981bc1669350299ff0e41d44b5fb6): 271827712}}), datum_hash: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(5879dd6967db44cedc62952106884e56aecf4e7c4320dabf4b5935b58ba5b180), index: 3485704920 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(16d5ed17d22b43269cf47734eb3b4791779bb8f0fd4ee8228cafd674))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1b64d0eff8511e7e71840c375382108a416a2e1693cc9a8267c57d8c))): {TokenName(276ea1e86fda2273cb40f402d7a2460cb27639da86abb2ef78b0194d1a31a2f4): 1211614096, TokenName(601b8aa8570cd9708e461818c8397225ff3f2bfb567f576bbd75c3dce165a460): 1969511630, TokenName(6175f3679a1cbe4af4cbd9cc838f1e454442b5114a800efdc1cd2dce973930df): 3358248541, TokenName(bfcf5347dc6dc55145329b53d20c6b021025998ade52cd93788c1cf9036d12b1): 3446740241, TokenName(f1929d7ff3c4a1125f0aa39a6ff07cd5c441e5be96f2dbf26c9850f8255e61ae): 101120211}, NativeToken(MintingPolicyHash(ScriptHash(33320ba5d954cec458cedeb51f379d8f1a03c63bf2c766575aa290bf))): {TokenName(659fd962a912782749f64099d5ef62c7bdd76df0e47e801dd52355ec2df96772): 3681355845, TokenName(9555fbee47bcc0e066c2b057dd0b58a7afcf00f683375a5300215044a2e703b0): 718630574, TokenName(992f3a2b9d1bd964fde0f28702f127a5eb6dad458cc9ad0975c8bd2c6dacd281): 3143767483, TokenName(a6d3dc33838e4dd7d5854840cf7266ba2de7a9f2cc645e0bba2a83158d518d51): 4001142531, TokenName(f86ae4385152adaa40bb91d1e324d5b9108142315fef1d745b3383c7bdd5e818): 1669088936}, NativeToken(MintingPolicyHash(ScriptHash(4ec368489e7c56d7f33c05f0f13e0d01c262aea9e9b7b9b1cc4ee5d6))): {TokenName(1da397e76c46dfd80a6ba27cd499780fb3010015fe1eeb414e57609f5b3b33c5): 1021749616, TokenName(4e8e2c6617ed3c8ce96534e7bddb53acbc5466c8b94add08cac996cc83dc3518): 2046357757, TokenName(5debc1e877eeaa22c8f297fdf2ce594d796d96cc321b2b1615c88a26630e8b7d): 2281547075, TokenName(63f44d9e7015d3a4fed840475fc6f044dc05ede4aa87275423d06df5df19d2f2): 989038786, TokenName(9ca72b88afafb80d5cf76f4ac650448a67b22a89cdfd4af40f12c322e2cd4efe): 1137235049}, NativeToken(MintingPolicyHash(ScriptHash(6eb6f16596b164edaeda09d0668c970246766bfb483c8d1b5b626dba))): {TokenName(2fb5aa9f090019f81e67e7e18dbddd538112e7be1c05c7071887f00a425d9b2d): 1239704588, TokenName(4d8ed293429a0b79a2f49b6647a018642cca2d18bae093d15437d0076d82e8de): 1776598507, TokenName(7b07018feac1207c443cf68d29249e633a362922c4d748fb7f4cbd943afc6b4b): 3822481022, TokenName(874d2a492dd2b6c282b09816503cea74a3374cd8913a38cb5297ef0bff5af29e): 437540623, TokenName(a1e6f7a9b2592d8a74933b6018143fce50f2cdcfe22fe7753c0e3c59a7e66d62): 395590863}, NativeToken(MintingPolicyHash(ScriptHash(999ca846b08dda1099ecc43c7b5e110174d0d25866181f1236ffa98d))): {TokenName(019eb9984fe708f75e2617a90ca8f330b68ca0ea30a43324e62cb2f29792a941): 238253765, TokenName(24ffed416278eca29e73cf12ea2308500a71f889f765690d51b6bb1b1f22a0a7): 753468915, TokenName(5dbb7cc66a29e0a44163d6223794ec202c880557907574e8e0af58b82dc974b4): 3722048720, TokenName(e2304c5ca3f88be964f9b2bc6ade3e3e267cfdae3732df80cbc97d4fc98dbce3): 1151645541, TokenName(e779ad879e44b0dc7a8e40c39908c27fd05993c111ef255f422b6c8e13a98e63): 4157772306}}), datum_hash: Some(DatumHash(657287e635f99601d25672040b09ac56ea18a55960088dd59b70ad7d04fe7116)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(5410f27c1072cfb57633a166cb06dc7f63d197f57b280dae1c92e373)), staking_credential: None }, value: Value({Ada: {TokenName(): 2236402502608423157}, NativeToken(MintingPolicyHash(ScriptHash(37f5493926c37b8fd2fa750e7c5ac4453500925fed31390d16d187a7))): {TokenName(8abef3b5a2e98a58775628e7d02411c91c9210efb788695245aa1ef9b58aba3e): 1120796524, TokenName(8fe2c5a30b736ae7dc3490502fc0ef84064753d439034097ef9ee379473c7dc3): 3576353478, TokenName(b27b491ef2b05836aaca9ef9b2e611dad4e0ede978758d071aeba684972426af): 83661867, TokenName(be70ed4d37a8ff547c1e575c5573170d1401bb3c003ce291c94685a1fe6b1b02): 3643189005, TokenName(c16f5aa74fb45b833aa6168fa7a2ce1231d5314e62264dc8ebea2194cac41c84): 1032182263}, NativeToken(MintingPolicyHash(ScriptHash(4a4c1e843bf65ecc5ca696ab9cab914183a997e16f4f3fa6265cb750))): {TokenName(1f115bc73e8f1c04d5c3a9edf3b9e83c09b5fe1e3104d8d7cd2bc99df23ff186): 3531971084, TokenName(297ff50147d03a27d09a2de562db7ed2292ccaec76c8700bedc2d135c7944ab7): 1219519124, TokenName(308d8ff13de1001b0848be9e9d13b9697d0417368d989571683c1bba36a1363c): 3605905568, TokenName(bec2f9b28b8a267f3fe5d5d5c711ae27ddf76b3ee505938d06fd51927ee037e8): 3060620575, TokenName(f026bcc21051e5ad2a321ab61c4b14a871dd1d45d61e4f98d8992b59ad983420): 3862631933}, NativeToken(MintingPolicyHash(ScriptHash(4d5f93ccd2c9b5bc0bc51df9555f9a5b3823139c67d859e538204dfb))): {TokenName(08deae698d8c725836a144e4721bf546222c04f47df98acf4e0c4f86534085e7): 2338878597, TokenName(229cc3aba89c317e4e04094c9fea0001c7346be0d0c303803a51896ce607294d): 979340440, TokenName(72eddb58606fb5bf6a259fb145f21ca13150d2830bd8001c47d7d2921cb53177): 1633054632, TokenName(79133b5053a3cbb622df9e3f314e8e6139e98434bf8f48585b07eefcfebc860a): 3762308518, TokenName(97b726bcd8eab247a4811dd05af608abea0db5b9941aee61efbbf6afb1565a1d): 1480211334}, NativeToken(MintingPolicyHash(ScriptHash(6be3949f84d857200364320e1a260682af5892931a7f5e66a1e6b22b))): {TokenName(0e36e47218f60e0e59e2bf44d460ebf7cc8a30b93f86ebea8fa58f6beec1ca77): 3590196303, TokenName(2bc0d6562ad16687f5a8eb2cf42fefda4cbd1cbafd663c8dbe478f89d2744795): 105976987, TokenName(5e5c56d42e5315b2a5a7003427e4e02070a2f222e689c60310a93b6890841368): 4109335879, TokenName(5fccfd2181d9544e2795a4521d2c397ac1f0d7c4a191656c3b604eac4b568583): 1270584497, TokenName(86918a5b0a3342877df524fe304b2e6b4d3c2f11873e14ec3f2ab3e4cb892e41): 3009525002}, NativeToken(MintingPolicyHash(ScriptHash(9fc9a94a4a5090b71f2a27860023b053298e49960420009eeb40e622))): {TokenName(01585c6fbabd257130a002f4c3a91fcc0139de3fff030a9959d0e2018018e963): 171502532, TokenName(56c81ccbad02d0f567ab9299134088a0882b4026bbee5a7d6c5708587f15b5a8): 3059613463, TokenName(6cd1ee5901d7547d5673dc72e07d20a10aa27d226dbe6fbe350185b70b48cc2a): 1483144782, TokenName(88e27c6a9fa0a32499dba4068bf904d8dbbbe7953fbb61f8863d726f2365a92d): 3942060868, TokenName(916ada24b31ac4a91b574e136c2a1c20cb911f14e88a513586f9fb871fdb443e): 1287286334}}), datum_hash: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a8030bfa36be16a64f8ac42b15c32243403ef169c43f61f82ee34f60))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2526288468), transaction_index: TransactionIndex(1423893661), certificate_index: CertificateIndex(1434755680) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(16b697ef79174cbff09178e9913caba27e7fc6388e93e9921a6c7535))): {TokenName(4cf873940e6b18c637aec69c9fd1aafd8e6928bec40e36afa91ba88892a087ec): 65884883, TokenName(5cf79433ddb13b2170a6401ffa528a969f5a4b98aae9cbbdf34276dbe4a10369): 1245109372, TokenName(9aef3dbd3f7fbbcf12acfebcf3c0b15cdbc3538d5b3d981932ba85c9ed7f2320): 3480773757, TokenName(cc20daadb793f37dd582e6cfb6656b0bea4c0b7807b695b5f8a49ea9b2f792de): 3171074411, TokenName(d90371478085e9f9fff95c83025ae4113ac2baf817f810dd466518b20f723505): 2368810595}, NativeToken(MintingPolicyHash(ScriptHash(35f1c74fb4c5ea9c12effb4102533fa0b170e35bce4a8e53369f81e1))): {TokenName(29d086ee45857772eb6be342451c74a5722bcce88df144fc285661d827fef1c9): 1392013783, TokenName(4c3d2ca9248357a385a6105906aa9700c861ef741ff21f09493b844124ab9b75): 725500744, TokenName(8f83c910e5ad53ec564a4c882b36293fc163a535730f37eb706f569e6e696812): 1744470819, TokenName(94917f4b89958bfba62d02bdabdc00a28d0491293a2d0a6770a5629152e605bd): 1150828174, TokenName(f632ac7774b14cf5ae8071a87bcb371ad0d0747157abd598a04d6b1643cde18c): 388479184}, NativeToken(MintingPolicyHash(ScriptHash(67849ecd96a82888f73345d0667f792be240c89d2a0dd4f962fb06aa))): {TokenName(5dc223b452bd882745a3c0f28acee5188a28063806f07af312e29f4ac906779e): 1574752114, TokenName(bf65de834423af4259aa29415d2705532c9bc5553bdb3fae9d88a79bd43a8f70): 736416511, TokenName(c6a2166230b639294ba5b794a809f495ba80e3c136b3f10d4efedbf0473c901b): 287728001, TokenName(cbf25d0dbc7172a5f932660210bafce1223d3420facd2a991d8510fa07ba6b8f): 4271054289, TokenName(eac70ec87a809b8cda02430b90e8041cfce0e9cc09f4e8972cead8ab1cd35204): 3829911799}, NativeToken(MintingPolicyHash(ScriptHash(c87e6ad4a77c08a9cd62704ac664b4847b8d3955343cc764e6799a76))): {TokenName(0ebf4dc6be026d31b6d3e89616a9b854274eaa6b27586684004732ef06ecc7cb): 3331548695, TokenName(714224a04712f420831f663035b5d31e676e11f76070d083912d5cdc9312f0b3): 3198236104, TokenName(8ca93cf893162b4eb0dff19d86db7652f949355b0c0ada237b0a3e6996fa03d8): 19227515, TokenName(9e6f2d32150069f192452f45da2fbb8ed5184f4ebb312744cc638c42756ad4ea): 2833663308, TokenName(a0e5f4ee93c14d2d0acc9d69451b5c4b7fbd492db0b2bb11979f98fb40afdb88): 3016347740}, NativeToken(MintingPolicyHash(ScriptHash(c94de030926a397f8f2eb5689d191ad62b2e55b0baeed260b1e1eabf))): {TokenName(09509d4b63818755ac0f87929ef885c36c51fc130b2b258b97a5c0392a9f1103): 4248747602, TokenName(78946fa16f926786d4bbde8a66a405d90c4553ffd44234518e3a734873c653b1): 3224251699, TokenName(bbaf846cc30bfe5df9a63d2b16b02cf4471aff42d12a9de48f72d75f4a108a3c): 1539058509, TokenName(ca348017e38d302443b33a3884262415bce7c2f81ec8c755533e31139f3892fe): 3749331943, TokenName(d398fc91851ef1074e08e4b9e4bfa89df3eb80f82473597e91df3e6ebf7768a1): 3885424405}}), datum_hash: Some(DatumHash(b628b6277edfff8d284ebc42ddf97d4a5efc09d629dab71f712398cddd60d820)) }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(bd0a12cd4086632eacadff7a35117757a005e09abd27e17182f82474)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2906389819), transaction_index: TransactionIndex(2498004148), certificate_index: CertificateIndex(2910959286) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0cb2a99edc13cb44382b865663f5f4a65dbc24e7841ba2aec5011028))): {TokenName(2c1184e9ef870aeeb81c9d0b3840e409908a48df2dfe83aed36b55f3167138dc): 1647705484, TokenName(8a774cc8014f0295cc6b50d65f61af46bb85b2cb26644bb9242642dbc2768cdc): 1375149956, TokenName(9e43844045f151ab9a64a727946b9c6d80959ed239109c24c2c814dbea4c09dc): 3736400037, TokenName(eb0e8c7312462a2388c7b76eab0e1fd8388ca9b54380efef95bc2ef4ab130ca5): 2516519196, TokenName(fbd7769644ccaf2a55bdb8af9caa0276101f7cfee2049b20d5a653fc532528c7): 1753111857}, NativeToken(MintingPolicyHash(ScriptHash(1d5428cd7a033b9b904169b213da8402625c298f88dc37a50be43d8c))): {TokenName(0145d030a9b4304b520b1c60a5fb897dd053b310030df6c5131afc4245f874cd): 2946533521, TokenName(03d49d46b9f69298a585bb7759c1d2f4c1bfce7d0187692c1897cbf2490aee00): 1883058736, TokenName(05e6883aadca625019882ba68fa8cdb1fd8267adefbf56ce16ff63e0c5daa9a6): 1828812533, TokenName(3d9cbd49c03af33640e1494a94f250dc97b826bfbaa4473a9544b4c96d062c64): 423948032, TokenName(a9284081504726dd673907aa6f6b0f4b4406e69474a9d8346f47d82319dbad76): 1980557188}, NativeToken(MintingPolicyHash(ScriptHash(a2bb8d90c8ab47d346d975e980a1d43f045dec292535093e0d51c864))): {TokenName(02f4d4e68cbc706e0d0c0837201675f3bdcbad8c0cbe95270f87b7e677e74589): 4059186037, TokenName(0d27ac444015385dc142b7f17854f6a2fd226eed40db00e5471135abd2614910): 893862889, TokenName(4c0ba14a4e81c539b8c1927676051248e1f0470a0bdedbbad99ba757742c37a8): 3677005175, TokenName(9f54572f0d7dbc278f65252ec8a9fdd605514b0eb146b43f7548637b5bdb6d98): 865230738, TokenName(ff85c18aaa31427a17d09dd8b1c92deefa98de67dd95b5134876d69bff07fa1a): 2197769791}, NativeToken(MintingPolicyHash(ScriptHash(cf5353435cb62d2163224104e0dae0078a694a4aaf190fee0ae34a02))): {TokenName(1648c8d0d1b49102baa656497e482412767fd18bb4cdf1cef1b3c358d7a89f71): 1711195694, TokenName(26bb953943de5e600739f97c4ce75a75764a1ab8a067cb3e7c29f3016217adcb): 2877718150, TokenName(815e21da7c69f3e64b810907bf5c44933407c2c5e8ad953abdad6e2b0a799e70): 977946915, TokenName(9353e34d7f9c8621f44f914dac8dde9cfd5000b9dee7ac693708d228ed718076): 283297721, TokenName(a1054626db4e0d335f46d7a7f2c40b742ad6c70b78c9f88254f1f84fc3ea8589): 968690886}, NativeToken(MintingPolicyHash(ScriptHash(dea44770355f847a4eaf18ba83b0d401bdbf98908efb0e8b1f897f83))): {TokenName(4921eb7143be35f9cdfee9b098bfb4e6c76a6fa916ba52f80e222caad6e57f46): 2851452302, TokenName(6a6493bf51f70f648010e4c5d9ab406fdea3f05951b51b917e846d03f01c50d9): 4152676206, TokenName(71d6a6180f26982f144f2cf289c96664eab73ea43b9ee9fee2fca7ea3b9a6468): 1380940925, TokenName(b6ab7566b6ea3fc735c39ba9b1431c3e5d1b0c8cb77325b4696035ab4d2cf546): 1747434410, TokenName(b902a0f2088eecb1f3f7f4f2b88c685a5840b62bb7ecc06416612b4cb9b7efd8): 2641353882}}), datum_hash: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(b2b038341412cba317cf86df6ef6e935449381af66030af75ff42e51)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(3342422d590ccd428b2f3fcaca1aa9b4d1e8f7366b546b1c6445f894)))) }, value: Value({Ada: {TokenName(): 4948328761542502746}, NativeToken(MintingPolicyHash(ScriptHash(072fdda177af7847e1d87877c624158aa2d98cfd659324f2b373c262))): {TokenName(320c45c154400fc4d8d6b5a8cc4ceb9f51f8ede2daf8baf0d4ba0316d675eda4): 411254330, TokenName(77e69c2eb1e08684727019bfeae04c43687cef2526d2940436d7d7368a816d92): 1855020307, TokenName(8a1cb9930c75f32f95ff8f133ea76ee23e833d3e0450c4a846328b5b9944710b): 250752536, TokenName(c48f515f70d52822afd8ec7f704a53eca595542f7ccfcd37fde27af4dd5c26df): 2374474381, TokenName(e3b15cfb883a25f465bcce8f501af658cf8efbee426829a9531b9763fc37ab11): 2313747249}, NativeToken(MintingPolicyHash(ScriptHash(093ee8ff80c2d0096a9fb455bef075e199fccfc1954bb2986326aba8))): {TokenName(44591cefd9a148f95a280dcde2ab7ef30813cda04c082fe16c2df07ab91283bd): 3029068441, TokenName(69e2c5f840466eab3308985fd9e16d25b366eaf31df06b19ade95aef1f306bef): 3504873071, TokenName(a8da02edfd4e5b1176ac9961ba56da291fe9907565da43a2a79202bdcd5bb4f0): 1138322246, TokenName(bb2f1a91b2ac39def8a7e55d990d4490a66a8c4415aa0399d0bada760b6db917): 1512771149, TokenName(bcfebd930b1735f727da96689b8a672368000e30de9877cb4e4bfa235b336242): 3239823677}, NativeToken(MintingPolicyHash(ScriptHash(5b07738191c965fbf02211ce93a8be82b130af907d547679d6b3c7e1))): {TokenName(130ef730af540f6e578167e20aaed3664978c350f0b29a5401ddc5bba0475fb0): 2033047369, TokenName(6652918dd53130e4cd9e04fc6bc61e86972acb68d642284a63885b162490505c): 733077339, TokenName(7f333a23849fa278b7b4c94f059915205a5f12147eef9ea272491799f73bfd2e): 87433845, TokenName(804070fb43e317d87955b340b5344a8a433e80da64cd36d2ea4ea57fd299179a): 1631450234, TokenName(870f4bc4ce866180c857901e4aa71cf8a1879916e3aacc0bef31651a429aabcc): 1324734331}, NativeToken(MintingPolicyHash(ScriptHash(90cfa5b959bb2669038f943b5bd9324b64f1fd7aa175d1e04bf593f2))): {TokenName(44c2177821ab02387c05145daea415f5ed1e17c9daaf44073db5e4c8f2a09b95): 1125997943, TokenName(5085d9c0c0ec21749772b2dd1d833dc89740983dcd0c23a68e2e6ecac1514153): 2928004275, TokenName(959bbf7dc15d9a6a0fed3f43f5d9b05d974dca9957da7a95e128721cb0b6dfc9): 2886942365, TokenName(cb9169ed8349bbc980d191c3a7f6a5a203b0f8f7b60876b5d2b1393d5f7e0036): 3635081973, TokenName(cd884cbd66ac62ea2aeaa479203c11bbe7ffe99c1e07d32809cf042521f146b3): 1702000497}, NativeToken(MintingPolicyHash(ScriptHash(a0db8a554393782bf4db132fb516da7278dca0ce40c0db3baa142a4a))): {TokenName(00d094c2cea576664164a22fd766a5cabf6ebd344528fb09bba89ab562ef305e): 4192416526, TokenName(0b428b95a12e8c9c5ce6682e5dcc6b1c3fb3899a4b707552afcf5dbd0154baa9): 2331618111, TokenName(0cec1dc6336fa94860d66be7580d78aebac53c1c970395eec552ad9b508b7b4d): 1504969392, TokenName(1d4a8587b38efb2b79414a04342c3d05f252ce3fdadca54a45f207e8f9c29beb): 2777991698, TokenName(53b02a79e80c31c85b84e0493abc93d536043ecd524cfd7d7fea032d05a6e7e2): 4119511346}}), datum_hash: Some(DatumHash(ff527f3d10e8feb4b6b49b4e5878f2048461ba3839a09858ba10b0f46bb5c171)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(e05c6baab226429642a0d4baa4a6dcdf0bc263d3435f5ae166c9a139))), staking_credential: None }, value: Value({Ada: {TokenName(): 4553602872540099082}, NativeToken(MintingPolicyHash(ScriptHash(17cf83ec7b334a11f0b4afeaca399f3f0655df3d47b8ae389b867cb7))): {TokenName(0fdb6a936ef95425fac91e840d467b4af2002c01cf41174166287b25cca7a05f): 2730309942, TokenName(1014fec598837f1f57a0d8932b527162d300dbc38461884018b7056f090bdf5a): 2791151522, TokenName(5576dc44909b08bad91f97cc4ec172a2d84291eeab5c53203668ee5110d58f08): 811998201, TokenName(a35801eb73e0f2cafe000dc265c49190b9edd8aa8846b5d7a4865c0927c4b397): 4122858360, TokenName(eaee31b7ac5fbb6b11665bb43ec0662b4a6e64e2797ccb45b8f0a75e280f1619): 2270382587}, NativeToken(MintingPolicyHash(ScriptHash(1ef6385877ca6778cf88e5ffd054ed90d66da25378cd568565a096ae))): {TokenName(329a62259a89c9ecad955d28201e94bcfe386a67190bb4b051b7166c45b1796f): 1494858695, TokenName(749240046949124728861c7baf181a7b5ad4a8f0c37d884dc79ccb907e6e5af4): 1710360777, TokenName(bd6abd5b26ac8e1a109190b25708d94da4bdc16cf244e79a096c72be24e0a0e4): 2190753389, TokenName(ecde2b1d7c514389b66afd1d24cbaa2723f07caaeee61913a9f9701e8349e36c): 1232171392, TokenName(f121d76461bb94330c69f12b123c279ec26b092f669dbb079ea18cd0a876add6): 4026230494}, NativeToken(MintingPolicyHash(ScriptHash(23b29f5815c42402017db7bd79d21037c19947ed7f2c11f7757ae6e1))): {TokenName(0e289ea4f9af5cfc43e20f747dcb24d12d3c7ce1a40d0ede72b9c0cf579041ca): 1173553796, TokenName(1692c126e0ee9010182a8cb4849aefe076fcb9a1f4bc94c274c311b2ef9e5fca): 284175176, TokenName(28e7a278b4893a6afb4ea92e417549ca644be330f15581a9cf8ce75b441eea1a): 2358327012, TokenName(af490988fae42de1353cea6a530d4b19a0c08ee8fbc39a216d8c83916d8b09cf): 3410120375, TokenName(c14d13fc0b208e9cce0bdab33085ba6c59a8852af0d47bac55a17fccbb1e7f80): 3055786762}, NativeToken(MintingPolicyHash(ScriptHash(7ffee3ce8d283d8aa14745314091ed0458569b8ea9e84c0f3e8fef22))): {TokenName(02ae89ed9dff3b2a587d4a4137dbddebcfacb888ecd2eb24003bc69b3e3208d4): 3054823407, TokenName(184d800153b13706258004f4d896b86d7228c5f0fc9437c5b5b26b7b1eb0fd44): 2454894028, TokenName(662bd5eae7d2166f3ef6d2d1ea8e0273f202caf1bb2cd7e6b54066a6a9d23051): 3022759543, TokenName(b31ff8f7cae312f932cc13677a0eeaeeb77fae01c49117ed7aa8a58960f30674): 3188065398, TokenName(c07142a9e17cb03285e1ae8a17a16bbfed16fef9effbc22857044d4289fa8364): 1465431524}, NativeToken(MintingPolicyHash(ScriptHash(e8e9baf27214acb30ebfbf7c000b8f613cac2e0bdd663626eeb0267a))): {TokenName(13e6135a846bf7bc213d4ae04670c5d5c886419513a99d4997193b552bde6dae): 4084850878, TokenName(37ae5df9337fe81423d7c7a41d217cb66368d85949a899c9312750eb5792c347): 3709611353, TokenName(a92e2356e20f6a58903c882805d1672dcf95e2447e42f22284f466dd8c6db2db): 228959620, TokenName(c589ec27c134fbedbc5ec2c33da74785245808c85c796903164d6a770b90001f): 1239222555, TokenName(e9f13cc81c4cd36d8684f0c049f92324c738137cc36b69546090385a717fa8b7): 3850436574}}), datum_hash: None }], fee: Value({Ada: {TokenName(): 969633109869906273}, NativeToken(MintingPolicyHash(ScriptHash(8d6723525ba3d1f1d6997c0ae46f9d85502e6765dd041161633c3560))): {TokenName(06303428b96cb3f1b1d275527a0b6039afda0c190ed10b559478d9cec0b7da42): 3814140804, TokenName(3467ba2a37839479cfbad1d28281dedf585a6c0109a4fa238371f65e9a4bf60d): 1131929688, TokenName(658e9b6b33c3eda9de19ea577dc497311d2a0b96dc8d6ff27893b035848b9547): 250668046, TokenName(8599f7565c24adcc16f57a3b856c4dce7e7a5efa48d9a0a91df313ab66845f24): 1236629975, TokenName(921f9da770507d599e88df415f5b5fd1ef2dce3388b2abe1cbeb8819eeb2752a): 1375718269}, NativeToken(MintingPolicyHash(ScriptHash(a171c162fa95d08d59c680fbe807508d41460683e736f2964856e2e3))): {TokenName(1aabd16381297021a0281493745863dba32e12553bd1b96556bf2e88506140ac): 3291925497, TokenName(2050da14445b8940d5dcdbdea4d274e6bf7873455431b2e634c72d0c4465c051): 620717311, TokenName(4f19c4aca84ea4a29ffee3440d3d824566e19c06010a04507ff7a5a59e302a99): 379732248, TokenName(a13bb873c9e1de1bb2cdc7f48863712f5e80eb212804c14b1db8ddba6dcdb29f): 2246452864, TokenName(f39ee6358be13089fad7c84120980839632dc2c4704e58df41d490d6690a7a38): 3334683934}, NativeToken(MintingPolicyHash(ScriptHash(ac9446f80204a60030165546ac6714046dead84812f05eadd94551a3))): {TokenName(25a0ee877632392e02cd43d00aa6a7ca261ba4556193e0dc396cf98c2af31c6b): 3444385402, TokenName(3e01f229172eebbc73423db906f42c63cadfb707992eec85eab601aaf5dc1251): 3790718980, TokenName(a58da0fc2411a07ed3e0bc47af2a2b29d6c113a4488a3be79b92aa3323986f60): 1134977431, TokenName(d66116b4056bdd548a4da2780337013fcf1c4a75abc7e94bb6cc446e404a3780): 2609803911, TokenName(e9d67a85cb032f4116e0ac6c323eab6404a56e1148b367a2bc8f8c55fe0825e4): 1014384257}, NativeToken(MintingPolicyHash(ScriptHash(e564398c9d94ef31ba6b710d366cd39a3a790dfd302991d2fa642e32))): {TokenName(0bfa888d52987c26166e90cf2304068253d96258e0c71e74a178604a84e89a5c): 4003280998, TokenName(31d69eab408c70a8c0f0449c9c84f8331a4a2abb1a427e712b3a6f48fe4fd256): 1888595874, TokenName(d624bc70dd5f611aa436de15c3e1e7535bba75e7b42342959e2391d7fe4c5c6a): 1989441865, TokenName(ed5d23f659fecceee3347e90127d2c4c44e161f547a4ae595ff29b6f88ba53ba): 2198525552, TokenName(f603ead8ade9a61b1b88bcb269b1c5f784a65451e29f1e7a0ecb8c48239fdb45): 3645297236}, NativeToken(MintingPolicyHash(ScriptHash(f46ef9af924ab79c91aed4987fd890b61fe27abb8ed9254e96c74cc8))): {TokenName(59094af9093043e8a96b5a6bf5a335b12ededcb9f01878f91495fd2819aa67f0): 1766038848, TokenName(93b8854769f208a0256f9ea596df9e52a3fbb06850c2498488f40c6b93f94da4): 3559068440, TokenName(a8ccaaea3d611fce0be3df7b58a22e351ac9e255c72bbb7d37855b81f910bc9c): 543249717, TokenName(be59a0fc8ce2d78d60882d184c66faffaf77657003d8dc9f70cf920147f8e0a1): 3750383943, TokenName(cb241e54a1f5e0ed7f8be8b6c54c5e128111ec57015afedc6e73913c17e97ce1): 2954796306}}), mint: Value({Ada: {TokenName(): 7631164501003577366}, NativeToken(MintingPolicyHash(ScriptHash(000b638318708d6910d2d4ca2cf92eb08f54aa76ef9288860580bdf3))): {TokenName(118c464ebe2af200f4a14649f8bed0b0ef50ee1bfed814a8de00953f89bb050b): 2442299996, TokenName(1849c62509f9c1f054d41d926038c23b684a646b1968e8cfcc4a3647a28754fa): 2030710250, TokenName(22cd5e8112cc3a3d413eb1d4de1d9c383b7534f45ea2e829b43844c22ad159d0): 471205976, TokenName(a945c6e456cbc77f35eb25e2b936de6282a93b0c0b63183f607da00278b92302): 3274228680, TokenName(ad86d0ad387617c24e81a4343fb745231aab4912a61bbff939f782cbb56d2968): 3179376177}, NativeToken(MintingPolicyHash(ScriptHash(0e0ad372d8a5549a9280d97575060f8d2f292ef7b1e173a60c4fca61))): {TokenName(9005e23d6a7edd5a420284842e7ae4097e9521bd2a4ca4bad7bdecca8b75d9be): 1363897572, TokenName(b7755a335efa50067a4757dab725ca8f41b1a0c751ff53d3dc21d0a05291c7d3): 2898233279, TokenName(ccd71950b2ba7cc3dc8bb1717bba2927ed15142e84934ccfff98d1c6d23c7d91): 1289247048, TokenName(d1312a57e53827c11f1df869b828865c50d17482a205e4edc945582385e08706): 3074462666, TokenName(eecbf9e4f9d0ef421f7a59868225cebf18f7000f6de30e0f8493cbfee4d04194): 4135510026}, NativeToken(MintingPolicyHash(ScriptHash(14c373113770b8e9a72a862f1abf89da699f73f44eb9b74db712a10d))): {TokenName(0fcf4d730e7463311d146a4d32a365364c6520bd22d40a4811ce659c05019cde): 1253206852, TokenName(25830271bae303c2a40cfe96cb91492f9abeb5da45b51facd1399c6c2b3aa76c): 1256411084, TokenName(58067388a86c970eeabf01414993b019d237593fbb4515b40fc7d6e29a52df85): 471578325, TokenName(6b7023af0f471f0bc78c7616ec90ea0f9fe0c8e4e3b0134e227d45736785d676): 183113714, TokenName(c9813c42fb1f38e268cedf35457615fcca99cc094405926ad16aaf4ae82567a8): 1385894198}, NativeToken(MintingPolicyHash(ScriptHash(4fdce36936b4e15aef63e7f608f0414dcba259852aca6893e5d2b9a2))): {TokenName(1a9d777417acc7644ceeb3d52f5586c0bda66302bfe3aeb680b87f06c7c4712c): 2870070021, TokenName(383a08a33046a06148ef0b38605246a0577d7ddfc2a9621ce83165164491167e): 1995923698, TokenName(9170ae6672cfffa3d2bfa40aa08a337aaed400edceace5c518da9f034aa217bc): 3250266866, TokenName(af5319c39aa37eb907271cb377aab921dcfb82cd28985bcd471fae49da966f75): 4015499506, TokenName(ceceac952f631978885d18466f653b68cfd4ce8ef8ac171ecd82a5f92a289d02): 636890669}, NativeToken(MintingPolicyHash(ScriptHash(e05864b623516a63e9f9e515522404b98b02b0b2221c54598fdcb6e9))): {TokenName(11d8fee4e2adaee17e985fccf6c56c114f86c60734853082add8441bf990b63b): 2496407695, TokenName(603ece16dbbb888998f91d1238c4a456ebfdc957834debf70fbb10d91ad7460c): 1108103483, TokenName(627d25c701d7696dcb6834b71612b51d575b931f91a5ef2e58fb5e8efad32ac2): 1195013276, TokenName(c13ae1979f893e33e49acea02651b6ebdc4482195d852ce9191499b39811a4af): 2197115122, TokenName(e891c9a502e6f8bd48e6ec0da44bf42d86e7f38840491f262d2cbba4f2752464): 2321083779}}), d_cert: [Genesis, DelegDelegate(Hash(PubKey(Ed25519PubKeyHash(33a2aeaaa2f2ea80b5090a2b82f487b57ceb931d469b58e01e43b94c))), PaymentPubKeyHash(Ed25519PubKeyHash(6a77b6f28a34ce07ad408232717d4946c493748591b8f35b94d0f25b))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(433742330), transaction_index: TransactionIndex(1845628647), certificate_index: CertificateIndex(2772472914) })), DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(742649179), transaction_index: TransactionIndex(704895891), certificate_index: CertificateIndex(2566189219) })), DelegDelegate(Hash(Script(ValidatorHash(ScriptHash(542497dc23302d140546cd8be6b86b518f704b858edcf808ac2cadbc)))), PaymentPubKeyHash(Ed25519PubKeyHash(7daeb663c2955e1c7bb6afa4005fda2c6ebcbd5bfef080b2e84395e0)))], wdrl: [(Hash(PubKey(Ed25519PubKeyHash(68aee271f2f2ed00343c237a0284243116bac2eb69c5d3800054efac))), 3319729642), (Hash(PubKey(Ed25519PubKeyHash(3a70e62fb80a360afab75373ca182ccd8b12145917e679784d82d799))), 1883636234), (Pointer(ChainPointer { slot_number: Slot(2507536261), transaction_index: TransactionIndex(2809721782), certificate_index: CertificateIndex(3948189935) }), 1091631966), (Hash(PubKey(Ed25519PubKeyHash(675e7d0092f2131828a0a0c1161d1cb2966896b189fb2508f33e3bc3))), 1036524356), (Hash(Script(ValidatorHash(ScriptHash(2a0df4e2705f4f465b7500d0448f5b86ce338f8f3a1ffc81936d613c)))), 2084137754)], valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(509290088)), closed: true }, to: UpperBound { bound: Finite(POSIXTime(1589796949)), closed: false } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(e113607d8a6900dc57999fbf7436a2b258b265c9de34b66adbfabfbe)), PaymentPubKeyHash(Ed25519PubKeyHash(9919208d63b0eab1469561b6160e620514a330a5c9687ea4da91eba5)), PaymentPubKeyHash(Ed25519PubKeyHash(84cd67e498c6e295a7f6d060445cefb3769342c7e6d80e49d9572f16)), PaymentPubKeyHash(Ed25519PubKeyHash(4510294c5ff167ecce09307c0e7754b9810023f91ab4a13c283ded1d)), PaymentPubKeyHash(Ed25519PubKeyHash(07843ba0ac368ac6fa41d8a68df466e6ce43290a792f43c925834220))], datums: [(DatumHash(1dd2ddd0f1687da13c0471227100821e5caafea2a6c0bd1836031a71d959296f), Datum(List([Integer(12111198339882327665), Bytes([148, 36, 223, 226, 122, 56, 252, 144, 89, 156, 32, 217, 100, 206, 105, 13, 220, 245, 56, 220, 245, 97, 79, 5, 11, 193, 163, 60, 49, 107, 143, 205, 45, 119, 143, 111, 0, 52, 158, 154, 35, 166, 69, 162, 159, 87, 136, 252, 138, 16, 197]), Integer(14917055000583713380), Bytes([250, 84, 182, 96, 4, 26, 241, 41, 166, 168, 99, 85, 41, 235, 69, 187, 56, 88, 226, 193, 14, 75, 123, 98, 232, 13, 157, 32, 177, 152, 85, 123, 59, 243, 111, 246, 108, 68, 235, 177, 226, 125, 225, 26, 197, 84, 217, 173, 246, 216, 173, 47, 89, 189, 140, 201, 145, 56, 94, 125, 200, 166, 205, 103, 149]), Bytes([28, 53, 48, 133, 148, 22, 66, 28, 53, 97, 115, 177])]))), (DatumHash(ac4bb31a4b8c0e5dcb712f54b54e403407223cd43f07ec9714d079ae10136e67), Datum(List([Bytes([26, 174, 162, 173, 112, 10, 99, 29, 35, 19, 111, 56, 63, 186, 224, 219, 148, 130, 223, 192, 49, 243, 125, 69, 173, 244, 191, 205, 226, 116, 205, 167, 227, 248, 232, 175, 27, 26, 90, 105, 140, 133, 134, 28, 145, 71, 212, 33, 187, 111, 89, 108, 130, 174, 210, 57, 117, 154, 220, 41, 211, 115, 13, 145, 148, 221]), Integer(10600455703549979744), Bytes([48, 253, 65, 239, 169, 140, 189, 124, 221, 144]), Bytes([122, 155, 53, 41, 41, 192, 134, 181, 116, 240, 45, 233, 57, 218, 36, 241, 20, 139, 199, 77, 235, 23, 233, 152, 217, 187, 184, 240, 64, 231, 25, 250, 160, 21, 228, 126, 204, 131, 219, 58, 41, 185, 223, 80, 221, 176, 79, 161, 85, 199, 223, 80, 194, 18, 180, 222, 49, 41, 202, 222, 137, 255, 29, 22, 213, 10, 144, 58, 238, 42, 6, 35, 243, 58, 15, 217, 40, 111, 25, 2, 25, 212, 229, 253, 136, 26, 133]), Integer(9156334723734449835)]))), (DatumHash(10d026a0084cf4a9945756217eaa5d6ff2451e56467e6c5cd42122f11f628b24), Datum(Constr(1096592962, [Integer(7149187219739976565), Bytes([244, 46, 11, 183, 246, 67, 232, 48, 14, 111, 216, 61, 118, 10, 48, 192, 253, 92, 61, 142, 111, 168, 197, 243, 114, 219, 132, 77, 186, 116, 95, 182, 67, 6, 152, 233, 53, 228, 57, 252, 22, 243, 240, 95, 48, 129, 49, 92, 42, 218, 9, 254, 135, 99, 92, 245, 250, 24, 66, 204, 229, 188, 203, 128, 251, 48, 125, 182, 72]), Map([(Integer(-14934554458418146212), Integer(-8733990149434153712)), (Bytes([157, 49, 60, 178, 244, 196, 156, 140, 229, 102, 124, 77, 45, 73, 113, 181, 20, 32, 240, 195, 67, 122, 70, 157, 85, 189, 198, 104, 227, 153, 108, 116, 243, 239, 13, 21, 141, 175, 93, 15, 145, 104, 60, 190, 223, 107, 49, 78, 85, 161, 59, 133, 31, 163, 136, 68, 172, 105, 155, 248, 15, 46, 121, 150, 56, 53, 216, 85, 226, 230, 68, 8, 144, 93, 67, 132, 57, 30, 123, 165, 83, 105, 12, 42, 157, 139, 220, 146, 70, 9, 114, 199, 169, 84, 160, 175, 176, 177]), Bytes([212, 160, 118, 135, 239, 173, 227, 137, 220, 211, 1, 137, 239, 171, 193, 85, 157, 221, 47, 64, 78, 148, 111, 79, 202, 215, 31, 55, 99, 113, 99, 33, 80, 188, 17, 229, 90, 58, 49, 78, 70, 152, 129, 34, 74, 122, 108, 44, 43, 148, 116, 194, 164, 205, 177, 138, 49, 227, 121, 50, 76, 97, 251, 6, 190, 209, 228, 81, 151, 157, 151, 186, 114, 42, 138, 59, 17, 100, 15, 231, 231, 236, 40])), (Integer(2664178424296852335), Integer(-6867474426338311931)), (Integer(-1806391647205798784), Bytes([244, 53, 57, 234, 143, 202, 109, 129, 44, 201, 203, 12, 149, 133, 165, 145, 226, 111, 34, 114, 123, 80, 137, 14, 222, 219])), (Integer(256972643692214470), Bytes([192, 141, 215, 60, 238, 113, 69, 5, 164, 130, 54, 109, 144, 128, 95]))]), Bytes([59, 154, 183, 176, 156, 136, 223, 146, 60, 72, 113, 242, 46, 117, 33, 119, 142, 142, 84, 82, 222, 26, 148, 174, 241, 32, 226, 186, 212, 118, 88, 182, 17, 227, 241, 15, 57, 187, 211, 236, 129, 190, 84, 150, 110, 40, 44, 147, 190, 148, 159, 89, 4, 115, 51, 75, 139, 182, 84, 133, 207, 120, 115, 228, 93, 37, 233, 105, 214, 95, 222, 46, 230, 49, 15, 87, 227, 237, 39, 80, 86, 48, 194, 63, 174, 168, 31, 26, 86, 0, 164]), Bytes([21, 128, 222, 61, 54, 46, 143, 58, 29, 162, 173, 205, 8, 93, 130, 28, 235, 165, 198, 155, 110, 55, 178, 168, 73, 221, 254, 89, 22, 202, 215, 217, 150, 20, 33, 221, 81, 203, 118, 156, 127, 214, 131, 22, 249, 99, 25, 251, 36, 75, 178, 190, 224, 124, 42, 52, 203, 128, 143, 114, 226, 183, 124, 199, 20, 200, 170, 194, 34, 236, 242, 129, 144, 176, 10, 150, 160, 228, 8, 42, 111, 44, 231, 234, 58, 32, 91, 44, 24, 71, 168, 60, 91, 93, 222, 241, 58, 192])]))), (DatumHash(5a9e575b9c15ed46c23d13d6dca4332e65173baaed23a0a85c089605454e21ec), Datum(Constr(2595342282, [Integer(3451760200702215501), Integer(4010655019245624044), Integer(-8093943009169867001), List([Bytes([193, 156, 95, 88, 91, 123, 132, 115, 55, 37, 203, 156, 24, 192, 167, 27, 135, 198, 243, 62, 76, 106, 186, 69, 71, 165, 93, 10, 114, 226, 203, 138, 84, 132, 238, 230, 3, 253, 200, 148, 45, 209, 211, 174, 173, 159, 35, 89, 13, 41, 247, 107, 96, 106, 96, 145, 94, 249, 77, 37, 173, 207, 74, 182]), Integer(-16665941241912134423), Bytes([20, 84, 186, 180, 237, 24]), Bytes([103, 149, 173, 37, 34, 114, 167, 61, 2, 216, 158, 169, 89, 50, 186, 106, 24, 166, 17, 67, 58, 10, 94, 127, 158, 87, 232, 65, 73, 31, 74, 194, 21, 100]), Integer(5453360218659488194)]), Bytes([2, 117, 98, 171, 152, 219, 55, 178, 129, 208, 146, 96, 237, 7, 220, 3, 253, 59, 7, 79, 213, 97, 5, 93, 163, 33, 195])]))), (DatumHash(2f9de4fc167f0b49183bc40817fc15942ab2f597897940cf768ef87c93fa0544), Datum(Integer(11619849138673604607)))], id: TransactionHash(dcd169344bc415da546970cf271abd433f7a03753088565f726230b5c9f40c67) }, purpose: Minting(Ada) } -cc 4ea6dee47095eed7adb6b2f1b4469e3ca031194fcbf8f58cb6c857342741fa9f # shrinks to val = TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(0000000000000000000000000000000000000000000000000000000000000000), index: 0 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(00000000000000000000000000000000000000000000000000000000)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(000000000000000000000000000000000000000000019f5c475c78db))): {TokenName(1f4f6c406310702632f4c3fa47392446d1b98889c00f9aa1626a94b980159df0): 298478092, TokenName(4c24672d372a413cdf59d512547e7231f0ef38e178b7018cb52a5ed6e9fdf4d4): 3492788874, TokenName(52cea5842a7d2e038ac4f72bda0bd3c6bbbf089aee1cd4f11ef1cd3190b12f71): 964251169, TokenName(a40750b39fe5116fb949a2cd52c88eb9357a3ec26036c260a69bceed6b3887a5): 2159064232, TokenName(ed869353d807ec5cc5ecd4d2aab993f4b0499fe03f8d34737974dff784818f32): 1725260373}, NativeToken(MintingPolicyHash(ScriptHash(325e8084cbbe91a0a80e30d8cc27cfc349085d2001111a51514d4d0d))): {TokenName(15b5a50db50d46d5ec5514cde300e35009062f30992d3931d3c1667e96584d70): 1865081206, TokenName(4ab14e32ac37481caa92dd11a64bffd7f7b1aeb57d9a5d2b96d27996eac65ab1): 2349547655, TokenName(9a64b19570409bd4fccacc8a554282769978875bdce4d923b1ab75d10f1296bf): 1851207128, TokenName(afb8270e291d11257fa7652e55830f0ccb1f7acc1f4f232c614a87333535d29c): 4017700958, TokenName(bfc27034cd3673af9f4dc828ee1aefd4ad7df8a57adee4a867c6ff7525f48bdc): 854588756}, NativeToken(MintingPolicyHash(ScriptHash(8cfd71a4b893f1b0ba1a663cdeea73c0ff9a116fec5bfeffad7f81c5))): {TokenName(17afadb47268d366e5422aa9fef69dc008099528e1b09b6c486ec432d7216419): 674029915, TokenName(1e2a9944808d8babb9c9e1baf683ac3ba14f161ec62431578a54abd2330f77f5): 1791958212, TokenName(9be89f1dcf4ca802510a01aecc9691008477ff1f9c7872ec339ef518ce215222): 995249238, TokenName(9d4c66b90efc1b0a9705a873394225bfec7a4c9897897f43476e7435a98ddd7e): 873638795, TokenName(f859d8be597503ec124919ce41f49f86452a6ae4045e005fb550c41cf46a7894): 664491160}, NativeToken(MintingPolicyHash(ScriptHash(aaf82f6194c9a2c9c22a2d84a6018f3db15baf1eef34ac9112df0f27))): {TokenName(42bb0f091664d20924f1233561b35a78888dbad58e3b730366c3f8d2afbabf7a): 2130410640, TokenName(a038c562498b1039ae48c86f1e0d2caf745cf52ed10765c5ad50c18766fd1e8d): 2441312155, TokenName(b603aa5b76770eaa33b7aff1e2f08ff7766a167442ea3cfe32433d2e5d7c1898): 1235255672, TokenName(c4e50f0caf814feac611970baf05e6a95ef681a4d3e18b5241f86a47e0e16c80): 3111581855, TokenName(d212a2247adf4ed99ab7a76e151c01392164857b4072fc429cbba28d10d9f5cf): 696705209}, NativeToken(MintingPolicyHash(ScriptHash(e43d40d173224446ee47f3996602239ba997eebbc89b90c5f7aff85e))): {TokenName(08f7a3d6aa99731f8f1c29408f3545f34acd59be5dd3f236f54d5a944a1b81f5): 225263698, TokenName(5f9ce2dcd7818cf2083128f9e54f98f8f60828e40bbcf3ab1f0f9522f7c788be): 733392177, TokenName(b2de3f0aa352b169490ebeb0633e4f7b2a0ad5d4977f31cbc714fcdd8eb58ca3): 2712434547, TokenName(cd30493be7306304470842dac2612255d72fed4d2d9f50e465c2a87e065df13e): 3399809590, TokenName(fdae4677b30e10039e118fd2f05ba8e9a1fe96b76a96bf568a3d31993672507b): 1218974563}}), datum: InlineDatum(Datum(Bytes([144, 218, 0, 205, 49, 206, 112, 203, 48, 141, 239, 85, 127, 139, 47, 136, 195, 94, 212, 234, 63, 151, 197, 4, 120, 67, 14, 234, 165, 232, 150, 48, 144, 82, 55, 157, 8, 74, 76, 4, 173, 68, 162, 249, 241, 69, 132, 219, 251, 173, 217, 213, 57, 186, 93, 252, 23, 255, 92, 206, 182]))), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(a2df58c0f9342ae1a01de26bb37d3fa10a8a8de1f68792f93488be3de867bb13), index: 2288900289 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(1e5801da8ba2c61f4aad552ba2666db78e014c5a0516e114e2485e49)), staking_credential: None }, value: Value({Ada: {TokenName(): 9077772753944363893}, NativeToken(MintingPolicyHash(ScriptHash(17c19a9d3c9fd2721fcd21d355cf215efc1677f4f51233868240d838))): {TokenName(487d6467f40f902700815c1f753c7472d255968fffb9700e6a88ece58c2e3e5c): 2661724228, TokenName(6772362ef6d7f7e3d48932c682d1623232c7a37c0780627bc762d544a37301d7): 432390567, TokenName(7c23d2fb743212b3aea606e7105c09bdeb8f13c41796acee993d6621ee390b22): 1475735511, TokenName(9b999b9a1d36eb0e007ba06d96ae00843d7429374861d8a0016c0ace862d54f0): 3837974677, TokenName(d2506f4269053153d864e0af42bafded34403ae0c8cee18fafc42b3bacb7df82): 3627314589}, NativeToken(MintingPolicyHash(ScriptHash(352d5f0781220fa28efa8bc69f074289772b3f7c9fd491ac771686e3))): {TokenName(0403dd3da072efb42c40980e52efc6d5ffd0d5e7de0a5184a9933e5de0804359): 2443674359, TokenName(32ec0495fb8205d2449ee8e44f17f514478d4556b7510d569491c7cfe3bd3296): 326409729, TokenName(53ff5a21aa4bb3655d02c626878d893c9673665582de1cc894d5560bffec7c50): 2758731830, TokenName(66653c46782300fe860dea0a5ae9f19d72016d2f1a789a91ae26aa667f8b02e1): 2490347972, TokenName(ce898f46d5737005a5525cdf56eb77e1f90ee1e9d32d7d49e69d49d9ce855866): 1911570543}, NativeToken(MintingPolicyHash(ScriptHash(669953cc87a77b91a385c5ac8d70bac264bacc90661ddc6a6d97b4fa))): {TokenName(56cc0e046d8b300ef14612df0ec5f196fe2c0a245c6379992e275867106a42d6): 2967458774, TokenName(7eb354e2cac70aa2076485e569ef5b8eb2cfdff1b5d478b575a9be90bdab044a): 4252955295, TokenName(a1738371cf5dc8a2781d875c18ddd7b4240f186396cd5e3988980c0eb021332f): 3304613221, TokenName(c0d6e3f303bf1a4ff710b2c600baa688908b8c3cdf172adfa86401c0d2023660): 1865242021, TokenName(df281eb7bb8a6a8421304cefb45d5ccbd250336c0eb4fb4c9c01c73537acc803): 3531359257}, NativeToken(MintingPolicyHash(ScriptHash(c2a3d01e2c668d57015ac8c793f559bc2335dbd93b216d9a39b097db))): {TokenName(0fbf10dce451b0ef5938dd50612b00ddfd7568a3dc0832675569581fa8d788e7): 745911105, TokenName(219eef88f2b12ac6e2395186f96db803914e249a79f0fc9270571edb29cf90dc): 354711841, TokenName(5bd274aab4e5113eeb5ff08d12f5c2c94e99c6b505f04b3bb9cefc62868116bf): 3519212836, TokenName(b231222b345e2003f6ce5edb59b79d4ce9aa5083f2b1124710987b6142d61157): 866543946, TokenName(e35aa0de564f94f459b3600570bb3493f61201d36233570ab8c57e6a7c97cd7d): 952891787}, NativeToken(MintingPolicyHash(ScriptHash(e4d28ba4b28ae7428db79ba76bfde03480d979cba1fbecee20e01d71))): {TokenName(13348b10567872245a3ae7378351aca35d05cbbedabce6e1274d7d9e2b2394bb): 95487821, TokenName(215634911664a4316b7f02e81b6d26100751fe9b93b4542e837675a1a64390f0): 945209453, TokenName(6a5879902fd5eb999ec210f1ba9cf3924bec25f8f5afc0573c205f4222590171): 2628764579, TokenName(7913873afa53bab60882c4017b0e69f3de328079266b74ada2ba3747357c6f51): 1087784257, TokenName(8338e35b27f5757dec720221bbacfb7f16255b0451f8db02235fb5c6e2e8ab2f): 2074210583}}), datum: DatumHash(DatumHash(d45897f55f130908190639ecec271ac407ca36c981f40d5a644be632d773d0e6)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(20b81a65dff4205bbbeb1353bb9abce3d3ac873db8c5413da1eea8be82384e28), index: 1401515414 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(bf408dd6d4d82476144322cfca102a11207501d6a7fc0e0276abbf10)), staking_credential: None }, value: Value({Ada: {TokenName(): 17226239645628683221}, NativeToken(MintingPolicyHash(ScriptHash(05737918037b436a5e19b9a3b976846d9b884cf075fdfbe8ab2837da))): {TokenName(30dbbca2b96c05786840bc34d2c9f8a0d93ee3567866902e0c3ba9c63a715390): 1922299337, TokenName(68f052e86dd26d7657eb2e660f327beb8ba06824980091a02bf0ac4ebcdc416a): 4241694833, TokenName(7d486476de91c59f471c958f72946b3d2304e91a8ed6992de7f656e0c7ab7ba3): 1286087871, TokenName(b634ffabebe78cb006a382dd4a1603477668f221fdbdcb4fc7cb5890d3e00d12): 2722243297, TokenName(fa571a84a604363ef386b6667e638c811ceec8fde4a339e78f08a441074f5b05): 2572314377}, NativeToken(MintingPolicyHash(ScriptHash(089b760914e173437485ed05492680dc23e4692607c794ce784aa16c))): {TokenName(4b50c28899cd46744537a5004204c9d9d728f5f06b5d0a58d85a4c9b78093fed): 3055907814, TokenName(90c09083d35712db73fadfc7e3aae9e32f031930a0ac43a7d87bdabe8ad6994f): 2891085892, TokenName(a67f5a95dd298f03fa824da698785d4ee1aa9cd58f8a584a734ab7ce3f6d8049): 3604978156, TokenName(d4ba150d183a99c3f7d557d5c318ea022e03281b9c92fc58dd297c18ea687f94): 2119709419, TokenName(f801b35606a5819c8b364944bd7a29b6ef9ea121c2d2e5714129f9480d00637e): 3050410399}, NativeToken(MintingPolicyHash(ScriptHash(2e8cd2f85e70af3d9b60b3ca1e8901c9504b9692a574108f381cee04))): {TokenName(13158a46be1784110e381c1c922f81e9b7eeea899d51365f487fc139356e185f): 4105100998, TokenName(21c14848b68896df4f244589a8b97c96ecfc61f03fb340b80cf69547fd5dc94f): 2297652702, TokenName(33390b5ae6a08c25671b9712d86f57e0c5ec0a244531cf1901ac535bdd731d87): 1005754467, TokenName(e13acac311416fdd3c94b89f2cfe33d9216c4a0a1a92337438e8897124e7eacf): 3474217748, TokenName(fac1b7beb919570c8f02474c6454a1f6503a09a852c7632ebca8e89ed74728a7): 773564202}, NativeToken(MintingPolicyHash(ScriptHash(6e1ffe77b1ef21cc672c8571e46c7d0455103948e0ba13389138655a))): {TokenName(059c757801e8ece193ed78e8d4b3d10cd0b9e5165a0f563d3d60a3813af9e336): 2787529088, TokenName(6452c2fee5c3fcbc09ec4068beaf194979c1a63308561e3b2f79cc21803b618a): 1795408408, TokenName(71e6f03ad83cbebdae82f68e3a87aa2fbbad90e1e992ca49e0b8e8ed23180786): 1601844901, TokenName(e70008d3615b2d226bc617d9209ecf164ad856a10d6bfafbc3b3011f720e5930): 968495623, TokenName(f9f96d99599e0efdf46248c2a0e06f454dd5361174881f1394fdbf17ca8d5e1d): 3306415807}, NativeToken(MintingPolicyHash(ScriptHash(fbd3ebb4c1d925958b48e029b2ddbc42587ebb8a74957f779fc898b2))): {TokenName(13d4d39b83dc7ceef2756422f6b41a01176fcc63c767f9bc2f9cbd112917f75d): 2582056088, TokenName(6524fff49e693803978743da09b95209dd4158828db8e2277ca5cffc29cc274a): 2164982155, TokenName(8bab4483e62a24e056d6972f887d4203ded62d3fe678666df1706512e2251d9b): 1620361746, TokenName(9646bf625ca0578323664e482040061c4754fe26bb2499030a886d1b9f2ad3ea): 533109910, TokenName(9d5b726eb1e1b0642bd54d22f25b82eadf5675fdce754f89704112ae31b4f0a4): 4075031947}}), datum: DatumHash(DatumHash(f7178eff489ef41dbb22ed848e1bc5d9e6293bb548979d5e68a447fb1f1ed8c8)), reference_script: Some(ScriptHash(fb289ea6747fcdca3e7e049bfa455e8faff05017a33cfc2b0543f4e2)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(559d234f19bc9fd6b3c1601b5fab8dffe0c8763abb0e988a76bf5b862b003968), index: 4009668832 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(2e2f1e1cfe2c0bb6515d6d7695b0b7fed5c4eee6290d8110566081e8)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2666152860), transaction_index: TransactionIndex(4264677920), certificate_index: CertificateIndex(3656972724) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(28b906c2469c30a32687e54890d81e4fa305e4dae5a1c6aa904f4481))): {TokenName(588fbbe44d8b4162967e9a644987aa83c235fdc507a8d55e583cd42385b986a9): 381441679, TokenName(737b9a4468ce66070b24dc1ee40675f9aa7b13e002d3e55b30961adc440f9ff2): 3543701530, TokenName(79c76b9c30595cdad3fb62b0e16fe9702433fd0c19992f22a4f087784ec0ba83): 2387693680, TokenName(953f9d0bc5b4777387c0d963e51027cd662b7b6e9157e71e0dbb2517fa6f26af): 1049034266, TokenName(d1911b3f8d1cdbd93977e58d2a20498108d9d6aa537c86d7fb57856f01e42595): 285686768}, NativeToken(MintingPolicyHash(ScriptHash(521075444c4e02a8adeb39630f33204f4aa57a08419c5061a4d7b83c))): {TokenName(43a27d5e26c83ba64631942c4c9a283095cf87742799dc8f89bffd4ae2869253): 3945412173, TokenName(7da8074067919d62193c1523a67853a08666e3841e33ccc80c92168bd8f03b3f): 1773466242, TokenName(8c2304f2ae7992e7028d8c365f3b297914b1d204761c949c07fb6211b4522fae): 2147886411, TokenName(c8ed9873dbfcda2cb149fac2ac367120aa8350c0b9ffed2c7dcaccea65b9230c): 1652301103, TokenName(e1c58e70ae1f74e3dc53068609a983afb2ba2803985e081019cb4007c5a4a42f): 1647130755}, NativeToken(MintingPolicyHash(ScriptHash(9c2d2c5cbded3c9a7376bbe56776f7e72f3fc4e6b535c92f2cf3156c))): {TokenName(5230abbf696d75f31f70900a2fa9110c6ffaaa6810cc83a06b15d1bb3459771a): 1293869912, TokenName(6fdb5bf139e643629c61e44a7376574d55d06b9578ba2e7b963a4d4ebfb0dbd6): 374768536, TokenName(e23691b12dd6f37371fc685cdb07f887bb64c1011f5112ab906e60feeb342523): 3231861304, TokenName(e6ee99a53df32a5b763c19f5b6554edf9280d6003df607da0798cee2fabfef4f): 4159172298, TokenName(eaae34a4b19c419158b9ff98399f76b346555ae862a1d14e3ec2ab4ee1b9087e): 203744017}, NativeToken(MintingPolicyHash(ScriptHash(bd61cbff190876a881619f86d73a5d55264c86b56d02cc948b14bdc5))): {TokenName(3bb69975e72dbb1db6d4b9472c155db4e688cd9dbd816db71cf52c3efa13e0da): 3233720600, TokenName(8724e429a0c490b4c1c761904c0a4649503ba5162f23e3e2900c9263ef8ee348): 907798956, TokenName(ae809a3c48ce61182537914dee7d4ebc3044ef99a9bd889fda1d02a58a2c5412): 3122440309, TokenName(b609ca4c5bcd5c0c9b3aabd65d005a5bbfc1843481dfe549ade9e05ecc931f06): 2322382137, TokenName(f5740705a56e988c151cc398a18ed5837b1b25fe5f0cb49fd539c8d9fb9b958a): 1243817373}, NativeToken(MintingPolicyHash(ScriptHash(d420e0e5f8d8047a710a8f62654f8494c449af745732d6981862a710))): {TokenName(58cc66455a862097a010123985fef3c078ffa10680b0513a63d3712a078db254): 2202239110, TokenName(5e6cb177c2b701c3fa733e533f011dde3000e33a9a13a7ce2880a00e8fedb69e): 3534401538, TokenName(73d08fafff2bb03a4c297fd150437195c24d03328fa0656720ff4d5f078305fe): 3153435883, TokenName(9b58c4e16fbf0b715fc7cfbadbd7bf42329bf7ec6eb5165b7f9d46eb4cfe5e78): 2162236305, TokenName(daadf610c4b72759caf3cc74a68ccb4efd19c8264e0c95d162372669edab8b70): 779747504}}), datum: DatumHash(DatumHash(49d222c0ac35c9b277f1fb5dc57261e12bfd237aecfdb7997e89bc728c0e0db1)), reference_script: Some(ScriptHash(7195783a1c80a32e9bedc6f4c580272033dfc6a564e1b2f1ec439af2)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(5bf01807de9c6759a3040495c46900d6f1e1004f3f4f545929077f875853ddd8), index: 3510854106 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(3397e121372202825c4e91627e122623215a0019b5ad766d5bd3b259))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1e6319017bc6d35870dfbfdeeef73fd9ffb82a10471f02ecda7f30bf))): {TokenName(07ffde46fbb00dcba2284f68b2d54db29792c298a5323da8cd721077db38fcd1): 3007032970, TokenName(8bd025268c55fe46310811f006e3cf45e411bec5a9a312c9d0a1effffd359737): 573362926, TokenName(d4f6b2b4a9b8149905f5df2506054274e2bbcd7e6b337ef47b7e7eae4c23b2be): 1877352224, TokenName(d7a434c0b2a267afdaef4186da1b5163b246cce62c5810d00e52639cee538dce): 3875247984, TokenName(ef0efcd032b2ba178cfe8e6d1ce3488a7342725cb822cd2bf40755d807cf13bb): 2395546946}, NativeToken(MintingPolicyHash(ScriptHash(6096e4d59492507b837e304772ec84dfde49a2257cffc8fb1f9e1ab7))): {TokenName(49ff3246d4e6cd47f30c2574385b525c9c25dbec7a11845406060a37f6ff71d3): 3001461710, TokenName(58b6fcda5fd1478f810fdb91e93d590d563eb52836f0bda948383c82096f1838): 3909115795, TokenName(9f8c2968e3335942e64b8834377acd2e39ff74c49c7398deffa0d60d47b30a4b): 2820312981, TokenName(bf1e3ebc6ca0e89dad0c502bae61e0b80641060d423ccb5b42b16d6e6d6d32b0): 441029893, TokenName(d397907889f6e56e44d1e1db064e617c154c66bdce2ca6122a9b93f5dfe08044): 4227151298}, NativeToken(MintingPolicyHash(ScriptHash(91fc120a6bc95ed35e6d1c3de97437b88c9c0df7a42c3c6633609749))): {TokenName(8a2591f2823d48dfb34b43cd88ec0156ded5d20073cf600a83fbe7d77f90cce7): 906054177, TokenName(b74c12412fbdf969b8e25dcde612cdb30438532a9910300684ffd76c40a8ee28): 654832590, TokenName(d55b8371ced3d49abcd773d6c544eae044629b7f13c8e0649b8fadb243edefb0): 4096721826, TokenName(eb1b0a89d22d1ecfbded6adeecb7288c11b6d7f9f2fdaa9c9aeac2ae9ee4c961): 1432617745, TokenName(fa41f7f80953bd2d6a8f8b48d6de89167ec41048207bca1094fc9ec62badf84c): 3792596042}, NativeToken(MintingPolicyHash(ScriptHash(ca11f8a4aa299ed89410ca59f46056bfba173c541d1b17cee8b3ada8))): {TokenName(34a9842c88047e70dd7ba5f429fae7e4548afdb2c33f30b917b1b7f540460e05): 2855078087, TokenName(70f10b73e86031c44e9d7879f6fde7705357ad25f9d1dfed815bf3c1c57aeaaa): 3190021105, TokenName(8363d689f91d0c6a3ea19860e1f612922cc252b41ebdc58439e78d3f152a6b73): 630956407, TokenName(c2e8b562eb4372ed2e582efa03e416c6a0c072119e15a12bdadb43e87b745564): 1048663251, TokenName(d827c3f71c3f1b0e280af73253cff6ea8bd33f90beabcd15ec326ea8c8c46767): 2217654504}, NativeToken(MintingPolicyHash(ScriptHash(f326f11b693529a85b8c99d504fea277cfd8efd184c21542d61d4cf1))): {TokenName(1e22c06a65b4f4ff321ceea30a50b355c58eb1c2ee7c53f9b8809401c0ebb9fc): 248800710, TokenName(3cc271e8515140ea3fa8a9405a4bf8181b3e5d449856d9d229b9f82fc794e087): 2126954849, TokenName(aa47821195e4b19b9e7a85953c5c117d95207058bdd214c84db24883f78f69a3): 4016464483, TokenName(d0837ad600e0a990eb292b9b5987c8be5b05ed8a8a8234d9d8fc26f91512c420): 4214225111, TokenName(f48663127098c9ce94abbddb78b845cf38055f8e25df2b0f9bece6f6f1589b38): 1601232670}}), datum: DatumHash(DatumHash(04975756d0faf9b1b030c54f60108983d5d33b302e45f940736bc7f96f083087)), reference_script: None } }], reference_inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(df415a517550c6447e0151075818b245d038c64041b32b0e40ade78aa6ae0a45), index: 1616464634 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(5a739f3de0668e36ba44a52f4d49868efcbefe4083311254ac405b08))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(1642185967), transaction_index: TransactionIndex(1760037649), certificate_index: CertificateIndex(663801260) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1f523e96ccd098cd6df5a5564c7bbab3a15dce3b6b6fac5fb174a476))): {TokenName(24ade8d92c0b61f74867695068f41422fbfe4f2ad4af58a029152d31b54e4f0e): 73890963, TokenName(590d57b4d32c0f3ff17a0245ebe29d546081bb18a2540d4c1ca62d9337e9e82d): 432334435, TokenName(83fefc093db994f9f94e58d3b4493da6514e63f4a26d57205d7c9ae9e9999726): 520557240, TokenName(a390bf268fdd95cd2d7a3d4d5a36fefc44746363c0decf8fea06dc1fb810ba07): 2017639615, TokenName(ab2a2d6409074e673ce5d02136d684126ae5081fd056026c762ae682ba6566d3): 3371327882}, NativeToken(MintingPolicyHash(ScriptHash(3ff91680463d13e8658e6622e8cfcbb874a2c1c06b1d3d77a1f01cd7))): {TokenName(341dd49ce78f0d05e07bf7836a9401268df81394d5fb1e63dca1d1b7c624e2a1): 1636164768, TokenName(3ae27a73f159587bdc5e7a337dd8fc8fdbeffd3a83cebabc55dcaf2608e0edfc): 2434315557, TokenName(41b20167c545b9197f967307e9d7d6ce58a173ed9ff283054a3db3c815053428): 1875763754, TokenName(49bd43ec952138899db4dcfbf784ea824037506fef27cd4c2e90b78959b7f365): 3707640368, TokenName(58214c3b2e9efd3ff5b082ba446e879c07807df1c3ee7bbad4d865aa223fec3b): 1984329010}, NativeToken(MintingPolicyHash(ScriptHash(663bfe989ebc5a2c47a3d40882de274a7ad1b999a30c470996e15bea))): {TokenName(25b9e20732e2e4097b00f2b1c708be697d2c9310721413a5452591c104f9804f): 2953456755, TokenName(488ba5b3c0807faaa44f59175a45aad0f7418103355116ceb853c0c72663a78c): 1465740540, TokenName(ec0fd3cf042a8075bb044a640d5ceb1f9916600fc4a26ab577dcaf9388a2aa38): 1111893591, TokenName(f34082bba61c76b0d69b585f8bcbb47cf68b4c7ef6ebbc91b8cc7688b1c02dd9): 895735227, TokenName(fc1c46beecbed4ce405834a512e57e6525431abd9d34e1aab842503a10560df8): 1571903970}, NativeToken(MintingPolicyHash(ScriptHash(8272c6bf89dec17e0c7fa6f89112b83b981546fa5ecd21ed84b3dca8))): {TokenName(1cebb482ef4947b994c00bafdaa4aa940f63c3a9ec059d8667da977fd7376e5f): 3166366252, TokenName(937d23126ad90929c9ec06ad19648fbf8b7dd6ebe2a1fcb2fe00933ce9c476c5): 626618109, TokenName(98eaf07a98270c03afc15f8d0ccc99015c3b8b4c7436732a5834d209cb09b09d): 4274731156, TokenName(da08ead990006575b9a4bc9dafb61a54e3be96284c6b6e5aae55bdf642cd5144): 2040089960, TokenName(f9257d246196b66d06273f31f2e2ff44295b3d4500bd74d93f8c111cbaa1166c): 2184766469}, NativeToken(MintingPolicyHash(ScriptHash(a720ea7e0809c3ac5c713b5087ff3e644933054e60daacdf05ec3664))): {TokenName(4d9c8a991d927f5a3a48e23c6901e33ef40517d951b6f85a13e62738c53cdc88): 728993400, TokenName(6a2e66d1bf469d3700d9cc659789f48d7871af58f20e23d17e7bc4c5993ebbd7): 1636587822, TokenName(923f2410e1a26de90deb9321d6e8131513bd95997317af85c297db0f4ee98c59): 3168320013, TokenName(f4e4dae63403db9b5422f649344e93765b5939fecfebcf865ab43ad189012fd9): 1619540935, TokenName(feba086c2a67091b06654cf2581e0958433bb98a7684bdc45c4382ab0d2287b5): 1112864610}}), datum: DatumHash(DatumHash(aa381003c42ab45f09cde6aa098ba1d100c1102f1a95c03700ce661edc9d2792)), reference_script: Some(ScriptHash(9deca16118132eb6b89f3e97efed1c0017f116c80af86bc0d944b5ee)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(c79f9376867c429a8d6307bf1ba38a78b92ca5099b64d353f2bd5f13d21e47f3), index: 1046223877 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(5ebc06922a39ad8a6d8ddd73e2741e2d5213a188fb27a71d50e4e2bb))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(0b63d507e5a04c9716e3858d22a325a72a5eeee0a6f68a1484a43b2e)))) }, value: Value({Ada: {TokenName(): 1437288783675715623}, NativeToken(MintingPolicyHash(ScriptHash(0074a43a2693b26cffc8757369540be4be08d0e5b83eaf9161269a8e))): {TokenName(03a926192b9f9f59d0fc810a03723010edf357233ac3969bab8cc3266e439a26): 1131830174, TokenName(1b5f59283e42113f6ffd272dca36695f730d9bd0d4bfa37ed38e59d74e87e702): 1440155443, TokenName(2b9455fe459033a04b7b1c1b4838d4bee12154b74ff66b87bfbe89238908d9ab): 4054564423, TokenName(3de84e7135ca95aecc0d000c738094ce096fe02f1b5218e283b69b1c55457463): 737078855, TokenName(7569a3d99a6e907ff8c5656f2a1c6d2e712fadc5cef23a00124dd3e1727126a5): 564960642}, NativeToken(MintingPolicyHash(ScriptHash(a1bd784d3e3023605fb9c95fa2ad4cb30fb915c884551f219c8f33be))): {TokenName(06747581c17ec06e4411dd9ccd2e22816df772f1ca8c97244901d3b43713bc32): 3692834816, TokenName(a246734c268a8dd05ae3a670ad3c6ba506a3957e57c403ca70aa97d033f1e617): 784084324, TokenName(a6e0cb8449baa701071e0f177e348d5ea2044cfc71bd08386c013a4e4c7d0daa): 604805320, TokenName(e799900d7136ec8aea19eeec9ad8a32aa836004cbc95518cb079498cbba1edab): 278927102, TokenName(e89402e1d2b5691a22eaaf2d65b6565aa4b6ffa4a48d2ea8ccbec2e092bb8272): 3634787523}, NativeToken(MintingPolicyHash(ScriptHash(b8e9a529c5cea23ebdaffd63012a782443b1e19aadd5c0b4248b0b47))): {TokenName(00c25213c4b035d4103ff424dc82318beaf1d5c1910f5b132bebb6f29bd16ee3): 594035392, TokenName(3f13e06840cecfc2d1a615b3193d0a3e41c5e9c2ca0cc706c02d15ccb0bd95e1): 3394473675, TokenName(591f635766d756c3295d3cea405f872d31365962f275fb0fd3fed619c796207e): 2482322837, TokenName(6925e28f1645454951027774f31eed7256784b14e51d2bcc14b6cfcb59eba06b): 1270601231, TokenName(dca0e1ba39e0cbf67c07f9ff559bc7bfda83576e2d8319f436e75a9e0d334437): 1732855562}, NativeToken(MintingPolicyHash(ScriptHash(b97d707f5fafb96cdaa3e2a19c39f1f12a8d0081c2e6fea3cceffefb))): {TokenName(173172bccb64ddab80accb733e3d96f10a8d062ecca6859a19644ab94bc6fac0): 3621726364, TokenName(17e742690edb942f790c0f97ca1948fe64d9f575c9d0ef4d423b1f3f0e2c4b8a): 2191440209, TokenName(220eb801bbc5a14fdc4553788f2a9e57197ad2f56afa2030ac36ef591b6d36e0): 1170382379, TokenName(b5570a8fd206cbee80a07e58733deeecde9b7222b8897102fbacc978fb0b3d7d): 3932551032, TokenName(cd897fee77c48f0fa95ee408e2037e2b8ab3bf4c44c5d41a7e9b157c9b17bc3d): 2794123672}, NativeToken(MintingPolicyHash(ScriptHash(f672e09b3595ee889e63e3b9b4023fb5467711b252222ced42783ab5))): {TokenName(1630a8bd2d937d0d2070f26440e057f0e12ceadaa1c34c0460d96b466a004729): 3163183386, TokenName(23a039a307d2e849cdcf47db0a685036424e5ff57730c424b8c45fbada65b3d9): 3199400815, TokenName(29169bc37d2e748eb3600d47ca6bd98eb14e3817d6b7d099d144b52f84c5c93a): 1882230065, TokenName(7ccb634032bbeb2e1c4312c1a1cca9a9bd685f5306f751178f4076a8f37469b7): 4271780163, TokenName(7d3501889609d089e4a1a4274a8854b210d7d9b28e398ed272ad0df770f467b8): 1943632457}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(574dc3fffdf7f3ed60aca80d1ca2a2205b5e3fa9e1a9667091d42dab240bcc43), index: 1737862752 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(15311b4673879ef3dff1bcda3f0af14f1b655cf8de19a8ac983975a0)), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(98b3e048de37f98c02a7fd31af92e9db6c20d781b0168c2822bb66c0)))) }, value: Value({Ada: {TokenName(): 16230381661492709578}, NativeToken(MintingPolicyHash(ScriptHash(0d1ceb7ca1121466f7ada249ca1c3e5fcce9d44021140a3ecf3e9cc8))): {TokenName(10fc501c063c1a74a2359a2172841ade6771462fe78d29095f7f0f3266968281): 2582985031, TokenName(3724a231d84bd925d7dabaaf5d94a15f151c2dd54ff9fe58ab199e7509c227aa): 3694507265, TokenName(39480acef125beed8909b29de204983105398b33f33358d86f98777c5451503f): 2205022978, TokenName(3f8c6652c58249e0c35a5da6546f80c5926f1f42b0285ea1d54999079df5f1c4): 3407071085, TokenName(e2b6e1f8e5b0e80c928bc651891b77e4ebe207db7e6c1f537c4bdc9a350bf4f2): 872356174}, NativeToken(MintingPolicyHash(ScriptHash(3c73b484f46bdf1d7bb96e1ae533d3e5aa1d16edd2863fb360fb7b55))): {TokenName(06d12763b7542590703fa42e2e43318df066acd7409fb22739d6515bb0a03d79): 1819498667, TokenName(16fde59d7533b1380be38121eea39be53709450cf2e726050d8c60e47ad62933): 806139923, TokenName(569253efe1ec413410968ef31e432def344eb3d2492a7db72fc3b73d21281755): 1878438217, TokenName(b1ca962fdce4f75ccba251d99f165a789ce31c6d09559a94974b33a03c3a88ae): 4007461623, TokenName(dbaada2cf21170b22e59b6ac3e7a5533d1bf48b34724aa92b62decd929c934f7): 2697836738}, NativeToken(MintingPolicyHash(ScriptHash(46d6ae712b079556715503b24eba3a475eaa94606f8d78feedf2c65f))): {TokenName(18b811a121897ba78680bc39eadbe33a18739aa183a434d59552ae7f24bc32de): 3777657427, TokenName(2326797398f3e07284b60b036c05f6590150cb1038190ca59f55377e206f5ace): 2877689602, TokenName(8362d78368776a9e80d66afa84462c2dbb6a5907d44729ab9279d4dfa723f6c2): 2145995569, TokenName(a9bbd487d4fcdbbe140d117b189d72a27a68c26edd9e8e5e54bf943f29692453): 1808718724, TokenName(cec5091ca8b1c71d5501f5fe589f285b175807b2bef03ad8ccdd457e7b08908d): 3272690649}, NativeToken(MintingPolicyHash(ScriptHash(e3338024c8a5ffb0c28de02741209d83447b3c0675e2eb6d70996a4a))): {TokenName(49ba7085f9ac95c4c599c4d52a861bc5426329867ff6021ab505e3b12ad48aed): 3370763027, TokenName(a764c5883ba2bf19caf1b1aa118a0f2cbca77b2e6bb8870fc2c17e5df8c57c59): 2806304134, TokenName(c43ac5b2c342c26147fc855afcdf90980b35c568dbcc9008372c046ff7de43e4): 1106846568, TokenName(fd898129fba868d557758e7e32ae34c8503d8c62e068a961c115ce212758f392): 339702258, TokenName(ffd9e142dad2df259756fcd01505238c02b9b13e3195c3ba5a8c82d196827c03): 2218489873}, NativeToken(MintingPolicyHash(ScriptHash(f0131469c07a63ea397e90bb085ef69d6cbe8edab961ad5ab1428238))): {TokenName(36412d5b62f159da7013a415d819aa24e04351e112cea03e3c6d150fa50f566f): 3116135450, TokenName(5e3d08814c6f9c2e1429277f69ec637133298007ba5e61c8073c7c4e5dced40e): 311137970, TokenName(7b725f052075c12b6a694ab63685621c6cd87db9cf3a7e4c676c9e4537722e84): 339725338, TokenName(d0063f34929204a161283b38bfe7b86ef20696150d9d0b2dcf5cfae7e57e97b3): 3418255052, TokenName(faa9585105f14e92d29cb2fba076ccc8825eb3a7554d99f1482024539f857023): 2693480752}}), datum: DatumHash(DatumHash(1eaf166dbb0bce4763cfeddc4ed3bd2ef481139d3c151016d768e7efb1f6c02f)), reference_script: Some(ScriptHash(729732baece33f3bc70839225a3b5c905e687e252a1f7012fea33263)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(a6ed2bb95a666a41b3c3fb8839b684effc7fa7bf6e9e54a7b33b46393fd65d66), index: 1928408220 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(4a1e2a6888b02a397b323e2533d0750f671bb4e79bcc85ebc4cdb531)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0fc8fc17b384722cd400d4c54cbd71d5e2a5ac29bb6cc09be8f2f755))): {TokenName(35938b0962341321406231d16c53e72c6bf689d8cc05ca674281ca11f26efb2d): 3055792083, TokenName(59378f9e0eb588818f85c71944354887f2dcee121f80fc5067ac767c42452775): 3070254985, TokenName(95b542ce3eb0392e33535cd223c096a958e4f3763284b1281f9c7e8815d87751): 449976769, TokenName(f1753a148eab554119b5a22104a5c6733122c84e856356e9ee61c8e91495d3e6): 2498916922, TokenName(fbfbcde34f443cabab43678abdbc28f846f39c38122ecce88b12dcbae1b59333): 1101837015}, NativeToken(MintingPolicyHash(ScriptHash(3edddd71eca5f8a70d09324867d7ead9f9d33233e1041810332d15f4))): {TokenName(1da1c3fa4ed1c921b34e069024199c079938272ebfdea23c6baf5b4b1fd613cc): 343871666, TokenName(3056be3c98d4c7bf3034ad5a94dfb0e9de83b7c53743a379e9fb763a92f3cb70): 1496672825, TokenName(566ac02682a92c4e51cbe0b585f70d930999a27bc060dc44bedfec1aeb969318): 2143451717, TokenName(84c4215a802391fa6e881b67ca81645235634c4436e328e2fe9e489c154a71ba): 582051554, TokenName(ab7df4886ecf1c201a5cc0f2c3e11732064c0383c12a45e8284bc6be35552ee9): 2477410850}, NativeToken(MintingPolicyHash(ScriptHash(50aad9b6b1457fb78ebe72a6d0c4c81aa39014a6ada137b03b959a4f))): {TokenName(058767cf5b7fe8aa163ca3d9d3815e3342fbb064f78ba69bc5ef35740a5fac2b): 89405133, TokenName(96bec1ef9b53b4b1bfd65c5c5bd1c751d365a535acd4bb11401a4e4172e83fdc): 1758977106, TokenName(a0f0d60221eb611b192c0318fe46915f41b03839e9922c40bdc1a326483cc36f): 2123971366, TokenName(d4ce842c79fddfe255e81c25bb4189e53e419cf4f74c35d5aaff12c198466456): 823370924, TokenName(d6cc40ab3a5f47dd590dc0bd2a87761f556b9277fc7301dfab8c1dc42327f51b): 614533644}, NativeToken(MintingPolicyHash(ScriptHash(7dc5472beef575dedeba07247adae0b43317f20c7d4f7d29d2ddbd4f))): {TokenName(201daf01c4717c5f43241ef5f170ae2e873bd73aa67444f5c49f3ff1356e9bb6): 1107385662, TokenName(4f55db736a7417bfa461633252e53767be23915fbf2262e308a0f843c6254d8d): 2200142665, TokenName(9028f491cb42e1f58077de7b860148eaba964c356aeb17948f51fc4d1cd05162): 3435285839, TokenName(c0bd6aace9ea7035000bdca54a0f75b94cc500ddb7c72a45e178556ac122e575): 1855012893, TokenName(f86c5c22cc8fc83b9ff9887919723ad0f52c74a35608b4486868d48309d12dcf): 292819744}, NativeToken(MintingPolicyHash(ScriptHash(d1e78e1b55ecc37099b09c19c4e43bc7d80091f6f7eb04a3dfecaf7b))): {TokenName(46fa6f11a1a1804d62e54e99c6008a8d4dbbee7e1ca8ece13723f41b7ae91ae3): 1958321457, TokenName(98b6a889c7f845563a43ae3d7b9b79175178dad15a89aa17857833797e478b2a): 3410658069, TokenName(991a5a44dff719183517b49de66e4e7e5407332e255997d4b00f9f2ca935416a): 2785847006, TokenName(b17a60c7d3b9be063fe04e5d7eac10680d3638a4b7c1d89d1a00b48db679dc1a): 3566753732, TokenName(b6ec271b2023f299b9be96cbb9eb0777f070f50b1c216e1dbc40bc226642bd6a): 495228508}}), datum: None, reference_script: Some(ScriptHash(82634bd33f7891bb389fcbdd6115237f7b65023ee592d3f11d24df1a)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(e8d0512bebc3f22bdcc230f16e701440d7658f93e54483160d65b6f62ab57c29), index: 2071800198 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(dcb280b41876837f300028983756d137e7215df92c08fb9b79f75a86)), staking_credential: None }, value: Value({Ada: {TokenName(): 5624235340638428308}, NativeToken(MintingPolicyHash(ScriptHash(1bac1e9619c62c8feef66128745efbb22d6f0a64aa631f461368ca63))): {TokenName(044bf02b9bcc5f707eaee855f0bc004a381b0d824bbab801f6d8c29fb58c9ee0): 3379296639, TokenName(36561fe689fba2eb8293e2cb270b3eaf53aeb390cf54f4f601f4dc006f8dbc14): 1047494172, TokenName(76b3183a61ea1fe69c0849452b46c6fd89d1a73e2f53de79bb6dd5d232dd4d88): 1290674388, TokenName(ca9f04a8a1510e023d8c044e4795ca4acb6596969280e22c37575e9e89c43cd4): 353384854, TokenName(ea41a6b1405d779ff6f61c6c8bbc8e0b9cda6bbf0412bc578e481da04676167f): 3704700847}, NativeToken(MintingPolicyHash(ScriptHash(1cd2215b34584d4dda4bab887b76f94d89de01a13abb61e5a9650528))): {TokenName(321a8831d15a104684ded815355bcf613f029df63346b4526b446880321c7a11): 2279194748, TokenName(52c417351a1782ae31c242a4cea1422f21279745f58b5e86351a755c5d049c74): 447980304, TokenName(58f95e1ad406bffc94e98d115ed4143f6da0fc5020344922e2d1d330c4ed4e32): 1746535223, TokenName(89887ad74d75176efcfd911b64d5e91155a4ae30fddf75b3074fbf215fbd4e4b): 3134212159, TokenName(921074537b962c105e1bc93216b3206fdfdf532c9a5f84f2691d5de18b27bd54): 495942185}, NativeToken(MintingPolicyHash(ScriptHash(25cd2e487a68d1714489f0bd1a74544ff02faa453ee82a18bbc666b9))): {TokenName(2b60bb3694f2894cd0a0a8b384c54cff4dd4e742998634bb27476bda6609f533): 2655304319, TokenName(3c86f4af2e89fddc5617cdde51d98dcd92fb90dbe3d97c7399e52e99f758ae73): 2837538083, TokenName(cf8ff5e5069ed337f0b84eca5b5ca2245db5dd7a3f1f5876d45ad887e306489f): 3133768452, TokenName(e870a213c3bf8136803d4a89c5562527828ee169d5a656bbe9f9083365e7216e): 1159067530, TokenName(ea558ec6232b2e6a59f3b92b937c9448f9d37ff4da3329e6b7291b6b3e1776fa): 538535041}, NativeToken(MintingPolicyHash(ScriptHash(87bd1e399ef87a366c2f862af586f7a88f07966a2e0688a2ef75c166))): {TokenName(02c2dbd555cc125cafd605272dbf268cca09067dfefdaec562ad9e1f31bdb59b): 1031204712, TokenName(19d88465a294458f0e949947be5bdfe74f6ad0e52aa92d7e69d714d88be82509): 1211739728, TokenName(3090a67fba097b8f60b320ba8a0eb0c1b73d1c37ef1a9e9888a50b5a9dc948ba): 2089163239, TokenName(74f2a85523073b48388f8649d1981d46bda39db4aa82ff1775b53ab686b83ff6): 2360565832, TokenName(ed16ac0eeae5444117899b1a858abbe2b9773633165a15d33b94725a0138dca6): 434838110}, NativeToken(MintingPolicyHash(ScriptHash(e1d315f27b5cd3cbe257dd6503679813d062d5c657841c5cf9c70367))): {TokenName(0adb1377740dfbb286c40b30b42982ea96b55b2d1bdc45486b72eb361d27429b): 548348522, TokenName(62e52135eb6d417910f8f8a88e75c9d6e6dc681f555633c9e25320305a02a46b): 3899433438, TokenName(6d83cc65bbea2df50bdd3ec930330892797278df582d8479dfa624f3a63cc412): 1029726376, TokenName(d80a519c322837737f5a3a91920577f3c39d398ba4b78626e032be10fe8ba3a2): 284355618, TokenName(e71556ea487ef26bfbcecbbc1e2d5b51cebc06b7a2f3b87f9ba8e70cafb92700): 2559183258}}), datum: InlineDatum(Datum(Integer(-9956574158313405922))), reference_script: Some(ScriptHash(52cee8e61aab51d5f7609891697546ac7d87eeed93c2c6dc3acd04ed)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9c58589c8daea6e0b0409c4f7ad0b5f81c77da6ea341f3f41bc72905)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(3059909667), transaction_index: TransactionIndex(289629170), certificate_index: CertificateIndex(418984329) })) }, value: Value({Ada: {TokenName(): 1778766396015761356}, NativeToken(MintingPolicyHash(ScriptHash(1197c6b68c6ea8cc3bd9c65e839851e3da58a6361c76251bc74117bb))): {TokenName(321d367c79a4aceaa2e8bc758200abe1f124f537e911df4fb33b4445f92a4900): 3508830932, TokenName(64bebe7bd1091a3eb2c1c8434ab3a20920e5564d1bcd8dc0df82d7eef7dbfc86): 790197286, TokenName(6bb8ac3d79705dd2ee39d16cc1c4a10b8ce210cab7cd570da8e9ae0cf331bdf8): 3371814343, TokenName(aee720de84015b51f7e36d957c7f6fe676da8baa71343c84fe55a1696714218c): 1578127368, TokenName(db14a6aa9dc0f0d2cb7610fdec3fb3b75a5a91c51cf8b31f8beaaf69436ca212): 3210872368}, NativeToken(MintingPolicyHash(ScriptHash(2a5ddd5284b67cedbbc0b9542944c54fd596e6a43d481de474ef0167))): {TokenName(1f8804ad5e8d32d68ba6e80dc84093fb057f25df3966741a3cefd239f779a289): 2829558214, TokenName(c1cae4a50ab84144428a9000d3e3fb22ba871982a53722ee99d65a41dbf2eb46): 1823425964, TokenName(c1fabaf56e2d6b9b575e2e66a1179a86e36660ec9acf91371cfb6d9c09490a32): 550930646, TokenName(c387c1bced5c13129aca014db0288e2244027e119d113d09a763c350612cdc67): 4216692701, TokenName(f4fc067b6a112f17b33008aec89995b5bf82a7d713d7310d655665ba75b0a0d8): 2786331769}, NativeToken(MintingPolicyHash(ScriptHash(35ba236db90c96c3c68b24a811395ecec20ad533dd5bc7a1a5e201da))): {TokenName(341e212c607383fab014eedb084bee56f2748007830aef3de482b12435f3db07): 3512203437, TokenName(562569975b624cf11e43043c032a114f8c7bb1d599a42a71481b86093e1234c3): 3589545001, TokenName(79dcb3e70bc3c6d22526a623d219c8bb0de1a8dcb45997a41a78b1a760e598bc): 3627015719, TokenName(a72a5e390b047db8f424664553f2a2f66914a974d7d5ad613f6e673e0b66b46f): 3523736973, TokenName(b5a42eeac1876b471fed880f36d92f4039dc906d2d518bf44122382b057088ed): 645553009}, NativeToken(MintingPolicyHash(ScriptHash(60c58a89772f3f858ca9ff76f1ec016afba91f196ff136a65439928f))): {TokenName(2362bad679a7ef42722ed43dbaebcad84b37d0054f9c64222d5d791cb4002e65): 2033594753, TokenName(48a009b659e52be6a9d9965f2f17db6f67203af28f5d0c92a21a1a0cb1ec7bf8): 598407792, TokenName(73989a41f7a31ce95ed23c1194448f66f5ca8fbd22f3c9fa83aeb7f3906167eb): 4045763823, TokenName(814d6964cd4464d1ab56f8e37105c739074096e16f0603d6889390431f362326): 2385763296, TokenName(e20e4a40482613712852f8299166bfcb350d3df88ac203fe43463558ef580228): 3226393680}, NativeToken(MintingPolicyHash(ScriptHash(b44b437978704052f799c0dc85035e0a00418d70341e4b215131b99b))): {TokenName(8a840ac55856e507341465ba66a1b23c6ae7fba76c73d5fdb415cae1eb8853fe): 2344408113, TokenName(8d81c723280fc3c49b8a09ac006fdca235cc712d764ccc4b2ac973c7cb3b067e): 3349808160, TokenName(b3bc1bafa4c4310fba9a68a081e692371d8c7b735bd62d84c1d336640fcb08e3): 4201247644, TokenName(d2fd15449c1b0168df70370038ca3f7b4ce291be306af4ca47672e6d891d824f): 3290109883, TokenName(d6e4c6a99371599e79f9412425696f389808809c52793ea63cd860fdf0742c59): 3890841551}}), datum: None, reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(0faca775bb455e5e7201dc2e15b8419c60b5af395a0ca6458a4f45c3))), staking_credential: None }, value: Value({Ada: {TokenName(): 17191670480344166570}, NativeToken(MintingPolicyHash(ScriptHash(13b616f498a53cd6d76ff003cad8dfbfb943862699d6ae1dd2f6d634))): {TokenName(1461c1038be0d7c206f85ea0b74bfe9dc2ee27274ed6712dd56cffb7898c7696): 1324640563, TokenName(198bad8abb024b7a1eb03cc65b6809f546b0396a90251df6c6b754be3aba7b84): 1867992264, TokenName(534228e3eff9fb336aa0367983f54199fd331220b4218d01b8123a981a80495b): 89428173, TokenName(97801264b4899a0a218373e01685c6dd4a9434a01ece135db94d15c6ee25d67d): 359436282, TokenName(bbfd804238fb1c4d9cb616ce09448145efb2a2dd549fdb36debf6bdbe4833e4e): 4275275621}, NativeToken(MintingPolicyHash(ScriptHash(8dbafc2e9759cc031dda7d36617b7e05560f192a2c20f2af78fcd76f))): {TokenName(55a428280d87a1eaf60a893a0f60fd237400df3466b7ce5802487bd2de8163dd): 967396829, TokenName(8499c0da34c51e108b13d1c676e3a9c6856d138be064c386570d11099bb46253): 3160710516, TokenName(9a727bda26b5febcbdf4b453b59224649c413bdad806a554698e8405547d7bd8): 1816487296, TokenName(9f906cc1e3fb83b442d8a23944015b45f4b6d71ed71c1e81875ca77e9050a0bc): 2866195868, TokenName(ee0afd07c03db18cc80f8d773cb25bac7165e63b2a6c68462d0b9247553b831c): 1570877030}, NativeToken(MintingPolicyHash(ScriptHash(a251260a0b82b0d05a91ed969ef66eee43699da7191faa844dba8425))): {TokenName(4ee98a99dea47d7d7284bad0fdd29a0723f769d63c05806134739506a2021b89): 2346037911, TokenName(65dbf707d2322852c658be02d749b38c59401e0409e300ddde0d12a34447b6ab): 1315013433, TokenName(6d0db7a763a6f24695afee481a6416327c0568c9fe2689568a04d332e54d9881): 1499516955, TokenName(7b874bf3977c665b77d50cc4eb476fba32dffa6e2b71f5d9d5703a28e228f5a7): 580680245, TokenName(8d36fd16080e83ceb493dee8288cfb8bfb79aad0343111b1709d617d13927918): 3616164132}, NativeToken(MintingPolicyHash(ScriptHash(a3cd9d960a5361d08a68a62b391bce02f40db08014e790fc50237226))): {TokenName(01ef3f234dd923cdec095839be17822c67ef030c04b575d9e095e39d897a434d): 103555697, TokenName(2821f1e8c7e4f204bb4fbcc85a963902874039f8dc2ff00b703954e3393da340): 1155791812, TokenName(4fa210c049dc8d7da88885b68dc0eecb2fef421fbf3415ad37eea80d10cfe43c): 398998325, TokenName(882f0a31380fd236fb3a37d2d265ee00435de875bed57f9535ec842d11c1f1fc): 2842051405, TokenName(98b2bea36a9a055d2c13012ffde883f02876d1a9c232ec7b400d0c19ef209db2): 626549601}, NativeToken(MintingPolicyHash(ScriptHash(da54406e8a31e3bec9e2902f116a036b657cd4edcdbf1abafecdaa15))): {TokenName(00ded037e41a50f777d585bfa6d5c455aecb2d44ba4106d23537b9e214d2ecea): 2915435893, TokenName(0971f6078400812c5e84f8f3b2dda6442b60d4342955c1262a8668e10cd7e84a): 4088687709, TokenName(acb5df938c0510ebcdd443d28e98fb4d3ca3b88a3f5f80147cfecadeedfb6d17): 1175270776, TokenName(adadbbdc61b5e5553fa34ff6fe9ad6c6bddc9083017300ae994a1cdd1bf277b3): 225174560, TokenName(b5ac403a4a9c86760b29815d564fb7835acb9c24dedd2ae20abf3ced5ee2627e): 3526364138}}), datum: DatumHash(DatumHash(1f1cb46dde0b2e062f29bdd4eaf704590dfd4e75a24a594fccd6efdcad82c28b)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9a3bc0719ea5cefb5c19d499e7f789f208d186900d5af551f968ef90)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(09d8289290e5a43c238a7bd3e4ca9c165fc96ece0d43acfded07d0a9))): {TokenName(003f5993d9e6be11b15e094030b592e24fc6bd70e3bb475fc1e6a9f8a1480449): 1815528716, TokenName(7ad73078397aa3477623017b9a3264df30a68b40d65096e13c9af7555f083cef): 1229163749, TokenName(7dbfeae24bca1701c87c91c25697a06bf478e35bcfa0c2444e93ebc20480ab68): 1382274669, TokenName(88b26817e33204a94f0898c894cbdb6970f41a699c4ee2bd73749b01659302f6): 411281757, TokenName(c089595ea7ac47a21b89c9383af436dcdcd6a93373fc42bd9f2cb5f6e0d6c7ca): 717514761}, NativeToken(MintingPolicyHash(ScriptHash(86f55c87fdd257e4bacf0136c5d28ea39d360f855c7e5cf6f242bd45))): {TokenName(23b21e6cdfcd23c5a999b219f085f2053aea2dea8bae3e5c75c36fe5e2408a9e): 2338625822, TokenName(4a7bf08cd87cd3bac81e17ec6552ebad9d2c140f70a39c0bb5745a0220ba8146): 3024758461, TokenName(5456d402fbfe36c7af4caf42fdd39e6f4a0aa1661c0fa10fc0723f8271bf89ef): 2136873665, TokenName(998f379a2407323ce62513463f459530daab36205d0aae750d86978d29660cee): 1783137114, TokenName(c24ae0cf5df8dedf4dec6f0112c6d0dc4adafc90159bf9651efc7fa2c701de33): 2718346328}, NativeToken(MintingPolicyHash(ScriptHash(8e81ab149961745cf535f1cdc0cc81950d076f4e98fa40847ed43100))): {TokenName(176b0db781b4cdfc59c2c2e4fb22733e1c228bf81107c7eff14d8213a1a00a74): 3843140964, TokenName(2d47eb236d7f4f8f422a27329df18b7c9d52202528be053c666eb9a968a357fb): 2710449835, TokenName(3779482f325b3889e3ba4387017bb05bcbafe02ed258f48363d42bee29fbf693): 3203306923, TokenName(4c97ee670e6061f0ef51987ea97c630c026c3895466e0e94db71a40bad69e112): 1343640868, TokenName(9bde7c9632b4f7bc5a0578468e510d860359416cc378d8580f82042bd2d76e23): 1013243267}, NativeToken(MintingPolicyHash(ScriptHash(b55a221780d89ed4cfe3446500f37676f8862a18d5fe9ffd029e6b54))): {TokenName(2faea7bb72d2f4f42f421ca3474f57ed7a0bc49bfe50e7fe6b4aa0bfcd7559f6): 2052560625, TokenName(5f55ff60553ee1d98dc86caa26f9f54feb69183fe583e9137bb2aec2a072c000): 3241834987, TokenName(61c6b54180c029682f51b1b918d3fc22b6bc053964b6d35801f59271a752dde5): 3108922155, TokenName(7e5a58d41c5b2354da63977dc1d505ebbad9ba92badc235cc74d4f9f3e4b7849): 349744316, TokenName(81b1b4d3f19c1e926398d6509d7459c1b4b4a5e3f487e4b152ff11f495ce0d6d): 2585552279}, NativeToken(MintingPolicyHash(ScriptHash(f95aaaf4f41f58473d9950d942dd875f619a55983bf4d437b18ee209))): {TokenName(33542a248239c86bc6a840b57eee80168862a706ef23a2aee3df3799f0a3ffab): 424813100, TokenName(59f9c15b98b54f119212d7828dee1b9c550fff5a2f9611bdac7edfeb8081bd07): 852321931, TokenName(a4b10c965633930f1c7e035b8c6aa2c3b4a8ccc7aa90486054ab85f355d87013): 902256490, TokenName(cb10703e6869e04bd24c9aaa966e90077ab20f5693703afeb75954372d684b54): 2343434831, TokenName(e306aa8b0e176caf6d36fdf9133ca07913a7e1166bc235f9b3f44be504fe033e): 3855295454}}), datum: None, reference_script: Some(ScriptHash(30f531f0d8f059a6b00bb17e95a7c718959fa751558f44a327857b25)) }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(ec761eea39c340a69c6fb3eaa372aeaf800555638c910e1e025c9a7d))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(03ac18eb0e12b53579997623a8f72fb3c429c5ebf5a41a4ccdd21d70))): {TokenName(19ab57f5fa488fc110644ebbf08da6fcd4b7f1b544f38da09b040f8739bbbedb): 2518964382, TokenName(62416073bdb421c7242bb19a546771a2b0409daaa66292d95c1cb33bc8943f8d): 1656408066, TokenName(a151df70ea8442edcebbde742098385809fad19a7b5ca9a467352a7ca1958143): 3908199478, TokenName(b397d9094ca4d8ac4c5890f63535cc519961a2fb6ed2ae85f85762d71ee39bd3): 1352267552, TokenName(d9e7c9df00f284849ccf4a99facb9e93a3dd6086747da76aa8676b4804bdf618): 2861143482}, NativeToken(MintingPolicyHash(ScriptHash(91fa53087d9026ebf8829416fcbfa3cba44ff5fd2de2cbf4dae4c766))): {TokenName(04463079dbfede339bd942f061f977f96d29eb8dd332c95ba7a83fac6dfae3d0): 144548287, TokenName(0924d74204259a14f3d79dcc4c562a9c6ab0117e6a27a88f7bfa7b739fa96e07): 3509554855, TokenName(6f27b648acdaa4746354b892be555c591747a0cd6f913548cc2473e4eee6f3e0): 1675798510, TokenName(8b5353741929fce6b960b675ae375bf2e94ce5f82889c7346c29b591054cdfad): 3578297260, TokenName(bde71f055d9c5f0286f337a6b82f6bf66e29aa8d5a5f5bf5302477be2aadf3c2): 608042687}, NativeToken(MintingPolicyHash(ScriptHash(b9064d7a8c2a1110a531d561d7b6bf7337b4e1960fc29a4eb8eafeba))): {TokenName(21056bad64decded64532114b0a37e8aa53f6149b07cf63064b0ab36a2cffd8b): 2632119827, TokenName(30ea01ce043be88cd6b868c2c7ff30cd91c2f17c9dffc0a53d264d6ea9528011): 1463337029, TokenName(456a14b9402437b057f06aef1918df492c47449f647845b9195042f40edde7d8): 2064017649, TokenName(648370902f82759dc8d0c3bca60a64b846b69e5334893a8458c1c64286ba6403): 3348192523, TokenName(bbbd9e146deee40b156040457e7b754dccd7c9a0867e6414980422b5e227049e): 2358894817}, NativeToken(MintingPolicyHash(ScriptHash(da4e9f3ddfe199c006d0f9ab721925c22c30b7c8772e7d0c230baf37))): {TokenName(620317ce5c7b640b464c7f273df9901b8472d8a6716d31977174050fdc3eaa16): 2076682926, TokenName(a3f5deaba8007f644a26988f6cda2a4d809799eab21325b21c2fb6fdce086f9e): 2412943953, TokenName(c5030f54495f3701c9e2887469a15ceaea3cdc15bb40f39906bc831019ed31f7): 615192849, TokenName(d5c5be324bb653d422258215ea5443be65d9ccbcea6c5cd2b3b5631bb4725439): 1142290255, TokenName(f7dc7edf6ea29fddd77a29324effeee617d2d45432ee9cf2cddc6d17382d9a26): 880307032}, NativeToken(MintingPolicyHash(ScriptHash(f2c054a52cfba3b2a48a2f5289be9a77e198260ec32064194a2b7998))): {TokenName(2213ca331cf1f07dde0a0718f74b63e2ecc6edb3d215eaa2b792558e65ee5447): 4208271782, TokenName(4b29dc7827b40bfa065d39957ec18f96bfe9f58dd0f5c076aa5324210e733521): 2669906136, TokenName(6d98fe0599f37e23d774f1a6cd209df36f85483c03ca564a22589144b2f9e914): 3749525743, TokenName(a6c0242a0756a62ec28075ec9bafe4059a5adb9cb92c3cc76bd8bf3a8b983e3d): 3155040882, TokenName(ec1605860834af7b073dc112ada90e6ab530c5ab9fdc1fbcddc3dab021d25137): 69909880}}), datum: DatumHash(DatumHash(24a7af37e514f61fb4bdc1d22c1ee8ececb9afdf8aac797571b5704c237380db)), reference_script: Some(ScriptHash(631d2a7109fc05b54a600e1172cbfcff9ef662b4883266c285a2283f)) }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(08627132179484c51bb35060102f121a0735f61f8d1e42c220dfe487)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1efa734d67168fbc8d93170f7fc65a9870f8f43b212b0cbd57295751))): {TokenName(17268d28e91d74342d4991fa12c3bae621a7af526238e3095be461fa9d26e46b): 2570813478, TokenName(36b28819d1ca7ce52536c5cf0a9cca828f96644b7bb41bc6d0d4467537bebc8d): 3393761679, TokenName(7cdd0baf63bf3b26b4bf8069bca24fe336646bf65c66646568efa80df3b90560): 418721239, TokenName(8a2d4ec9912b245c011791cb914e9904b29c7466f51fd45dfe07f4259a694639): 4033126661, TokenName(f768447ba0fbab3ba8ac8385859a0d89c573706179ff8c7bc41dd1dbaf3cc015): 1275518025}, NativeToken(MintingPolicyHash(ScriptHash(30b958c36b3e9506471e962ac0d6ca6409cc26940e79c2f17063d43b))): {TokenName(0af86696aee816f944107fc689dae0ed62da4f78b7a8eba25af007e366682ab8): 4102103124, TokenName(42d0dfee36a8fdb7a522ce21366da8e11f54e79b1ecbd8f4e36481adaab5b395): 3750284091, TokenName(60c7cf7a2b4bc6cf0ebb20a6faf7585d323649b72f8a912ef213c7d93e317c5c): 3130665970, TokenName(71419f4cf1b8686ca6af11192ac643f8617e2dd3628748654f0a864c9c9ceddb): 3747489957, TokenName(7d4d39214d8ebb33e3c4c4f1b997274d6f8d93bce93fec7df8c5c2943ddc5899): 2707795912}, NativeToken(MintingPolicyHash(ScriptHash(3d5f6d8bb70891a015ce82c8b7d55638f61ecf52b7ee2ac12f557a02))): {TokenName(148a2348d53afc797ffdb9df38001bae9000793ac8dc60804e745b8a87404a9e): 675953931, TokenName(2999da457948714f1ad9c33bd540ef5e4db4725a3789d7532f3abe87e9ebfcff): 1144848020, TokenName(3ab918add85b549820719f580aa09e5cef6d82b1e447fb5b0a2200d75550ad1a): 3837268611, TokenName(4ad0746080153f2099046d58f94349e051314a13dcef24add1027f15e53d1916): 1350699108, TokenName(6760b9ff5ecdb761b4240bfb67764d9f10f3171b738611945a7ccf0d0c55ef1f): 1646471413}, NativeToken(MintingPolicyHash(ScriptHash(45e3ff091c274f7dab3fc0b6bc8522150eae804573e65d4060a82458))): {TokenName(89004b31dcee69f16fee1d1c14f339e969b5f8e5622042e2ea6a60fc18c1fd6f): 3535052531, TokenName(b0514600cdee8a5c64d4c5f94f232e2ad5cd7bfbb3705f18e52b2aa3de278f57): 3551698795, TokenName(b71760084577c9f984a3801b1c549ba7bea5699da16e9a3fd6b88ae2824d18c5): 4130989591, TokenName(bbedeb8f323991e258dfc55530ba7ba8c66c572c83da45fb4e64d85bec43baf4): 3803686025, TokenName(f36ddf2e0ac6ff05d34598255d1773c22f42ee976c817ee63678962a42653f5c): 2086145863}, NativeToken(MintingPolicyHash(ScriptHash(bdc5fdddde9806d91f7da86b3abcf56400aaaee4e1713f6ac3791ce9))): {TokenName(383b831d85af8a481a7d3eb6e755fc66a307810bb6a8c7cd4408aedc7a169729): 1587342539, TokenName(84dd802f39b9420b27b80b0008df3edf69647bd075ab1fe7454c6a6ddf9e7c7f): 4029852972, TokenName(8d2592f85c7d81c201b05cc8b5848a3c881caa9266744023d76df570460b18cf): 2123956503, TokenName(db8016743c4af9aeb82ba48cd4b92a35e674e9f2a6e5d3e408b49c044e625843): 1811830174, TokenName(e78f7a8668cafe8fb9eb907d11310e2e7a2c91586c7e65f26b4e4e1edd6594e0): 1199343382}}), datum: None, reference_script: Some(ScriptHash(dd3246fe6e30d877cdb57609b8756a93ea209cf83d17ee3e549e00b5)) }], fee: Value({NativeToken(MintingPolicyHash(ScriptHash(2f9863727367b0d7e2acc0779f9c4d7276a3ce14434168e939788955))): {TokenName(429a3f398cd615e887111585b6e80098cfaeaf114b041ed632e59b9241198a30): 1555683774, TokenName(4d47642d7314dfebbc8e604fdc780f696363ad680403355e87ae4da7816b9638): 3592907140, TokenName(4dbfdfa0dd57671ad6d070e511f3dcea18f6345278f5236b0f0a760071b5aca7): 3408980460, TokenName(562cb1afdd67f13de123f96ff4a329e164b1d1fde34e64c5e000bacf443d2b5c): 3168086864, TokenName(aa5f81ea275a4b5d4541c1593376bb4b6daa83b4ffcb00be9e9e07070ee8d323): 169981035}, NativeToken(MintingPolicyHash(ScriptHash(3a4df10551937e229f522b733111206a4c59a2388628a8749004108c))): {TokenName(187e6fde82358b63c03451b8dd1361fc53a2b6905303bb9632013cc1be34ab5e): 734045897, TokenName(3403e18344cfbb6653951c9edba43e1aaf427c9f5a635db3aeb96079c556ea45): 4010288560, TokenName(bb520dd935e854714c3167fcf8b605928c56f1d087f26440593b67dce8264ebe): 989031355, TokenName(d5f9e314b5460128827a0dbf88b0fe21df985ea3f3405461fb5b6d3a0d1b5d2a): 2046624902, TokenName(e882a0be331fcc394f7dc1ac99e729972d51b9d55aaa1cb7f97341cae75450d7): 273147440}, NativeToken(MintingPolicyHash(ScriptHash(68110ef703304ae479c444a6201c03997cfc10b6295f998274dbf2ea))): {TokenName(06f4266e7f2c030891cbb9ed55bd1f0c3fd41f54c0063757f5070977f4df742a): 895390465, TokenName(538d1edde8cdcbcff022266c300676a2deaf83659c1b51737340585536ad0076): 1716482888, TokenName(62b19a0454f9c2ba8f44bf1bc53bbfc3856d11b30c9f0958f2fdfe6e7973fe51): 1173906700, TokenName(a34f088141c5c4bee0c735d8bded3da2122c6279c33fcfe32cf900c0f4c5cd5c): 1478004184, TokenName(cfb00dd9c985a6c5cee0444bbcf147fc7afc6e05c2d85fbed2833ae410e3efb8): 3063484456}, NativeToken(MintingPolicyHash(ScriptHash(9d0fe31ab7e3f2f7406e878e08376aff36e10dfd56844f8981ea3a66))): {TokenName(132efcfbae23f5c18a0ffa9bb7b258ee701abb3797f38a1097dc6851308986b9): 985486808, TokenName(24a8b01676fdbc399e6a1589e6a7bb33d766395c9d78da8d113d451201d54690): 3241903114, TokenName(598c739a09af4bb634c708c30fdd6fc34cd633f5bcd1a7d6dd7731f83c5c98e0): 3005678126, TokenName(a8b0b1e5142cf0f1cac3f104fdcad8dc55dd65800ef64d1b6e57829a8891cb4d): 2988582047, TokenName(c80a9edb35ff6b5fe9292140e284f3b110034ac1cea95bef2eb2a4c1849b4dd9): 553307105}, NativeToken(MintingPolicyHash(ScriptHash(b2fbfbf224eb9cfc223bd3ed11f6c0a4cb4375f5f4cfb7e34754a613))): {TokenName(1d14511e247931cb6733fede871fb50c5b889a8191b26d534ea2420e6b5fb793): 4043197660, TokenName(49617ae47d57e3ff6dd8129b181f3f4bda7df20219a6be2cd2265c23449a96d9): 273104966, TokenName(6288fbea5a0135345990f9f79adac3f81b0644e8e5175f6242aab3f387084237): 66366596, TokenName(72b6c30b1ee0e44aec201e0361e8e3df1e18ba238d8aa6ddc4b0817755d11b8d): 2062758746, TokenName(83622b675752a919f2aa1ff4c68ed11354374b2abebb1029ad88f1a93a831fb4): 1099160643}}), mint: Value({Ada: {TokenName(): 4104180352706495912}, NativeToken(MintingPolicyHash(ScriptHash(1a5eb483f29e60cf94d6db289237c92aefb6f00cd17116ee999734b9))): {TokenName(25da6b3e9e675b6a8bdd597de4ac48c9b3a880ac5ccc63acd65cf62f27f9008c): 1231233814, TokenName(427420e13c51ebd62c14bc0efff31f770328482a204911d1e6b32e8a6e3146d4): 1996334957, TokenName(710e81cc94a0cbdf08b522ca8e02ba017b2c57ed3ee360b0bba12f1dd39afbda): 2661078626, TokenName(ded843f4173fd92c5d1b6c343da011cc5373eaebd74046b8effa159b95b0b4fc): 399673598, TokenName(fed348c8726ce77dc3e317ead26f820379e5eb998e3215a6c45aac9eaa1434ea): 4151868046}, NativeToken(MintingPolicyHash(ScriptHash(1cf98e68f452aa7d791c36d9495f37dd9d98a44cd70deb233aab4a8c))): {TokenName(488e54b0111d8ab0110f091a930ab1a3bf29648f15e9ce291b445fa74c271e4c): 427903071, TokenName(96744d9e07184dc82d51b499e984838834744a02a59d6d5f0b213e318936cb85): 1997947289, TokenName(9b6160513350d1f3cd0bc865c76ac9ff4f17b0157220d569226c7a10b636a24b): 669481020, TokenName(bb3a60a8f39d1df1afd753eeeea00993bee72535f3ccdb5cdc3911ec1cc31021): 4067912973, TokenName(d2adcb9b62c6646a8653c822e91b87de8a9abcbac84b799b808ef43639a4b016): 3918566276}, NativeToken(MintingPolicyHash(ScriptHash(870ecba83cde3dfd018ea32d685cb450d2d4295f5cb4073f29bafa9a))): {TokenName(0403f0c9cb67117c895168ae75deb3bbfb9c9d13b43a2ecfef164b3c9cb7a855): 2905897182, TokenName(1f6d139cd673123d10495454fbbba2d3b72c8bf630011164b8ddb16e078808e7): 2763742922, TokenName(9b4c9f57c613b8dc4ccdaa59ad95dbf3bbafecc90821b014f4bf77211b2799fa): 2647325274, TokenName(d7a183b7753afe71a94ffc4b9e1f23c8f59fa916ed981127f9b2741a24243acf): 1630302619, TokenName(fb047eb4525d6ef3550b3e87597cebdadf66dfb547dc23250ffc478ee03e40f5): 2645150031}, NativeToken(MintingPolicyHash(ScriptHash(a186daa8e4f866e46d68808ad115232a5ee746fd0875bfb18ac1b8d7))): {TokenName(7a134f9e9c448fe6e97557fd36f3d7a81639d04e609bce6dc37d4a8257596a20): 149746960, TokenName(7bd98296d4c5a45f14e45f1ef70b44e323e1a4a342d5950048ad28ed102bbfd2): 3131521095, TokenName(ac9aa0564b12e5ea103a569c59713d6ea1bc9fb890a618e39a87597121d3be55): 3147076479, TokenName(afc3bec871cdcf99569a69ac50dca88cc75eec498d1d1c269e896fda014a1c76): 258148948, TokenName(b5348d158cb92e19b81c56990d7ee1e705abc19a3a422d77d81153ea5832ebb9): 713428795}, NativeToken(MintingPolicyHash(ScriptHash(c92bdff49727138c31cb3d49176e054816447dbbc79d39f189f8f676))): {TokenName(153334516784cb259748056bb312cc5416c04e15c36db4fe9cc2336b21ab4253): 835283426, TokenName(591e68815b2c0f8d66418a11fd031d6bfa1e1c64587d7988963fcb158dd6f8be): 3356235553, TokenName(8b9065fa54273dacc3752b3a703daeeefe6dcba97e0a9db43c97fca1224b4858): 3794081327, TokenName(c9401e06d8dcdd84d9556d06589915eaadef20ce3897ebc5df76607b06b61435): 1689084015, TokenName(f944a8b7e0c7f94173f35a1d7a0e4c51174f9ac89e20f71df3aded3db66feffc): 2290874670}}), d_cert: [DelegRegKey(Pointer(ChainPointer { slot_number: Slot(1255069606), transaction_index: TransactionIndex(3060645162), certificate_index: CertificateIndex(1133172045) })), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(2058101779), transaction_index: TransactionIndex(2683260422), certificate_index: CertificateIndex(2332862830) })), DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(2949232829), transaction_index: TransactionIndex(2376444952), certificate_index: CertificateIndex(1584659227) })), Mir, PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(56a7cd13edc88705dcc4e7b5c3a4be407e4cc15556fd31ff61da3de7)), 1704978752)], wdrl: AssocMap([(Pointer(ChainPointer { slot_number: Slot(2518930256), transaction_index: TransactionIndex(3594332237), certificate_index: CertificateIndex(832943901) }), 283529990), (Hash(Script(ValidatorHash(ScriptHash(99b971201b74682b3aec8d3599b5f7b04f69787ae11b56381e2e89a8)))), 1315944064), (Hash(PubKey(Ed25519PubKeyHash(8ee1d52a365940ccd463dd7e9c5ede976637263358db336f85ef20c6))), 697469854), (Pointer(ChainPointer { slot_number: Slot(1144497856), transaction_index: TransactionIndex(3973812288), certificate_index: CertificateIndex(2551665535) }), 1781367262), (Hash(Script(ValidatorHash(ScriptHash(166e40822092ce009e3863b6af2192415ec2bea68df4d223ad081be8)))), 1007921653), (Hash(Script(ValidatorHash(ScriptHash(6f60de84d117a5e915908cbdaf4b4516b7da7d61c745810f3f2587a5)))), 3106659847), (Hash(Script(ValidatorHash(ScriptHash(b7bae71e2d057c4ac0f4337c854bbb30ede877c2d7f9c5adda3f5ee5)))), 1053145090), (Pointer(ChainPointer { slot_number: Slot(3714372803), transaction_index: TransactionIndex(72042050), certificate_index: CertificateIndex(1509327066) }), 3940037914), (Hash(Script(ValidatorHash(ScriptHash(7067f6b6fb9add1cd4409a061781c24c8f9d2aa56b630b312db2e3d5)))), 4079720784), (Hash(Script(ValidatorHash(ScriptHash(a4b4a8e347008aa489f35b98272a6ca4fc25959b0bd20a68f8592e44)))), 1584515697)]), valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(838409353)), closed: true }, to: UpperBound { bound: Finite(POSIXTime(361863719)), closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(b4819d111711ba48868cd06ff8d99ab5b55e7534aece8ee98e6c455a)), PaymentPubKeyHash(Ed25519PubKeyHash(2d3ce5635fd6ef2beead54164759fe87df4853d7f504ed1061c8338e)), PaymentPubKeyHash(Ed25519PubKeyHash(a0d48ce56b063a264ae1828159fabf544ba69525c37766835b6bcb68)), PaymentPubKeyHash(Ed25519PubKeyHash(f11701c55ba58e812def810ce8b5c18d49945dafa67456b3903b8ec9)), PaymentPubKeyHash(Ed25519PubKeyHash(ad5b51db58abaea6ee92412e6b8c27f95d8d4c6e5541edd97b049e81))], redeemers: AssocMap([(Certifying(Mir), Redeemer(List([Integer(6239320199750037689), Integer(15913589025057844587), Bytes([133, 208, 148, 171, 114, 67, 36, 209, 169, 38, 209, 97, 67, 163, 204, 172, 104, 82, 231, 119, 134, 19, 204, 55, 74, 236, 118, 116, 35, 78, 54, 53, 104, 127, 234, 93, 97, 1, 136, 194, 168, 56, 83, 218, 179, 78, 64, 76, 211, 140, 137, 196, 45, 229, 40, 84, 74, 108, 200, 193, 96, 13, 20, 253, 113, 214, 237, 215, 101, 39, 154, 249, 114, 229, 169, 161, 170, 19, 210, 86, 32, 56, 11, 48, 207, 147, 209, 27, 150, 80, 46, 39, 62]), Integer(-16623484847137450040), Bytes([36, 80, 100])]))), (Spending(TransactionInput { transaction_id: TransactionHash(79cf6c453b2acdbe0bb65db560233f5a227950ff0880c3a2a3eb775c679fbc7d), index: 2947145207 }), Redeemer(Map([(Integer(10749594368703218252), Bytes([113, 229, 13, 115, 192, 166, 124, 147, 99, 41, 140, 63, 8, 115, 75, 57, 186, 46, 31, 55, 114, 209, 243, 143, 249, 212, 236, 67, 212, 53, 60, 154, 211, 97, 73, 162, 200, 224, 182, 175, 216, 214, 186, 10, 11, 106, 166, 155, 106, 231, 208, 60, 39, 70, 47, 238, 202, 215, 225, 240, 19, 231, 63, 166, 171, 126, 253, 30, 22, 220, 251, 116, 226, 194, 175, 6, 28, 223, 222, 35, 97, 43, 59, 74, 192, 58, 147, 111, 59, 69])), (Bytes([202, 49, 16, 204, 32, 74, 62, 160, 224, 58, 222, 187, 174, 91, 237, 234, 57, 89, 93, 11, 49, 122, 142, 239, 159, 142, 219, 204, 85, 238, 86, 8, 80, 102, 79, 15, 243, 138, 205, 202, 75, 86, 77, 111, 35, 212, 106, 250, 82, 122, 8, 179, 55, 121, 68, 62, 112, 167, 160, 174, 5, 98, 250, 250, 108, 63, 184, 95, 213, 212, 254, 125, 247, 233, 104, 222, 14, 5, 87, 51, 1, 38, 91, 79, 75, 87, 172, 159]), Integer(-16105624062234957364)), (Bytes([206, 100, 252, 224, 85, 67, 0, 146, 168, 134, 14, 141, 81, 163, 252, 204, 27, 37, 184, 60, 209, 69, 172, 37, 216, 220, 201, 131, 24, 255, 210, 173, 18, 180, 30, 27, 195, 201, 108, 124, 17, 229, 134, 3, 13, 93, 143, 181, 22, 222, 66, 113, 71, 26, 184, 240, 82, 213, 23, 220, 232, 88, 169, 245, 143, 171, 37, 48, 173, 226, 1, 103, 3, 75, 183, 216, 69, 208, 12, 242, 53, 187, 227, 103]), Bytes([49, 98, 69, 40, 146, 13, 63, 49, 174, 103, 155, 108, 107, 131, 192, 222, 105, 202, 36, 61])), (Integer(17641650114553881220), Bytes([19, 66, 173, 252, 116, 20, 193, 176, 60, 114, 77, 32, 12, 83, 46, 11, 241, 32, 5, 15, 184, 106, 252, 164, 244, 132, 224, 65, 158, 241, 107, 104, 107, 169, 176, 206, 32, 67, 3, 171, 142, 133, 54, 95, 43, 225, 86, 220, 155, 165, 230, 61, 219, 16, 185, 72, 208, 213, 81, 82, 25, 190, 195, 183, 161, 182, 126, 50, 130, 58, 200, 128, 130, 214, 11, 206, 120, 145, 226, 233, 122, 232, 80, 155, 39, 51, 181, 59, 140, 73, 224, 9])), (Constr(126032016, [Integer(7787559864735705180), Integer(2127818927508617713), Integer(5155631119871866475), Integer(-18396566547523949959), Bytes([63, 188, 198, 248, 216, 139, 137, 73, 106, 210, 221, 155, 224, 44, 66, 140, 68, 4, 51, 22, 74, 125, 60, 8, 202, 245, 241, 108, 140, 43, 50, 209, 231, 253, 2, 38, 123, 153, 16, 65, 52])]), Integer(-16409732504822602435))]))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(db6549ac5a932d508911a7343478c85b8519a13fb960c15e7442bf14)))), Redeemer(Map([(Integer(4864576940907377842), Bytes([175, 126, 3, 7, 3, 123, 228, 255, 206, 187, 163, 236, 222, 174, 77, 185, 186, 43, 203, 218, 255, 102, 34, 200, 39, 35, 29, 12, 207, 218, 121, 145, 223, 192, 194, 214, 27, 219, 211, 230, 233, 174, 251, 210, 215, 238, 139, 249, 167, 19, 144, 139, 108, 208, 188, 111, 26, 120])), (Integer(17866170359980033590), Integer(9968111103518514952)), (Integer(7062931128494742539), Bytes([188, 212, 63, 126, 119, 180, 238, 112, 224, 137, 119, 72, 21, 83, 225, 164, 31, 97, 157, 123, 61, 101, 47, 197, 225, 249, 4, 135, 207, 56, 212, 79, 16, 84, 226])), (Integer(2986177198920072604), Bytes([205, 136, 177, 63, 94, 84, 219, 157, 150, 134, 131, 146, 214, 32, 175, 103, 31, 187, 171, 187, 180, 180, 205, 39, 117, 68, 99, 159, 96, 73, 228, 247, 183, 227])), (Bytes([88, 132, 17, 231, 27, 248, 82, 197, 215, 196, 142, 69, 179, 145, 113, 95, 202, 25, 91, 116, 94, 207, 21, 43, 242, 200, 199, 29, 138, 33, 236, 4, 24, 132, 241, 112, 84, 194, 187, 116, 22, 131, 75, 30, 118, 48, 138, 240, 125, 34, 135, 115, 236, 164, 122, 214, 65, 2, 27, 192, 10, 235, 145, 20, 138, 243, 100, 213, 6, 108, 50, 19, 185, 8, 175]), Bytes([243, 50, 250, 219, 146, 10, 119, 162, 24, 46, 123, 40, 64, 77, 233, 17, 114, 235, 37, 32, 129, 131, 127, 214, 129, 134, 15, 176, 86, 230, 81, 87, 199, 75, 107, 27, 228, 190, 25, 132, 190, 237, 99, 177, 137, 249, 184, 72, 188, 106, 216, 171, 71, 2, 3, 95, 120, 102, 202, 178, 6, 31, 153, 232, 3, 11, 136, 192, 194, 61, 126]))]))), (Spending(TransactionInput { transaction_id: TransactionHash(7224c90041ca10dda085de5afacad591f9e7b847242c3dcff572f3b04e8d172e), index: 944131020 }), Redeemer(List([Bytes([155, 139, 250, 173, 109, 126, 116, 148, 239, 105, 35, 166, 250, 209, 138, 254, 143, 100, 91, 188, 57, 202, 217, 165, 20, 197, 58, 251, 25, 142, 25, 220, 9, 166, 0, 184, 86, 229, 139, 202, 24, 255, 67, 234, 104, 32]), Bytes([137, 215, 194, 162, 74, 174, 65, 28, 13, 61, 160, 169, 76, 236, 134, 201]), Bytes([190, 87, 61, 95, 191, 155, 191, 200, 213, 232, 191, 174, 140, 244, 84, 142, 24, 244, 149, 238, 175, 31, 67, 159, 192, 88, 153, 133, 62, 41, 181, 131, 165, 0, 240, 101, 162, 100, 211, 89, 179, 132, 224, 61, 147, 74, 142, 247, 229, 79, 191, 178, 76, 12, 39, 235, 39, 197, 108, 190, 27, 131, 214, 210]), Integer(10877039398281208866), Bytes([245, 49, 133, 212, 69, 170, 182])]))), (Certifying(PoolRetire(PaymentPubKeyHash(Ed25519PubKeyHash(0e2c3e533b548d4ad5b0cddf94dff6140554fcd04df242a344713595)), 3596605903)), Redeemer(Bytes([237, 84, 107, 181, 142, 178, 35, 247, 44]))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(34acf9d27298848ceb4c0d40c846e2647f5d7af9cabe7c16250fff36)))), Redeemer(List([Bytes([78, 90, 214, 144, 251, 187, 188, 123, 244, 237, 165, 1, 72, 126, 218, 125, 133, 234, 74, 239, 96, 94, 24, 90, 190, 3, 60, 95, 181, 152, 108, 110, 41]), Integer(5731157922341262668), Integer(-4335164808407264972), Bytes([134, 242, 84, 26, 178, 183, 212, 54, 149, 70, 5, 162, 180, 53, 242, 114, 206, 81, 85, 175, 206, 100, 53, 103, 209, 73, 207, 182, 228, 79, 115, 193, 145, 70, 95, 242, 115, 87, 106, 159, 89, 91, 30, 68, 193, 124, 115, 47, 31, 40, 133, 80, 151, 255]), Integer(15690818283624318033)]))), (Minting(Ada), Redeemer(List([Integer(2069942577745421945), Integer(13319561239276934380), Bytes([196, 179, 178, 122, 8, 111, 2, 199, 170, 233, 14, 123, 96, 184, 66, 46, 225, 233, 3, 53, 155, 75, 255, 105, 39, 145, 114]), Bytes([56, 119, 56, 131, 146, 197, 103, 153, 31, 8, 223, 37, 83, 233, 80, 62, 156, 89, 168, 164, 218, 28, 160, 9, 92, 136, 167, 173, 41, 222, 180, 128, 42, 87, 188, 131, 254, 134, 213, 86, 80, 160, 7, 55, 235, 106, 226, 219, 204, 69, 37, 195, 38, 32, 113, 52, 133, 95, 193, 110, 228, 97, 53, 180]), Bytes([29, 31, 81, 90, 253, 98, 22, 39, 253, 185, 103, 37, 32, 104, 81, 205, 210, 190, 31, 104, 156, 109, 252, 171, 217, 248, 61, 253, 159, 190, 24, 150, 162, 35, 71, 9, 77, 217, 199, 96, 35, 190, 214, 40, 167, 249, 82, 47, 216, 16, 95, 234, 130, 233, 141, 153, 102, 238, 1, 119, 118, 249, 47, 59, 194, 46, 190, 53, 2, 238, 46, 216, 239, 12, 200, 247, 206, 36, 61, 53, 4, 32, 16, 248, 175, 190, 107, 208, 110, 99, 213, 178, 253, 208, 76, 40, 64, 192])]))), (Spending(TransactionInput { transaction_id: TransactionHash(4b9a8f093e2e8b1822e4c68ba111a60d7ad9cbfcac0674f6fb7c5b16bd0d8fd8), index: 20566719 }), Redeemer(Constr(597936047, [Integer(-401514188748236140), Integer(15735402432053599665), Integer(-3275194184185951579), Bytes([248, 175, 249, 54, 46, 96, 253, 85, 101, 158, 120, 145, 117, 109, 38, 171, 72, 81, 53, 87, 129, 96, 39, 255, 77, 147, 31, 182, 206, 87, 21, 181]), Bytes([141, 216, 99, 172, 227, 36, 116, 196, 8, 1, 233, 126, 99, 32, 214, 115, 145, 152, 137, 183, 242, 86, 151, 33, 219, 162, 67, 26, 178, 51, 232, 189, 40, 92, 28, 68, 193, 212, 246, 155, 115, 27, 157, 43, 152, 124, 113, 68, 176, 176, 125, 154, 157, 23, 13, 226, 127, 242, 79, 239, 221, 243, 183, 24, 221, 237, 111, 127, 157, 194, 99, 110])]))), (Spending(TransactionInput { transaction_id: TransactionHash(48eebeaef8deeffd6fba7b1b98e118a5cc2086b63641eff458daa48b6553877c), index: 845727722 }), Redeemer(Integer(-16728904964620355042))), (Spending(TransactionInput { transaction_id: TransactionHash(0d57988e521e371aff11852b58e1088fe19726abb33f16bbf1206a67475d575d), index: 2941169133 }), Redeemer(Integer(10497112379505076689)))]), datums: AssocMap([(DatumHash(2d193c5ceaf445b29ae12d5ba957b3824cc13133825c9da6f963407ee6cee6d3), Datum(Constr(196802684, [Bytes([14, 76, 99, 234, 208, 48, 115, 11, 29, 123, 216, 168, 109, 191, 12, 116, 70, 21, 116, 253, 152, 47, 3, 151, 129, 0, 214, 127, 244, 166, 131, 139, 79, 80, 150, 48, 189, 167, 181, 71, 183, 127, 21, 201, 37, 213, 8, 17, 111, 13, 243, 233, 41, 139, 217, 234, 6, 148, 194, 164, 241, 138, 82, 181, 213, 52, 191, 176, 235, 60, 150]), Integer(81961458671434559), Bytes([240, 107, 34, 91, 249, 1, 37, 212, 169, 237, 172, 193, 25, 129, 199, 165, 217, 53, 77, 159, 67, 196, 182, 226, 50, 54, 83, 202, 145, 29, 240, 51, 33, 36, 25, 231, 192, 71, 49, 200, 49, 19, 182, 243]), Bytes([100, 160, 6, 29, 159, 137, 51, 13, 245, 169, 84, 74, 167, 90, 1, 41, 176, 246, 93, 181, 98, 116, 75, 182, 159, 109, 79, 71, 90, 92, 105, 208, 44, 195, 220, 176, 194, 116, 180, 187, 198, 86, 160, 77, 110, 41, 147, 67, 82, 95, 185, 81, 102, 44, 23, 185, 79]), Integer(16239469322319425174)]))), (DatumHash(fdf11482da690539eef20c26cd27cecd7f5cfb6d12852a4b72dddaded7158c74), Datum(Map([(Bytes([214, 212, 251, 238, 8, 244, 215, 48, 250, 101, 190, 51, 192, 14, 170, 57, 47, 186, 48, 216, 192, 147, 47, 92, 9, 198, 24, 233, 73, 134, 93, 64, 172, 119, 170, 191, 179, 11, 50, 112, 144, 229, 125, 97, 210, 147, 168, 202, 158]), Bytes([5, 14, 29, 114, 190, 203, 143, 180, 12, 165, 116, 1, 182, 219, 108, 83, 132, 117, 54, 100, 31, 156, 211, 88, 159, 68, 197, 29, 114, 150, 232, 216, 77, 148, 92, 125, 136, 191, 36, 188, 119, 221, 156, 10, 51, 10, 69, 138, 150, 166, 7, 223, 31, 253, 113, 25, 145, 56, 125, 79, 174, 179, 20, 23, 12, 167, 229, 207, 70, 100, 75, 114, 220, 175, 221, 159, 194, 103, 16, 67, 253, 138, 44])), (Integer(-13599185349541535264), Integer(12320948268393618043)), (Integer(-6026077469102340747), Bytes([147, 219, 79, 148, 176, 252, 123, 58, 118, 60, 164])), (Integer(10908679578297618426), Bytes([25, 54, 73, 167, 50, 78, 131, 108, 146, 58, 96, 138, 136, 33, 116, 32, 23, 12, 107, 202, 25, 172, 104, 71, 132, 79, 154, 117, 51, 97, 230, 166, 231, 148, 193, 57, 53, 193, 129, 13, 117, 143, 111, 38, 180, 130, 164, 214, 184, 233, 165, 215, 5, 124, 47, 140, 166, 210, 103, 157, 118])), (Bytes([110, 19, 70, 212, 173, 55, 3, 64, 181, 219, 160, 252, 245, 170, 104, 163, 6, 200, 103, 164, 16, 62, 211, 89, 125, 254, 49, 12, 64, 24, 139, 34, 88, 54, 65, 84, 173, 82, 114, 24, 118, 150, 178, 136, 212, 111, 234, 169, 23, 28, 18, 201, 156, 63, 208, 223, 147, 25, 3, 7, 195, 63, 145, 209, 248, 125, 23, 173, 215, 13, 0, 48, 195, 77, 235, 204, 238, 85, 250, 32, 167, 73, 94, 154, 132, 208, 219, 171, 242, 104, 215, 146, 91, 252]), Integer(-9199529737147709059))]))), (DatumHash(f033e4f6e37ed83b3145d1d01525488437d7ca41bbe52a39aab31a97f1224e43), Datum(Integer(-593552128947493946))), (DatumHash(e8aca7e61f69e1260d8d8e0cb8b6ca34b2b6a11a26f22f69e88bbcf644fb08b4), Datum(Constr(4088868737, [Integer(4177234764228082000), Integer(3603356264052409860), Integer(8465656476941222898), Bytes([202, 93, 174, 183, 221, 67, 107, 168, 93, 30, 39, 68, 104, 207, 226, 0, 230, 8, 86, 190, 251, 78, 138, 209, 6, 212, 115, 70]), Integer(-17617145114892162587)]))), (DatumHash(d3da487bca94b2ae59991c9704d0a3d381b88531125c0f9ee4dc13a0e0061067), Datum(List([Bytes([186, 52, 194, 43, 73, 74, 176, 184, 214, 121, 67, 158, 62, 120, 30, 157, 180, 112, 132, 250, 216, 165, 198, 213, 253, 98, 230, 17, 32, 53, 165, 193]), Bytes([148, 34, 172, 191, 198, 193, 41, 148, 30, 153, 51, 181, 164, 64, 122, 165, 155, 71, 126, 89, 76, 81, 248, 225, 168, 50, 118, 52, 67, 34, 147, 134, 165, 234, 234, 147, 202, 6, 209, 137, 34, 136, 11, 10, 203, 12, 7, 128, 15, 136, 64, 4, 45, 8, 82, 239, 86, 206, 119, 96, 89, 163]), Bytes([]), Bytes([146, 61, 87, 35, 59, 214, 192, 241, 62, 172, 13, 232, 50, 195, 214, 253, 2, 218, 189, 136, 143, 1, 21, 241, 175, 218, 119, 49, 125, 166, 227, 48, 202, 165, 176, 149, 43, 154, 2, 125, 194, 198, 90, 147, 21, 140, 237, 246, 227]), Integer(9971176567098175649)]))), (DatumHash(c61c8ce968a5382e749189706386376dd97818d9ec3e59123fbf224fb282605f), Datum(Bytes([107, 27, 72, 2, 106, 154, 29, 15, 2, 16, 140, 88, 37, 220, 111, 108, 172, 80, 114, 175, 140, 140]))), (DatumHash(0d7e84d00ba68cb161e724f157f15b429995bc6bec06219abb6ebb0e05321182), Datum(List([Integer(16237504671388057912), Integer(-16285226431970625050), Bytes([247, 109, 75, 197, 44, 133, 186, 4, 72, 71, 51, 193, 0, 113, 147]), Integer(-10372740837566876008), Integer(11123773230320431390)]))), (DatumHash(598bf36b92c1b696f4edeca936c026ea54fcedc4a9255c78794fec17379be8c8), Datum(Integer(13795168235298107099))), (DatumHash(49624a0f85084a48045f84298a6addfdfa6479473e82f77e4ade173f07a4d772), Datum(List([Bytes([71, 229, 111, 177, 61, 96, 150, 100, 214, 56, 249, 163, 231, 18, 20, 0, 217, 46, 148, 214, 164, 155, 11, 75, 184, 34, 147, 94, 115, 69, 195, 23, 213, 203, 128, 138, 238, 122, 53, 173, 210, 12, 74, 94, 43, 183, 228, 164, 95, 18, 159, 11, 131, 5, 119, 178, 85, 181, 88, 168, 61, 102]), Integer(14293894423366455123), Integer(1221696318822708709), Integer(-12695428866911314187), Bytes([37, 105])]))), (DatumHash(61284967c2a9fa4e359cf84d716a443fa4a1e6deff58a59548aa74c89cd90b88), Datum(Integer(6734396926988172344)))]), id: TransactionHash(17b27f69606574edea9d5a1f15e8c9abd732c7e2fd2f123a654b341d88b08e12) } -cc 6754dc117f31dda503b9cea982aad28214fd39069e2a35e276e7a80693b5a7ac # shrinks to val = ScriptContext { tx_info: TransactionInfo { inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(00000000000000000000000011d5322bb28add0c541afac5f59c2415cd39baea), index: 1172339953 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a1321bc06e424938c7e5a3db667a16cde2f7d4145662c8a8cbcc7eae))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(132492f5ef8c29cafeaed2adfe4abb1009c40bc2bd1d0cb7fbc73482))): {TokenName(0563cf40cc97ba5f6e71e11188fa463b3caf052a5f888afdbddd0231e05890e9): 4267529379, TokenName(319d34aaef3166fc693e7da784a17b3a380ec8413adf4a053a89fbdbfa8c8688): 3022272300, TokenName(5d1f501fdbb8e2b043051a37bf3e6f4462f58ea3459b168e06566d7a223b4964): 1472647335, TokenName(7c780c5081be1ee268e5a8983b2093b50a6d68188442c6cda8f35a61babf8f7c): 1407873443, TokenName(8a318158cd161fb7a25a338c20423bc2b7f3fd53b7b2349a64c36efd87965592): 2983736929}, NativeToken(MintingPolicyHash(ScriptHash(4601585ff8414333098dd5c528dd7164188ef66b73e7a50b5403f7d4))): {TokenName(21503d22ee6638c1b9f86d9f216749cfcdd7b9c3f05cd63b3735bafc99d56e35): 268819850, TokenName(690a9d25e0ce3f8c96977cb27c91255e5c8251779a9cb890ec23d6b56df5ccbe): 2049992157, TokenName(bfb672e721a9bb93772abd070b280a57033d1217ea7e7f82fcb6c84b194b4513): 314390417, TokenName(d10cd94de9a3b91a3d0b156a0f8b656c0f0133d0fef376dbe85ee1247cb47ad8): 1019985646, TokenName(f76c898e35e477b7d4f658dd21e4aa3b7d99b9911f53134287474293c1ad5c48): 1337489045}, NativeToken(MintingPolicyHash(ScriptHash(4f9ee1cbdc2abd45e53841e9bc178930148d637edc244f19827d1b82))): {TokenName(4dc84a6f8f1db80a1f074b07adcc80f559465cff416470ab6095b767de801458): 226509656, TokenName(b665e1f8a1bd6c867aa6868bda6b66739b2c4ad97130e7d85167b92933e612e5): 3081002613, TokenName(d23696e1a682f98fd0fc046476049f42f89d5cc24835b0784b7100254c818ee5): 1540836842, TokenName(d3f3a02c9e046d64f19caa44f964f0d043ff655fdbae0dcef4ef2ca6279d1da9): 857302425, TokenName(e237c96477dcf222829b69dab4d3bbdde33abc18bfb9d43f995a28a085a11600): 4025060393}, NativeToken(MintingPolicyHash(ScriptHash(ca7fd51fbe9bb1cb116145a4f2870bbc022b6bd0ff423a099b159b51))): {TokenName(23708eae008cf5a8c0f80de6e7a234f5da2a7bd70e77dd982b9fffa737931e48): 2826237570, TokenName(3c39631b60c542bfed5c5aa3810a46ce8a16a7bcdbf85ffef02f82a610a8e0b7): 4034833149, TokenName(45e3651220d382bbaacc96a1fb53ada50353788b1455514b3a81017c1564357f): 334707204, TokenName(e76929505adeb664e97b73280866c39e6d7a7375f3d2c07db9e29b2aaa1a64a9): 4267139948, TokenName(f43d5d1b593a13cbadbbf2ff662ac97c07ff7b612a4dfac10780490fe5c77eb4): 2861426176}, NativeToken(MintingPolicyHash(ScriptHash(ccb13a35f256b140e44c02b4af30764b1d12c57a7043cb1fb326f377))): {TokenName(44843230b3fcfbc9f25a9ace669fb0a80d65cb45e0900c346bb8dd464c1e2c24): 3886874923, TokenName(59c78285a99d5f06d60e33913bb25499e7f191da5e7e5fe0c19b34e0c4b8de24): 2372979482, TokenName(6ac148aece10f6c09c683719fcda91b2d1a5fef071693fc176df2942bfee6afd): 2142107358, TokenName(b58cd5725e4b0bb298802dbe2b7a6f294bf4e771f6f23e584487b792cf859c67): 1813112534, TokenName(f1af2ca64c1aeba2037fefb1eabc8c385da50cda787395ad88102ab05287f69d): 1241001126}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(2b07b7877a2b46bc4579ec595aefd73b398b1bf1129edabab45f9dae2958d81f), index: 1243967587 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(11c5699e46aa23a4bdbb1521e5ef13f0af4cbd8ccbbe11a7197d55f9)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(1728648231), transaction_index: TransactionIndex(3590170767), certificate_index: CertificateIndex(4283880003) })) }, value: Value({Ada: {TokenName(): 7748603629653168127}, NativeToken(MintingPolicyHash(ScriptHash(0c02e4d718f96291697fb0bd36769f5cd5b37bd67d1bd272343e9fe2))): {TokenName(5c72315a5de9bc63bcadb6dbec2af6d5dd22e67ae080a75b692cb650dab05166): 1927482761, TokenName(8099c9a487bdf002ee3137cfa733edd6244225c73eb0da98e404fe2d472ef4cf): 3185204016, TokenName(8d1d8eb3f49354015db84c27b0dde13c4e35494c822ad72ef79b81061322c556): 148143710, TokenName(91e2210236086e3326cebbca8e3113d4b2245c9d596cd38d05fe5a4b537fb3c1): 3953111174, TokenName(e8c032c78e4cc50fef69f11cff90ea4d005acbdffc12a8d4532858dba1e43264): 2028865169}, NativeToken(MintingPolicyHash(ScriptHash(280be125df57f2457a23dcf6051c2f9d7a808a4525cd863a3da33627))): {TokenName(189e7dc25d4453ae7fe26c665e2678ba87e01e8edb4a468006ccc4f201571a9e): 4185894986, TokenName(2d08b6a48320fd20d083e3e2d5bbb552c6190990b112c51f72a53ba50416e1ec): 3575835787, TokenName(4784527077bf4fae44b72289d7f386ebfc85a7027e666e343fb77fe30f9ee062): 1633553840, TokenName(5afb59bda895da2ede5739ae3cdc8a3822763fb69b01c00e5e1508c15cab8ea5): 490427526, TokenName(bfd5ab94d71e159d4b1f8e0100285868d4db2ae35478776e7a6cec74bbff5758): 2797161448}, NativeToken(MintingPolicyHash(ScriptHash(4ccbe3c3b80623782fa30aa49abc0b5d90810fa18f997f183fd745e2))): {TokenName(23222734017052d6945e2e56deb35b2b1e7586a7d98c4a4645bdac533dcf5f51): 1708191530, TokenName(423583311cc5510ee57122a1153d6215049a53819927d9f5e5202b00d6eb36a0): 4210856024, TokenName(5c002dba64cb8afc8c7ea7533ece13c195d029ed9dd664c85559f0674407d920): 1179183873, TokenName(7e590fa6de16d366094f4091043d7d118ebf719fac24313646eee33aef392089): 2073268386, TokenName(d7f83d86e2b4c8ecdd3b4ef5876cb2802e6100cf1d09963bbdec106dffeda8cc): 927853813}, NativeToken(MintingPolicyHash(ScriptHash(7cd50420383651da418a92da5c91d727e31bc34c07ac3d22995435d4))): {TokenName(0b059a492843318861b9a242173695674ee3730818031d31e9393b6725aac77b): 2317693307, TokenName(4547699b8126d931915793b4bd95852b6de579bbefbae3e88a1531fce25fcee0): 583744481, TokenName(5e61db5b1a03c309654f1a4d9bd65477011aea838970b1150b8b18262f02ba49): 290296387, TokenName(9b6b72305e7fbd0c3ed605e23e474991582e70f63878e53b4e9c869b040f5f5b): 1480523016, TokenName(c83fb9d4f892e8261037fc7054011a0b5a374a23d488d535dd49b108eb191442): 736650869}, NativeToken(MintingPolicyHash(ScriptHash(8d673ba1a215d046ea7bba4d80257f6499134acf667d658633f276d4))): {TokenName(02ca529425c42b3e95e4f42e49d16bcc6021554d7400ce4ae7dda185991994a9): 748377391, TokenName(5f82bccb82a27e6566ec1011b5035ea3655295c2be1e9fc0c40829b731c8c961): 2438112588, TokenName(7c27a2a9d896ac4d4b4fc1c80a15311a430de3b5b37a3fc7f3b3a7cdd861334e): 733744395, TokenName(91fbe467bc389da8540eefd9aa06340927a19a56d727b0fbffaa47accc8d614c): 2138315087, TokenName(dc2268f072bda291c348b91fc1ffaa9821e2c848662b239319a636ec39471579): 3177580649}}), datum: InlineDatum(Datum(Integer(15075788117240937958))), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(603d1fdf0eb705103314a22989c4e5eb73ba742026913342c41ed86d2fdf3660), index: 2051295606 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a4216e25edb29e77a8d0aad24d129def1842d9579c9d4e3f682dc55c))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(ea7b33747144d1d7d13aa14f7df6697eabaec5fad6ac2161f0693214)))) }, value: Value({Ada: {TokenName(): 8925537596683938766}, NativeToken(MintingPolicyHash(ScriptHash(29093716b5f94efe6dc0d363eeb0597e465edaf28e3d6ab44147944d))): {TokenName(1981ac8871574081e37734e62f42d59e5694a149d3e1a8a39954f0b9fe2b591f): 2432836977, TokenName(4acd5d154c2ab392c1710859c193efcdeb9a4535cbc8e0dcd046b640d4eb7552): 902076967, TokenName(753bd5b750c94c9f6ce5f8a3ddae424f72936cda90ac9aab4b38b95f5e714cbd): 332318396, TokenName(9a9e5e9f0223500222f9b75d0ffb77d2ce7531291c845e8bb6689de491d692d5): 340392667, TokenName(9b686d2e05165f022cba64fadf1088914bb366a507ab213c8c3ddaf7ee7a46c1): 3685600604}, NativeToken(MintingPolicyHash(ScriptHash(4d626f6a9399c5bfa902fff30c083c3fab316fb674ceb3cadf2ec9b1))): {TokenName(74e5f89afcc7d5991f383af40c46ac32834030978c0189980e190c6bc61927eb): 2660653260, TokenName(7d85353bbb7de907ea35ceaa7d1059e9673af6e70cf03b7795d35f64b8d989f9): 4038719552, TokenName(9aa7e1d8519ea3ba3080f75482fcced303c43a06ddb5fc86cf1a1d61ee9647a3): 3376008048, TokenName(c9d0f508f235c15477ed3b0541c7df528d194c81e691322502c80bbce3e72b93): 2552040617, TokenName(f45c9fd4835fb6862c993e732af56ce86f6f80fe52d87ad2b34ca87c33ddda5f): 93882121}, NativeToken(MintingPolicyHash(ScriptHash(83af1664cf3e4ffa798d43afbdb681e14bb316513ded6f041717ffe4))): {TokenName(0c8d91e2eba3751e7448c2993f15d727f9be1f1a761ad02e14fb0ce89f78feb7): 1580835092, TokenName(1c6ae29f6ce2d7da849da44b7a726196e68095729ef6b4d8c7c0eb361747a31f): 3375235636, TokenName(cee109e119cdb548e08d433d900d28dd53402b097cb2e2b2660da4d1def1d60d): 4128095315, TokenName(d05c690fae152227daf62a7798b42688152838022e541483ecd9c035c3e0b98e): 214072117, TokenName(f47aa961eb58d8500069e96172432cd06e985d50abf1d5cbd1ffc7f4b76b5d4d): 4115183080}, NativeToken(MintingPolicyHash(ScriptHash(aa8ac7ac8c3301cbe6a4f79f7bdbebad4a135d9638a6a8c4fcd6a79d))): {TokenName(5462d975dc29be0ae56412567c9a4b3402cb41a8032a14226434147c5da1c03e): 2745335079, TokenName(7d663f36b92ef6ee6eb57c396344f199fe9e5de46db02fa4ac77ce3e1d861218): 2197791936, TokenName(8a7729799beb6cc12532b6354bf9bd7cb9e286c3b3fd876de4743f4d51bc9a58): 824585603, TokenName(af3af3e4808cf616c5d52524c3cb4e661c51c4ee8df6f746030e2777518cae5d): 3376409866, TokenName(ceefb226d3775a95b9ffaf22eeb5de5e07c140610d7a35c777c7d708db648999): 255007278}, NativeToken(MintingPolicyHash(ScriptHash(f251d0a77f02db88b11a55a7e28ffca19f7784971cf06bc8fb59b3b7))): {TokenName(896fc5052de9928da0dce4f9f7027c82210dff01137734a0cfbc0d68b6cd3223): 306344900, TokenName(9ac2f97ea90bd314e1f3e367ee1822b857c932254fe2e8af46ea400845bf16de): 4186517141, TokenName(ae7833ac678940e9ae4fdb023981607f48622f1887201f1ea87b218e3d4a5802): 2705283853, TokenName(b72b9e7d554c3bc5f31594c249d56eec8b49bbf65cdfbe1dc8379940a38b7a2d): 3341327994, TokenName(c91ffa8366cacc28917ed8b0b951fd276c9cb85ef3a6741b33825dda546c1c50): 4167661001}}), datum: DatumHash(DatumHash(2b4131e00a320d0725797d982946dfe0c11d9068b0825c8465712f66be2d87da)), reference_script: Some(ScriptHash(ff7e2343bfe108a8a274717bddb6bec8765505c848218d03c78f2e05)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(63e71f3ed0b72ce795acd81022fc40804542770cafac1643749ece536c82f743), index: 3473660016 }, output: TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(01519a6eaab23e224e3a730777da99c9482523f48f947e068e20d67b)), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(3c232332ad432fa3bc474d1448fc06ec13c9045582f7f1532bf65f36))): {TokenName(02ced3f4669e6f1d5de68b002773f43a303ac1f818ebf36cd4cbc6e52f5da94f): 696656815, TokenName(0c915be63ac8e42869e2266cde84695b1d3056e6c716673cb4e3f4a8f1a5b6c8): 425545477, TokenName(251f94d99daf5dd6b9cdbe7d6cdeb03319ccba15d7be17e81400304c5ad2c88c): 1797429777, TokenName(28d62192084e26396fcab568e94896c7345857172934f450539cfbd6b947733c): 836609154, TokenName(a5ce984550eb3ff4591d37fce44e3913b2187f3bb5a9a826d25ee64b1b098eb3): 3380257614}, NativeToken(MintingPolicyHash(ScriptHash(3dd797a91a6823977bff7c3cd03170d1de3348a0b210adeaa88b79d6))): {TokenName(121ffb277c0db5ec48a8eb058e0c054cd4641d75780b415ced1318886f26e35e): 4069578957, TokenName(b7cddd8baee136938f93127de502055a5bb6da34067000ff30283a94d54723a3): 203685091, TokenName(d8092b3cfdff2fe5e1e8247b794dee3b7e6cbd8c9703350792705916e19671db): 2208159976, TokenName(e81744921f1aa0f3a441c788ecce3b6204d8d37b1bc1dbd37cced02bcb0622d7): 3789726687, TokenName(f5b7a5111b8feaf9f47baa25bccda014ea60ee1678b49e61dcbdcf88857aa6f7): 2781647908}, NativeToken(MintingPolicyHash(ScriptHash(768f53818971a0ea66b0ca1dd4e29d97963dc85c778c9ec4d5fc94a2))): {TokenName(08a33ef1c5c75d2b979ededfc7898535366cc743fe6d92097bbc1ef9e304caa6): 1663049919, TokenName(0c2aed8449ab1e4e0f0acd5caa6c4f22d46192a72b013721b48d74d72c8a41ac): 2294787973, TokenName(7e5c8e73cae565519aa6c4ed9d6647a3d18e44cc8af73708847892bf0c40102d): 3966512321, TokenName(a4482d820e7f3dfb2e78c953784c3578016a5f74dc3f24b8f900df70a6a25c6f): 2867611653, TokenName(d19427fb71c83d685805532e52bf798f9d68b8887a071781dd98af27169e5a08): 3457975349}, NativeToken(MintingPolicyHash(ScriptHash(9216b26e7161977e8d6d2baa59622d4f61e6e1719181a555734a2f5f))): {TokenName(70e9a2bb2794875b847fd4692f3300c4032e4d36aaf3a0a1cb48504ec6e898c2): 2409066633, TokenName(98091904386ddc71ad16d277bf544467ffbc66ce5c0f19254cc5c401087ca94e): 2236215107, TokenName(9f931891cc743575035282022929a975b8605fbb332e927c2822efe0543eb86b): 1825752575, TokenName(c3cc1ff4a516b48eb26501c419409c253b463f5873e26a68acb688ed10729f7a): 2543388652, TokenName(e88bc3947bd1256e59ebafef62dd42cc35254e32bc6c1d8e2c1af8082515f876): 1955706972}, NativeToken(MintingPolicyHash(ScriptHash(a9b68d234435c5920f22063eeedeabb3d9cebf922f69b90fc4912103))): {TokenName(10d53d8555aa1d766af64524899283cdd58d9b2a3d0522966385131f0c79f090): 3709039757, TokenName(552164813a95fb2a807e14bfcde12d897eba1888cce42fc506b66d6ce2e27aaf): 2570348155, TokenName(e6b46e5ae30378002de0f194a4d6e12dc2974e2cf825765b5c029b79c9ce3ea7): 2735422298, TokenName(ee9457852a462c0485900378df8a82db5b9f294b90ffadcda8d3ec23175c3202): 2913431510, TokenName(fe73f1ba83f705dbfb669c68524f91a66ed434860ae9134a7eefed52605a7b8c): 3067821360}}), datum: None, reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(09cf43b747a5975081574107d549c120ac31d43b991410677847c96e37d3a33a), index: 995961261 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(2544219b3b272f8affb97453b893ce3f618054a41ea2f4698b4926a3))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2612535545), transaction_index: TransactionIndex(2837987253), certificate_index: CertificateIndex(169250896) })) }, value: Value({Ada: {TokenName(): 5785086996295989328}, NativeToken(MintingPolicyHash(ScriptHash(24d3daec3335fe935a2dab1a9f72a106b491ea9514446b6e6eda7a44))): {TokenName(261095f4c6c9a636501c1a9f286ae75dda843399ba769b11ca9eafeed99c999e): 3372569647, TokenName(396b56bae233a8791c740f10d69e169acd6db3a77357355745bf75f83f5fa6a2): 3445609636, TokenName(5fd3a4024903053bc81ebcd2572868f726650252760de89549c1dbbb48ea8ee4): 4098907285, TokenName(635afa33d221ebcd8135c51d2c6ccef517ab8a03afabca02b1b3daa2f2e40d49): 1937604927, TokenName(bf171ca9b23bbaa1789f7608a3b0822263152ad7f17004a04c4806d8f49f5574): 191326486}, NativeToken(MintingPolicyHash(ScriptHash(73a3c06e278dbff68844f15ca850c7961dd572d7cf7dd17896ff7018))): {TokenName(305a534019a8eaa982f9e48ebd7fd29832e61cee7dfc4ef484db78d7c68d5532): 738652252, TokenName(61c785b7f8c206a14dd23d6154fc0dd201df0a50a70ef286610c4d4e789f45ea): 57281176, TokenName(9fbf7f92d5eb1e7a67eaff98c0028b6bd6d66c5866f871dcc415053152200634): 4024650166, TokenName(ec23e54ce23e1c3dbbf1b09b8183ebcd8387600823f4daee6323f0443373f2f5): 3484556259, TokenName(fb5c66d2dc5fcb3de669a10464d8f338e87c3f52bb92bf05bb6bb44774ff5e4c): 750166036}, NativeToken(MintingPolicyHash(ScriptHash(977b0103e7e4e19272752ce64715f8186441f6bf1f1d488a4f6e5740))): {TokenName(0a82e97549b50abdbf4d773a369231b08c1b7b6156f3c9a7f278c22585e577b8): 2913503834, TokenName(16a46677b19c6e2943c38dd581412e0f6b9b3d900dce33faea712a6dfb427776): 3758849122, TokenName(d0603db40b588c5f3859ea5928924537869d1963394f0aa63acda40143850d5e): 663744825, TokenName(df0364ce03c1c98d81a39ba2d3ea20ed7c95ad96532460d5a98fda854d7a6adc): 753062651, TokenName(e784df7764e83764422618a1392e20471d6ccc29a2ecf52cf5bd7caa0a6b75e4): 2955831740}, NativeToken(MintingPolicyHash(ScriptHash(ec5517e94a51a1578d4210c84c9ccb6aad4d9787e320a24942c33546))): {TokenName(0964c4d537213556c3b48d1ef2959908da834856189b4a396053d6722534bf30): 1476539119, TokenName(70780e606c49e25c446f369684747ef0d741d1f4ed0a147f7011505c842221ca): 3018400531, TokenName(a097f076c4d43992236e75e78a33ca6739151a846c903b7cf6436ec021255e66): 3888307119, TokenName(ce883d696c8db1229ae4ebcbc0e470407cddcc736bf7cf58827a8ae9e16755b6): 4070548983, TokenName(e3bb6f9753811c1d98c82c4a145c31a16204900cf53f4e6790edd6273c82d66a): 1174691894}, NativeToken(MintingPolicyHash(ScriptHash(f4ccbd6a6de163cddf206c16ef35b190f380459a63952d1b1895dd6f))): {TokenName(05c0f563fdb2515ff573c60a8388d47433a14e2e40ecce72ea238f82725c8170): 2294748904, TokenName(19828d0731bc0fb884b6085a14e70867dcbdb58a0e0ef0cd190bfd64ade91564): 4125510808, TokenName(3917ee9c0502cddb3cb8eb5f664b3cfe4f831a77c7ce23bc434a2017576d210e): 795989689, TokenName(7bb9055244ee6059f459922e9697febb411efa46aa7f02aaf04c8b67acb87751): 179016285, TokenName(94710aab52e891351cb3215b1190357af69efb64fa68dd3ed0fec2f8af5e124e): 627950714}}), datum: None, reference_script: Some(ScriptHash(19d34805b0db537602cd9e61601b0ee891803db283a88cab71641068)) } }], reference_inputs: [TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(646c5ab020b4e0bdba45dc39270c69c1578f6275aac4e5c7d2e1994a1d4a9ae7), index: 2130406616 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(96100aa59444a37b9fbd6f905c83b4ccfbb6756361795d7079ef9b0d))), staking_credential: Some(Hash(PubKey(Ed25519PubKeyHash(974ba2cbbc09ef5d0edfc553b9e1d714cf5c490f3b30e6634da4e4c5)))) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2025c1c32ec8e186d74a28f893fc84914b6f889bdd159d3c3e4294e4))): {TokenName(30bc58ed8dc6e5d1239e196ef0333a1cf8734bf2719f25e210f2b581c17c283d): 3138538209, TokenName(8b6543496f447f20a4412270f317dc35524ee3eba336add3bad964ee1fd5973b): 4097751066, TokenName(b8a6fae91dae37a54c5f1f2748d1702f1829aad1af6ccefcfa9be575386ad69d): 1698135801, TokenName(d1ece0fd967fb550c45ad773ab9216f074f2290ae8d861aa334aadd8a83e3e43): 2379338132, TokenName(eeb7979e4f9a0fe0ddb6ddd99f02bba8f369d2deeabcd634d8b3bd0d17762e1f): 1144425251}, NativeToken(MintingPolicyHash(ScriptHash(96431eb431dc160ce8528c595b8527fd37d8623a658ff5b4e2910310))): {TokenName(187400bfe405947a0c85026af447540639c896f98168f1b2a321bf70767329f9): 780087136, TokenName(229866110b973a27788d02e04c82facaeef7f3baf3d10304820fb7c3f7162e6f): 3698607039, TokenName(26287b743dcebe10d2c79b2de972a578ec4f114be1824f3286a202ab779c599a): 3551441967, TokenName(b7e5afa79a5c6d138357f37f4a7d2aa891399a6aac98aa6ad53c547de534c69d): 188390724, TokenName(fd7481e9c7e26d8ced3941a1bc9e5aebeec9a1cb544fdf950f00f88bccf8e6ab): 1096813748}, NativeToken(MintingPolicyHash(ScriptHash(b8ceab26b6ec226c0a59e3253ac1983a0ae723b4b05d4b664adbd75f))): {TokenName(8b0e37aaa16b68908baec30d4ef4f15cbad1552e8a7af5de7d490f26ec221ee2): 2958418805, TokenName(acead95d21b48bd1bd984290391d9ade32cac36cca9b20b6d99f85069698b735): 764473882, TokenName(cb1bc51b825125e32fce52e5df29589e45d9d3a75bfbdd35ba7517d1c66dca2c): 158222626, TokenName(cbe38044887af69a5eb7a3d6d8de642a6bad8c7dd94b51f4d2d7dde9a098728e): 733176453, TokenName(de2616b83869ddfe31d427a7bd915e6bb481f9602e4deec63367246536b6d170): 4096836745}, NativeToken(MintingPolicyHash(ScriptHash(bb8a610ddbd715ba31202d918f194b8a91be206d9eedd8895a20cc2b))): {TokenName(6c9323150bc643e37322e95d33a8a14f429f75b8c7c62434e2d976e626ff3ad8): 72174935, TokenName(78d6fee92717c0d497933bab0ff3e8e24e420ffdb1ea1cd1db1f1080d77687fa): 3839528739, TokenName(ce0a9672afbff271b9a6c717d7dabb85cd0a280aedbf8f9708205b087a510a3e): 190791990, TokenName(ced17423c8acb2ca8138307e51d3d87626a6f37412e1c1f28079b542c324a9f5): 3341648181, TokenName(f61de49e729b1fef2493ecc84890474faddd1ac67d75588ca2d7e8b3e1c632fd): 3007165824}, NativeToken(MintingPolicyHash(ScriptHash(e4294bbaca3f5fd9c0d411d58dcf0727c1fa9b2fc2599cfa762dc10b))): {TokenName(05e1943ea4866dd92d18ccc944b702d14b8b9fc54433301314bf79ab6b189c7b): 3287269245, TokenName(654fed4b393e723741eac2833f6308f46ef79a23ed0d4634b1728ec047b2929b): 2637736497, TokenName(6decce0caacba946cf43c83beb736f44ce8845049af156cc8acd7d9ac3b8099a): 1185579404, TokenName(e14f8585ad69f0bcb39a99891a7b0127158317343627765717aac9b109f10e72): 3437265369, TokenName(f9bdc38e8c0b819272e5cf00769d0bc5f968a0ead94c046f03f6818a2763ccd3): 776023997}}), datum: InlineDatum(Datum(Bytes([144, 173, 223, 201, 140, 121, 148, 204, 192]))), reference_script: Some(ScriptHash(94007b6185b7346bc984bd7ad95afcfc40d40f1553912a99dda88794)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(b6b64499eca0629b83b141ff8928ea942f12f43b3499dd22cee3ec324b085075), index: 3829671490 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(e26318be52d90808041b52c61dea2742f853bf5256f8efda5deba934))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(870375327), transaction_index: TransactionIndex(1246192293), certificate_index: CertificateIndex(2668375927) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(2d29d583a565a7c5664554ae73786ecc852b3705834a56207904b9b5))): {TokenName(1606f7628e7732dd5ae6464621e4e1455a97c7a4f4a7cc0286b6943be5915a24): 1832724581, TokenName(88c34e27758409463f67122289d19abb38829c0e30c7ff737b56817c097bb4f0): 518606772, TokenName(d74c5e3c383a4fbacc69ae35e824d49f7dea29b8763ce837eec4d8fce13864f5): 3713597674, TokenName(e069beba1b8c7ca90e7c2cc24c3d2baaa0d7345fe017225ee751ca5cc04e4677): 247823558, TokenName(ec6b9e4701fb6cd7788cdc49eb506ac29875a4edb19e2662a95d0f3d6f02588c): 3728361650}, NativeToken(MintingPolicyHash(ScriptHash(419e1f3287f74a6ecd6b7dda0dc332fb85c4b2b9a21965073b9ae8ee))): {TokenName(186e64b3bf7f12983292b62c47651d7f609b11c461a370d8a907e6e83e73ce1f): 3809259102, TokenName(3c89442f9a1013a06894baf60361a50cec905c672f4e8ddfa0bfd2e6f7852efa): 2030150634, TokenName(cc5e1525f397c479665ceb6dba4f19fea7bf8738a56308dc8e045f8d68b42910): 2779674349, TokenName(eb58bf23499953ed40fe55dfadc766b5e87c04fae463b0a05871ded80a89a4a8): 2622975792, TokenName(fcd607e5f4333727b779480f9e95b9d7cbed1fda1fc20ecdc219bd9c2ffa8792): 2991420154}, NativeToken(MintingPolicyHash(ScriptHash(90ce09cac5a7c5999221bc657e06a3f5d0e62ce0d33878d2e41dbce8))): {TokenName(9acf4262141f5acb8e98de1ec52bfedeaabf2b18c48264fe823adbf57cc29603): 1924413208, TokenName(a4802f086ebf26a2b4e3d16bfc04729cb8ed709c29451e8654fe5c969f249852): 3388478348, TokenName(c1434306da913ffa233a5b2006ff00de3c6483f591da63fa8cd61dfaa4759f94): 3354611819, TokenName(f28be7ddd7371e33148cc070296929277679733fc5af5feac2841662434d259b): 2551327226, TokenName(f707345ed60c0fc657fb699f7528a5d77456161f2aab5873f984421505869d81): 4187154854}, NativeToken(MintingPolicyHash(ScriptHash(95cd10afb254ea65079c3843e18cb313399b126dd042bddc38e86fca))): {TokenName(2c025ca7026d843a87832fb56a0d95c3d2b629d10eae2b287fbf2a57ebe01bad): 99849342, TokenName(97a30ebf70e75b14edf59bda226ad48a236a97a526f53a45c4241eaeb09cb216): 1440733641, TokenName(a68840161fd5d25b87a703b724d6ee62eabe573d16ddef143ce434994bcfe7be): 1525056038, TokenName(aa740250918bb880ea544664c1513ac01431f3fe698237bdd87556a0a3570e44): 3675185957, TokenName(f29b9b52614134f76b39468df80c6c6767ac0289c5b21ddea01222935793f946): 2328116611}, NativeToken(MintingPolicyHash(ScriptHash(9751742fc2515edde873bd9dc4709ffac7e44afc6311899d7b120fe8))): {TokenName(3a305ba2e185dfbe658bece2bf4309d98a27150cb911daac96dbcb3c88825579): 2013425254, TokenName(5e3cea53b9975b1540fa5e97e1a4cb8d47286febc4e37e418874ee00317fd42b): 1430243102, TokenName(b97cd54dbdd4f5339146bb7c12f86233097539fe99437d3e7a132608a89f6686): 3640949646, TokenName(ccd68210c540d2e70b1b3b8ddb3da71afbc3d84c80b80f19fea307270bf91ca5): 3085066512, TokenName(dbe81cf006fdca9a3b4f1126fc829e46f0f0b3851443bdde4a6d8e2263337920): 1798570448}}), datum: DatumHash(DatumHash(6ce0fe1ddd86f2210d67b6768c34f26aa206ac0c7fe63cc045b4fb87f3d6da08)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(1a8628cb331c8ed648bee37951f17a2a4ff16ead08d374387745957df684d510), index: 1909219806 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(bc17ab562fb24627336dccc799e7bc3a138ed82f77b7fd0279dd9b96))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(761437903), transaction_index: TransactionIndex(1679473444), certificate_index: CertificateIndex(957930270) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0ae3735fe68192459d4b2ef8ae30ca9560528b586fa40b95008f9219))): {TokenName(1b48b00ea46a5ce95a01c4fb95874c6a1a4c180769069bbafec6bd42d9e9584b): 1271347592, TokenName(3121d8b957fa7c96206960b7b84c589d60f02e5581bfcdd1d8c9657ca3e51178): 1716028803, TokenName(487cd18ea350068bea61713d305c27effc6e05e1247b59ffafd2f8d130ddcb06): 1980622124, TokenName(5eb9f51b040f78203f5c185c46bed5a499ea00e3808614c4573fe9ca9e8a29fb): 3367802477, TokenName(f7c612d491d33a4c3d6fef580134e5a4c599305bb08b295c924a3880e065d67e): 507756363}, NativeToken(MintingPolicyHash(ScriptHash(695a8c13b8152b5ea46cd7c9f1d0daf2e4311286ccb26b5b8af50e1a))): {TokenName(1f282df05100229503c87c1b6f001c7aafcc823231d81b1ddcb36746b20af82d): 3786938144, TokenName(873128617bfbd595e0a784929f6dd84b6bd28908df6fd3339c7948788c3cf7f4): 4262995817, TokenName(b9569b2eb0974527f78eed65cb4a329a6c1f4f80469fcc422737c71f466e0984): 1292462706, TokenName(d066788b9cbf13df2897e6d918fd506016c0fb96c8be194fb1673bb313f10496): 2349739461, TokenName(d12bd2164a090ccac674be88b6d9d5ed89292773f0caddf134463787d4e58221): 2541659157}, NativeToken(MintingPolicyHash(ScriptHash(8e4f4fe9648492f0360f4051d94e2a92e6d75f653af78bc482c7013d))): {TokenName(0f87b3a2c1bce2f6bd26854dc946935b03adc3012ed795fc8577dddb707fd543): 3227061065, TokenName(55a2fc934fbee7247339f0c52a1e1ce7faed6d4e13d03337b449467982dc9216): 483049655, TokenName(6222702ef60fb8506ff5d1787203b0c6472ccb98f4d561ea4ddcce01297a7cfe): 1725796137, TokenName(dcfaee0cc3f32cffdd57d822861179574880de2f6e2dc58c0ab0b5704cd4dc34): 3670968241, TokenName(e61632ca43edeab1bbfe8562d31889b65044fb6b79f6a83e7f35c4b9b378065e): 3962241471}, NativeToken(MintingPolicyHash(ScriptHash(a37934a127d3e87ff3c99fbb1137c9c8e9ede17817fc2cfe4e636bda))): {TokenName(8cca9cff66be72436b1a33c005cea8b5e09af05a68ee1486155dc36ea8dbf89d): 1332569697, TokenName(a20ae21714fb6005c71a6da893f6e0ba7742428708a383f920014e87af72d865): 3704577329, TokenName(b8373ec1f3bafde0c5a901a2021aa868d3b6d3f5a62d86e06cee54150be43a56): 2244211345, TokenName(f84082a08bdc5cc91c570a0e5122aa56c81a2c9f875f42f02efc99d3853b1eaa): 3317333304, TokenName(fd429f5dd49fc8d124de2be99e0c726325d3a128557619593ed3b19cf47324d5): 2247405293}, NativeToken(MintingPolicyHash(ScriptHash(b6aac5a73a52ec1eae3b182fec231e3d42397d63ab0533fda93ccbf6))): {TokenName(01859cfdd9763efb845bf2cb8838e3e0d3a54f06fce3cccfba72a10878fbe4ad): 3826300014, TokenName(59b873b6e1badb452077003bcd9c051289433db2810a40ba45ad3841bc63f23c): 2818072503, TokenName(7141ade3951c51424a1e0aa5abd99d1b46afb62658899017e1692a5712cbf7a6): 22430721, TokenName(ecafb3a36da7eb4e41fb5582be578cbb27edee114d49c5721fa96e641dd390cb): 170615864, TokenName(f0bdf9fa62e0ea72ef9ed9d2f77fccffe658dc6d14097b9fb72bf26aa3197996): 420350960}}), datum: DatumHash(DatumHash(9b40e29d7da6fb93d37c4bc8e9a0c2a0bc4414d7074b27b9af6173f586198bd7)), reference_script: None } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(83f0b03d92da9ea6aaed8b3168c6bd1a0f2d98a14e4139a5035ecf4c01749077), index: 540155390 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(1b4366c158dcb5bf5a9b416cf881327062682339bb6db13dbb35ea41))), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2067503976), transaction_index: TransactionIndex(2585448354), certificate_index: CertificateIndex(3646125818) })) }, value: Value({Ada: {TokenName(): 12552441740616864806}, NativeToken(MintingPolicyHash(ScriptHash(3d51228ed975c19514b4f11f8bcf1f803878e75ed01337c8be8bc19a))): {TokenName(35391eed4337bea447bd9ef1f525f99dc9bfa5ea0a748cb3bbfd2c9715876625): 1179301494, TokenName(3600788453825ea4304b2ddb7575d8abff9326a66f55452f3dfb4203be9e3427): 609877132, TokenName(395db378fc56d33b3e28da1f68455a82473507e7047aa3f1f6f5e25f7bf1624c): 4063400532, TokenName(bb0baec22640b1096f65430a14405fe7d100988342ed94d40b73d1a521ac356d): 2159632668, TokenName(e867990428a8f4dcb694b1479ef2b39448287af311013575e0377dbb80adc077): 183808920}, NativeToken(MintingPolicyHash(ScriptHash(49e99cd9d95cee180c7b468834e430781c0e7cabfd936d44d03b0b0f))): {TokenName(2abdae1c2337b9c1bc424986be62f52267d7675ecc260fcb8e6f459673737b1d): 3155480505, TokenName(2c440d4964412914f032b0b32de573782682a4433180c7bb9aa3216a414e1e03): 141822420, TokenName(4720f24fa43f44926be7616861058b8e36190452a0cb158956be6908e659b3dc): 3085723435, TokenName(5a2d2f37e9a6baa7e1016c0cb1eac4f63ff5dbd57b97a0895b594c85be8760c9): 3344221632, TokenName(e67ceb5b0f0199a1f9b9d308e23c82aa2c261939e4d48aab9647ac1940ea8221): 87311652}, NativeToken(MintingPolicyHash(ScriptHash(67a17765d3a41131b81223cad0d53e560a18f58783d45997595e97b1))): {TokenName(2eb7795cd0b7e76bd99b05447bbc60da4a97d1d2a1cf762500aa9a29ad216f02): 2183399998, TokenName(33e9d80e08e035e914c82cdb8e0329be399caab7545ec96b0b3e33cb995bd75d): 1095828543, TokenName(4d4549797dd6bd2ca70832e7b70087e11d02c36bd085b79f703718cd10fb84ce): 1627164280, TokenName(9d48819ab9b6155bb41ca8c431a3ce317284b9982ea74941d77bd20e76f5a2d5): 660108007, TokenName(bdbceafa4c1a9f584a877fb01a14256f599c65e3aabeef247fc29329da931435): 1372680189}, NativeToken(MintingPolicyHash(ScriptHash(80f49de9bb420f7f65e18db26b010b18f1b391a4acd7b51701d9c389))): {TokenName(23a9b01506659529a62658bd37ba00af9244afe5675fd205e3fce00ecb1b26fc): 1479964789, TokenName(7e634331e067fa27a79a95d40b9255aec2d8107e644d72faa2db3cf1efd42c1b): 1821433452, TokenName(a30b26dca267b7e932f6131f6b8bce807eed828d4b74a08190e2739b533b3a10): 2263626605, TokenName(b753886ee2bd686df8ca7a36cab6f5a87ff3775a51421a1eb5bfc681064988c7): 1850967796, TokenName(ca3f7c8b2cd8771890fe00d3d341cb542d1cb8cdf09aee894ceefee459e73d4f): 1639961577}, NativeToken(MintingPolicyHash(ScriptHash(bdce1a0f7ad780af057293a8a64ceef56f8afbc51c01356a13974bcd))): {TokenName(0c0fccdb20591022833ca0e7708df3b0cd506a68e4b83293408bd0cec2e49d6a): 1654625365, TokenName(1cb71f74ff9debaa2251f91b962654498792947ddb105ac7e613402ec29572f7): 1271857943, TokenName(9066b032e01080776eeedc15bc2bad71f1b8a0e831d9087ea22533537730e7e7): 1269402878, TokenName(e025b7ffacd4edb007b6d8947417a539d130a5605ed13569884671248f0c69af): 3368054984, TokenName(e63c0acf468dafbae64fcdbffd6221753500b67f4df1f4042ca10a494a4b2db0): 615929597}}), datum: DatumHash(DatumHash(c8d371812b1cb8b53f974c16c45a6b9c46bcb9abdaa1e442856751a65a4a6706)), reference_script: Some(ScriptHash(c82fd2f11a9194e341c61a2ae7225ff63ffd7e630417cab5916ced87)) } }, TxInInfo { reference: TransactionInput { transaction_id: TransactionHash(c7cbef04dfc2f87d2999e1d0397f53a53027fe499a2b32edd651a6d938d6c0ae), index: 1077270253 }, output: TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(a71b65ef8c2ded85bd584a8e2b191bd63d6c60bbccf3421945eb4ecf))), staking_credential: None }, value: Value({Ada: {TokenName(): 7156803453470119240}, NativeToken(MintingPolicyHash(ScriptHash(1161b610c86c1e75edf3f0d038d405f8f59ba8eaecb23eef6fb16620))): {TokenName(98a4513639f157e409cad17ec3a235a735cb35ae4f5ff7194e3f79d667784c2f): 3163495675, TokenName(ab0752e01c794dd2287447e78a45d7e9b49f78e8c22942133a2e9f601fb01e33): 1210163815, TokenName(bcc334756c5974daebcd66b2998aee37c70a8569ca3438040c1d4a2fd249d78d): 487106306, TokenName(db15cfa89f63737abae9987d3ce7ad2ed4be9c8e9d3ce82aa2d3b5580e3329e6): 4253691530, TokenName(e9b9c4cac8fe3b45ebce38cbcfc262c63aaa02607702b2e27b5addeb3cbd0812): 2339395740}, NativeToken(MintingPolicyHash(ScriptHash(4e8fd2bb2a6dc8ab479e7c8bc1a4649375cd8127a3cd9ace7cc2497b))): {TokenName(91bfdea1dd2b9260abe7beb1e38cb66574d59e54b6985e1d01e33cf97c97a947): 916427158, TokenName(bc827ef5f962681762fa3aaa69930fbc08bf3417fe94388949dedfbb7f7ed4ec): 891234669, TokenName(e94eb3cf8e966322a3cce9c85282cf754af375ab0de6b06dc8023fb97e0572f7): 1598503206, TokenName(ee51f54f8d1510b9cd8d7c83953933158276d17207fca777ad298d178a513aca): 539141427, TokenName(fa6867c6d93307b281feb2813fe7ff70f4e8a8ef14f7199313052a8fca2e2974): 729910279}, NativeToken(MintingPolicyHash(ScriptHash(5516f34e8fb492032688a7b273a9358ec32b3cbcf48061c220cb4017))): {TokenName(4e90d7a121d81e3623bde4b482a81ae695caa5b475d505f078116c88bb44d80a): 1845425198, TokenName(626d9f52379dbacfb2d09b7a8c75313facc4e8ce2f280e1deec485adf3d7956c): 3593534598, TokenName(a4d4b930af00a6fd82868df4d51207b17e9b41343afc66ee8fb6b1e48facf1bc): 1311996403, TokenName(af74f5502ce5bb7a731903bd84c09461d8d241db6b6d7222e2c8b14a4205c465): 4208117114, TokenName(d13b4c2742b5678822bd7939b32ad4fb7ae90fceb1de1e9458df258b703f3062): 3037895863}, NativeToken(MintingPolicyHash(ScriptHash(b6d3a54f8dcf71c9f0c61322ba8d9572f1c47810881c1e87ddae3cf6))): {TokenName(161506d868904713582acc1df6b36e39fcbd19381a799e1af71ab5e688385242): 2340600922, TokenName(16edb18ed24c99ab83d90fdbfcc78a0fb0093c2b124e1c4b76db08c34d006dd3): 3502052496, TokenName(35f421d013e66786764f5945e355fcbbc7654d758e452b4b399a190c117f13b9): 71254364, TokenName(9088b8384e5e9fdfd8035f16b705db02059a79c6f6293adeb8f10b75ea40a655): 1823461577, TokenName(923e9cb3206fba7e9b02ae0f90c974b94317a650eac406cfc14ab6a811dc6b12): 1856719175}, NativeToken(MintingPolicyHash(ScriptHash(bf2a05f904d60252a7df18749b600e002df789ef486e9fdb71d0a49b))): {TokenName(31f826f150f88681e0f1c1e73c4a58663344449ec089476eb0deee5fc6e5ff26): 95503230, TokenName(4508b41507b3d60d806d62799cdfd6c79593cbfcc37e2043ed34403cd02b17fb): 1008817678, TokenName(5e01100ea0d776e9a3c473f8c816415883c3e75e84eb2e9c1cb42dbcaf524759): 1872868478, TokenName(a696e051c9382ac9eddc79815789b5e25f555337a02c4199c457080443e4aecc): 2154123498, TokenName(bafd57ff69329b22c461bc3b169d3190c149bc6dfc74886246a169ecf6e8401b): 2108335683}}), datum: DatumHash(DatumHash(14eb14d5b8bcbcacf39f126e689a849a031d34dd03d6e07ea437b0c2616f1a0d)), reference_script: Some(ScriptHash(49e78fa1de3cc9640d11c3f5f7f119126a7f927c2b55f680fe6fbfb8)) } }], outputs: [TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(ba445747b88212fb3149fd9a4e2114bb17bbac60e3e5f2cbadcfcf98)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(899768585), transaction_index: TransactionIndex(2759915814), certificate_index: CertificateIndex(4112801973) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(1bff977e7da5f5ebb1ccf27789e223aaf6ebb81c25f12be7844811b7))): {TokenName(10cf1a17450644793a81563cc2fe53bc4a01d27d1c541ba1b1c0a41b079fd5a3): 779878032, TokenName(4b87861edd9328c6726d9232dba42b7d217f84539d9a0146b576f1027ceb38b6): 3901662060, TokenName(7b6084343b304f8fa95b96f6561844a12ea60fc89704391879318be2792b6ed6): 1875546898, TokenName(7c6133c8dd0340e41ae5f0d2317497a4ac4c5d50b08a16ff3bed5f6255b7e94f): 3707629028, TokenName(83de5db633ef34e346dfb0a7c38fb28d8e6272e3718aef89d87b1dd9caab9369): 2343619670}, NativeToken(MintingPolicyHash(ScriptHash(24d043b2017560d073f421021cecba5a0425a4ebc0efedaa6a45d454))): {TokenName(259a7e7efc7706e523bbad30e85c8dce6980c5867e169209e544ecc9cadf5fa0): 2895044326, TokenName(46a84240b4a1c6ef8721a4f763f0d9475d2d79d70f83ccdcce85ba1cba36618c): 1222114718, TokenName(db322ef98973afda5164ec3638450be5453baaae04fd5a54837654acca642f7d): 3738279108, TokenName(df0647d7590282ea27752b0434446c827380ff7791b9c1cc7a162552431d5bfa): 3147940003, TokenName(e3e53108ea87e41484bebe7ede167bfda6389b988e7182438598f162fe67dc92): 1985240142}, NativeToken(MintingPolicyHash(ScriptHash(71322fb14a67a2c0eb30db7083ffce94a516cbd67178ef81ee86ba48))): {TokenName(132f973fd88fa462fbb0569bf6356b4fb87eedd7abab1c09c6f54a6767462724): 22415309, TokenName(4f9297d598fed68e8a083cdc2814d31b1f9dd0b98fa6f096b3ebcea6c15b4755): 3055702483, TokenName(9726f3a59a7efd85f21fee20e83a8399b80133f4895cc7556efaf86e663ce3d0): 3426937370, TokenName(b00c59e99b9e18a80f477288887a30aa3fa5261f8c26ce0d7fb502642d01a572): 3636537275, TokenName(b61d1cabbc7baf1714dbff1b50d165b08638c53dee7ec98785569ce05cd7f4d3): 88385042}, NativeToken(MintingPolicyHash(ScriptHash(9698fab4dda9983aa171a07503c807c3f6c34624cc1349268dded999))): {TokenName(072355c208e4158d58a8d61ff048b4c2d90a19ff4918495add3b7f23ac187a9c): 1573299677, TokenName(1aed6b0a4fe3d21668cc913580c3e81b4695b2fb75bdb6b80cc644c475054dde): 423429763, TokenName(7ee6d0cc3cdef3c7d254caabfcb13006afa6de3d01d116cf58875d131bdd97e2): 267477376, TokenName(9092e84be17b25a85c1489943b195078d880a3515fd055be7e01c53fe491e0d3): 1698930157, TokenName(a1c5d50d8dd3be80119312674f25e57a871d9950afbb40a0f44cf7dbefb3423d): 345034190}, NativeToken(MintingPolicyHash(ScriptHash(9f4c36211c209a17f4efd9abf60646f325f8e7dcd612c25c504de62c))): {TokenName(0e95f2005fb3a217a8dd6eac3d86f98888e9e69c33ddf805e8305f02dcbf443a): 1351697681, TokenName(188d5931fcfe4e6445e7fa9caece48bc33477782ecfa5695605cba2f1f20ce1d): 1178440262, TokenName(c3c3888825b634b1607e7cbe7f861a419d2ca8ce43326fc8abc2e4f8172d39f5): 3300428800, TokenName(ca61bd29644ec9b78e2095e3293a88ec49c6b2e7ebbbc19dc3015aefbd23ff92): 289391054, TokenName(d5eda8dfbb617d151e13fe600c82ee3a0370beca4b35950982a6ae7cc3c302a1): 2203548854}}), datum: InlineDatum(Datum(Bytes([172, 204, 122, 65, 176, 130, 242, 101, 212, 76, 35, 122, 89, 174, 206, 189, 109, 183, 207, 132, 59, 71, 112, 58, 71, 137, 112, 254, 154, 221, 37, 193, 138, 1, 170, 244, 230, 10, 62, 69, 166, 159, 94, 195, 168, 210, 140, 36, 184, 208, 204, 11, 253, 18, 218, 169, 94, 94, 60, 143, 103, 51, 82, 39, 229, 172, 224, 43, 64, 4, 180, 151, 6, 160, 108, 129, 229, 1, 45, 59, 85, 250, 215, 25, 5, 85, 56, 226, 150, 85, 216, 42, 152, 28, 68, 213]))), reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(bdbfa23d8deefb93ffa4bf890462dbd7616b99aa2680ab1672241099))), staking_credential: None }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(31619c614acc3222f75219a01ab74b3cd9708b00f62bf520b041e225))): {TokenName(678f3c6ac8db8612e9d73f057f4515ca08f7e404fa0cbcfb71bd649fb0980d09): 3589168136, TokenName(91c84501f96205bdf4b6aca99d7d2f5c709aa014800e20006a21a5cf9c59b92a): 759784216, TokenName(bae7c0271cd70340268dfabb18d6f54913d985bea566066eedcd7707d1bdc6c8): 3929250270, TokenName(c6af7d45c3b984df6b0757022f8861b152299af8d4d38bdf298b4f601cea8b58): 1029156462, TokenName(fa9bfe0586b8880408a0af9b05b40f123290a085acffcd04d81c3b21534a0e65): 2698477718}, NativeToken(MintingPolicyHash(ScriptHash(4a2c57b3c17580c1d723f832ccfc0241176153ba975e85610913a300))): {TokenName(1d2d2d7d5168c9997d4b9d4329a2dc94d47d12ebced35b3d36a06131b4fe92ad): 802237653, TokenName(200fa9f4ef1d7dc517f0403f54ebff78e8f1869a69580ed006b59555e561c838): 2312135985, TokenName(6f41355034af0ed50f3a4025f34c3899610f3c61fd6203e361cc6cd50003b20f): 569937628, TokenName(ddb162c84740652400857a798b265db775e8dbf8292ea4e046689d3a7906f898): 1871747574, TokenName(e11640b32d4d9056476747d0bb7e66b1ad3aebf591028fbf43a12f984221759a): 1080171958}, NativeToken(MintingPolicyHash(ScriptHash(640fed20ef8924e123f322e14333c773c7f1b87c6a5708fcedeb1a79))): {TokenName(1ed1e9839d58ecc982023381f05339b42dc26a5a98cb9c0c3d108436328a1ec6): 4109321831, TokenName(285cdaa0fb44838fe4c27185e29a855b17f895bdc044b73d980c39fd5289ba9a): 1479211059, TokenName(4000b3e6566ebfdcbde1f74c603feff94d530bff71a291655311580caa81706d): 1971840017, TokenName(9b95a24a591bc88f3d223c228d716148e8fc19029ab41e65de58dfa912d09c30): 744486814, TokenName(f5c3d8e8a58bbe712cbb355b0e043aee752d7fe2bea523f1cad591dc60f09017): 2299665746}, NativeToken(MintingPolicyHash(ScriptHash(69f1d75647d26ff61a254714e978d787b753c9a7db7588443090eaca))): {TokenName(5b27a5e9b66f913386a3872645aec1e61d5541124301c55c19fd3c77d4046b4a): 1010087636, TokenName(908b399df3fa67379d20a785d7377809c503cfbb186022c52e8c50c2a550e78b): 1071051906, TokenName(9e2022e53b37914365c63da9f80f65e4021f30476e0d2732301af3f97a10ef42): 1959909187, TokenName(b6941e9be539426bfee82fff33c3c712ddbc3adc1443dde8ffdd19affab04f54): 2115767810, TokenName(b7fc7f881762a1449ebe331d17fa1b5f1ebfbc59ebac954698e26ae22f418543): 1344923748}, NativeToken(MintingPolicyHash(ScriptHash(cdb588931bb9cf54a180db3b6f4c3f2a421107afe0a387fb7ad733eb))): {TokenName(073e40ae288ca3dca695d8a1d67f90cd144aaa66d9c70750f31db0730abb4b72): 720007408, TokenName(106ec0a096501f488e0971ccd91a10e82c6ec3d825ad717cbeb80d40103132b8): 1978215740, TokenName(8143fbd0788dfe619e0c6ad0fcb20b37af6db08f762afe0612129bb6edc86737): 2023491291, TokenName(94624006be92dcd0c635049f31e965dee7884809da7b283f6ebce1251452973d): 2458305516, TokenName(d2485a5e03eabc36abb9f53605c126743f0e1f93ce238c5d02a6515962eb9498): 2130436929}}), datum: DatumHash(DatumHash(30baf44468c67d2ca8c71cdca08e011c5198f3ed6dfa5f32230106fc689b8730)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(e6bac9a34c5d8e1d87f4de324bd290972466b8dfc37cb993cfe4994e)), staking_credential: None }, value: Value({Ada: {TokenName(): 2345619003581031683}, NativeToken(MintingPolicyHash(ScriptHash(691cf06acd0567c9e228a3e5464163b72cf74df61b3854be97fa4a4f))): {TokenName(3ba833e2f71598e57b6b3e56680d073f4d202ead017e4c957ba263f808e19175): 982856673, TokenName(4b5d85d9a851ba616ae76c36fb7a9b8767d90dca49997135e3c7a7553391448d): 2722557260, TokenName(e9beeaac7ecd8154d4556eab163516d2f23f6b14f1b0df35b3991becd729c8d0): 2236608870, TokenName(ea139e8a13a72295e43c47471b90bc1c60c36e1e395fd7fe291899f5d9f839c1): 2111553428, TokenName(f133ec5ce25e504fbea1b5f07eb81830b6aa51ef0a444a7c66826e445d270067): 567966558}, NativeToken(MintingPolicyHash(ScriptHash(6d6bdc127e5a142df4164a58634ed279ee23c7dfc4d1890e01f710c7))): {TokenName(120399209c28732de97fca2258f0a5882ab7a43e4908c6d90200c020ac475654): 2232606251, TokenName(1c016c718141e3e32287e07e21006b28b198f4209da3d7eb9e5df107ab6b935a): 1783983425, TokenName(7ba4b45f6dcf0836bcbf8c28ae5baf0ffa628feb868c080f3c6b7f8fae3ce2e7): 1880185242, TokenName(b33032b9cce3b8a353d8decebbc8b4e3098b8d7f175cf7e4caa49fc0960f8285): 2946189586, TokenName(b68f1a7ae21895c735848a47919039dac10232e7c0bad7dac31f763298cdf78d): 2148785780}, NativeToken(MintingPolicyHash(ScriptHash(95ccc105961f20b642d496575c8618ab45778aafeff72114eaca3c87))): {TokenName(19d50a0aedd0c0af9f4962fc29848afea286e8a25cf76676b72794055e5cdf24): 3486082732, TokenName(4ab6a7f6672103b16e90215284bcbc305cfa09efca1cd7d5830c85fbdb1e95f3): 3539097440, TokenName(7b7b96f68731e738219a3d4a9c06443ad74aa5bf064d682ad74f0bac2485181f): 3176132363, TokenName(cde11ab41bbd39741a04004079f2eaff3e99e2a12bd84af790a392e84aeb7541): 550985563, TokenName(f5bc1a1db541abcedf99c4ff89fda1e0c9db9006b07ab1c564969aebebd09a22): 4087481348}, NativeToken(MintingPolicyHash(ScriptHash(dac03c917ea11a9a5a2019f0ef38dc71f50ae6da4fef7ab249b59a92))): {TokenName(255915696336604e690d5cdcd5e8caefc8c2cc7ba14c4ecf90d14b27e3cfc127): 3785128112, TokenName(2cba8c1eabc7864239d980f529ade5101532ea8fe09d77203c91f61e34c5fcd7): 1135484162, TokenName(b2f11129a271944764222ccf1cc2198da61fffb57d369387682fde0f20f34879): 2814977963, TokenName(bf7e8119e2b3dec3d6cdc6b303139e166939312940949de45c5cc4371ea7a907): 1892917545, TokenName(e20e58faba49eddf0fcf29cd18de169efd245c4144d6c3f3c90d6a20901913cc): 1380583014}, NativeToken(MintingPolicyHash(ScriptHash(dc51a951d79cfe5723775a9b68ecaaf914c0bd4ca333c97a33bd5a78))): {TokenName(1b4c96c4f76fb3977b8ac414d12cca36bafeea1b18c9332b6527c567b3dc0ad3): 4047894026, TokenName(4a251d7b17c1688b67436848f4b085a6e85787cf4367db02f1f339f0b639d8a7): 2105094856, TokenName(4b657838392205527c62f57656ccbb43b8ebb557e56797a930c6b007d60675af): 3999884748, TokenName(d22e85b376f205061b77fdd8635ae3519b91277e6573aa5e05404502c092a9a9): 1098536676, TokenName(f7f65974967b3c0f0b59ec46ab1e39f4b3ef7a01b578a9a6be72aa1e2b612979): 1852889996}}), datum: None, reference_script: None }, TransactionOutput { address: Address { credential: Script(ValidatorHash(ScriptHash(8a1f70957ecc5bcf07237a514caff635f9756113d819f5d76f699f51))), staking_credential: None }, value: Value({Ada: {TokenName(): 1875050608586845498}, NativeToken(MintingPolicyHash(ScriptHash(5ffad07ebd776892eb9cf70be33ff89959ac8bf23e9144aec3dade9b))): {TokenName(2c0e09f291d5fe4e56308a4d053a30790d8180afe401474a0a9b8d9a68fe84b0): 3419174824, TokenName(33d20e7e257e8115bafc6277f1528150275d7532d1f4d40a84160e83f400d09f): 1233415608, TokenName(634c0f9175f3b7f80a68e4d6d0ead26c37259ba69359e4e045f22f99c93de76b): 502702735, TokenName(7642483c7c5b82394543bd6a0e82e39b511473fc0b11aca15a739e0334548573): 1957847211, TokenName(fbb16ae3311e95d9824500586e2d40ef71fd93b9e04b92baa6b629c991445644): 3743842378}, NativeToken(MintingPolicyHash(ScriptHash(a7e61d902489094101ae4065dd67f63c8e194e7d04c4e3780f3db47d))): {TokenName(1cc2fdb067c066553991327877808728bd064116debb5db6a475d37dd6b65435): 582182882, TokenName(5b42bdc1cf920a6926365f2d3c2ea62ba7196bdaea0381e879e0cc1064f63edd): 1077275549, TokenName(6c896858fb9e11506a9e7a7ed52728f9ceb432ba5756997be71e0728f35c2d84): 842216307, TokenName(cd50b8569e102c9b1227161ce0e12705cc399b70706ec78e4f64a19a34511aa4): 2394710341, TokenName(f5be742a06da27af05d251af4652feb6102a306824a66338f074fab8a13b1719): 1958201718}, NativeToken(MintingPolicyHash(ScriptHash(d0a6bf87db69adf84ce36aef9ef5befd4bb6be47a124cc219fd76802))): {TokenName(07c3d821c1485fdcb00810a3b5c141217252c61a24513271f30741078029f92c): 3890529542, TokenName(229d8d778334b7f0a3988987575c2e6c9738cba75d8bb04241309cac0ebbec40): 1630686667, TokenName(2703fac3434f25c23a336dbc8c60ee952fd606d485a8f1d14f7d45278f902876): 2142684854, TokenName(43b46257959c0067e91d1678d6d1928031584110bc425d362de0f470b3bbdb13): 1155914263, TokenName(57498f6d566edb2750b7786de3273213d38d784edc1b5663795af6d83000df05): 3798578233}, NativeToken(MintingPolicyHash(ScriptHash(df3d1ac555fe681926052336f96b7237f896dc98b5fd45ed98a4c118))): {TokenName(0aa392ff72eb2e15bd76f081ee194e9c92ab0c5a9cf13f0c1afb98c5d23f923f): 3632623055, TokenName(37988b88ccfeebf8c96553676844d522808a9c189a93a1faafd75412ae41b1cb): 2529992407, TokenName(8cbdd7d69d4dd33c5fa25020b6fae979778c101ee1d15a021de2c4d2f0205f90): 1159873407, TokenName(ab3e2eb78d15c89f7534cef7f735391072821ef558368bdb99c1362465f8fdbe): 2838666169, TokenName(f9b27d6f3432e9dd010ca1dfc51af6b592f1dc6be77f85f1453cc89c0d5f794c): 320800172}, NativeToken(MintingPolicyHash(ScriptHash(fae71851e0c869d670710c4cd5cc380cda0b6c77cc12bc8d404a088a))): {TokenName(19561f4e59d0b31c731632465805369636a0d830fd373808d343c881a515a98c): 1523624715, TokenName(4b95c6d6eef55e7860333ca1c77fbaf416ea40462e464d4028fe1bb6d9fa8a8f): 2672564629, TokenName(5e857d5d57f459d890316b3d7279aa5c90ff56a7ee089c93f20558898bd56d8e): 2676225451, TokenName(d0fd43d731f7636b964dea6b8c80a3d5318b285d65fa18cd2644343ec79d0042): 2068220055, TokenName(fcf5a2a03633681227d43c0168f905c4b67d3bef71fb713d18f169a2b718d064): 4168155326}}), datum: DatumHash(DatumHash(826d7a66d45db89c49132f6f0d47bb60dd0c671eed8bba33cfd1cf722f0752d4)), reference_script: None }, TransactionOutput { address: Address { credential: PubKey(Ed25519PubKeyHash(9f5a9609101b26415da5bd82fd838ccc530fddee001b04415f659a21)), staking_credential: Some(Pointer(ChainPointer { slot_number: Slot(2202497918), transaction_index: TransactionIndex(2126350206), certificate_index: CertificateIndex(821134753) })) }, value: Value({NativeToken(MintingPolicyHash(ScriptHash(0c6f149015fbf25e0bcb8a612d06d075c985fec2854fb069ecbe5d67))): {TokenName(0fbada78724dddfb7dca902d36487563632ef647b0d12b7d286a6252decf855b): 3328392272, TokenName(29f966bb059400c62d419aeaaf87f7b152261133371b3ac137b53e07c428efbb): 996923888, TokenName(57fd19bf614e4a3e5ba431ad041b359b8b74b8c58760c665504f937ec8fba8fb): 4136587877, TokenName(59aaf95e06f3bcd456f1838b11dbe8d68365b7dc64093a9dbdd9c9cb41c5e4d7): 3090979415, TokenName(d2ae5bf39dd75fca8e7f26bd7344898e5f42384f36c76d0d86449ca7d1cd6e2c): 3907724448}, NativeToken(MintingPolicyHash(ScriptHash(953d1aa7c8a6597ea255436096b7b8653d3ef99af22584df3be25b9e))): {TokenName(160adfb15854c5ecd6adfcaa5c6536461b42af6d802908dd17a33c6da70015c6): 1063620687, TokenName(1808a791db8b06d9152eb2b36b5b1593e20f11d2a4a4e3e29d567c664a40638b): 3788863571, TokenName(7f39bd22a48bae016ffea03a21da657edd97785eadc12c044ce8e185466e6e33): 3102480397, TokenName(900b2383360942743b2d715045286063849c0fd58d0baf4218cb1bba36f239e2): 2873646979, TokenName(f1ae7c12c75370249b24a2b4b6a0bcd583e67f08933c5372c87b999913c91bb4): 2416656345}, NativeToken(MintingPolicyHash(ScriptHash(bba45db883e225c91725659b7cbdad0b4e3ed6fd762a880e757db587))): {TokenName(1e234a3b4bdf50113ecfeb00d6499751654ab66e314e26d453d7db2ed89df561): 4141472780, TokenName(344822f1c18b6021081821ca1d8a6fe3dd62b1966bb38c5596604cc4d857c6f9): 3120952892, TokenName(df630d96f19a6e9105a7192f1d5d5d2d5c0b087ac03332fcdbd560100634e5f3): 639708949, TokenName(eb3ba991372a4a3d8c55f27ffe66ac4eef04b7af7daebea3d6dfac437fab9384): 2233927639, TokenName(fe0b8f25d4e3823f5f33c2fedad4b225ce9e1402bb2cba591091e4b9b3fc5350): 2923985628}, NativeToken(MintingPolicyHash(ScriptHash(dbc813806f603986046859c9a1233f82a60a5d5be22875c7257829e8))): {TokenName(223da369e60152a4eccfba4f5e66dec74719a7e11b707ed045b2722040d387bc): 2816803314, TokenName(466e9624f30622c39e429787d8dabcebc433cfd97ee8f74c7fcd30eca007ad47): 4241284657, TokenName(b59a08ea8d7638266fbc88937361c010fc97a487be00e214c6a27237aaecc6aa): 2793411479, TokenName(de16ee01ccaf7bec5d970f7f8eb406b30a0a519d7a21ef8f13e619435fe51359): 3457509201, TokenName(fcb79dce7287c26da98445c5633171009fccb8f5d4a9e10cf7fdb8cc2988e9a4): 1973183991}, NativeToken(MintingPolicyHash(ScriptHash(f93c4aac2c238a53839dec1f85e0f6d7b0f794a5d26d5a547335a57a))): {TokenName(2044ee496ab8736a05cf92574c9f02947d107804e3be9156606b614f379d7d4b): 3903125479, TokenName(7daa60cd5695a6fe07e4ce83510aa5948b8af205eabf83683dfdc8a546f5caf2): 3447520966, TokenName(8836545aa709f54efa76dea09acd6cef5e79aae6327a92241a0a1f750ff75284): 766065464, TokenName(b49ed50fe0f51d3331947f589665125b77728606188fa49956a4d70eac4a2253): 2263306418, TokenName(d8f448fef891d6c37018e9c7e77d80fba9df64e4c0818af64306c777c36a9ba8): 2507925515}}), datum: InlineDatum(Datum(List([Integer(18341390424677414674), Integer(-15188219571950571493), Integer(-12618291903575643987), Integer(12604060985820067889), Integer(1711885320080205276)]))), reference_script: Some(ScriptHash(567a963be3f865a25e5a36ed088b020dbc7ee2824c99f1061f0c470c)) }], fee: Value({Ada: {TokenName(): 15803115623070617160}, NativeToken(MintingPolicyHash(ScriptHash(51af9658be40865278fd47f42d017d860682df63a06f1c0b6e14864c))): {TokenName(00576a3a5f458896aa30b52876cfb69549af50f0058f1b28560c1e3530f7f655): 1891164644, TokenName(346fe26f4fcf7436e8d3d1d94159a86a136beb779d05e610474ea5a5fde683a0): 231309602, TokenName(6a030d5bd54aefb998274c8305eb4915b359a58fa39aec5ead75b67ba94a51c4): 1408961262, TokenName(e368b8e6a939313a805442efcf28bad130952f255a3c0e554acf962c3e925eb3): 2028257270, TokenName(ecb5162c612556f713b3d434a6fa8b7f4dfbefa787c8f9ee8340c335a2f95ead): 2505255268}, NativeToken(MintingPolicyHash(ScriptHash(59a48ee567ffbd294754a2e58ded4ba6ab3f327cd8c7c1f1bc6a8701))): {TokenName(056aae0d11e020963fde9202797e0ba7a6155a5e03a9e40f06ed001dff1f868e): 4062212792, TokenName(6398b5866d75538c40b3114713c7e6e927b19b777e69ab3d85d585ba683e39a3): 179831580, TokenName(a32be848542f1c36fcb05fd76957d93f9a3753e35834d0cc4cdecda2c959c713): 2573060774, TokenName(da053c704706ab24b9d4d6279869447c0609a973850d7cfdacb0b5650bad39b4): 1744184575, TokenName(f8a507a37d0c9f936d3fffa96a9bffdbd7b7c458c6d7e8db3bbdc1c89abd6889): 4216496880}, NativeToken(MintingPolicyHash(ScriptHash(67a0397effe1d763f3065fff9555c652dee27c9c3b08bb2dc34544c8))): {TokenName(417ef25e64dc8bf269771508b80f09daf2c793f2761acdac2447c5f4230d8964): 68891500, TokenName(833e13de8f099d6438ce362f4ebd4011e8583dd1d08c3105b51856db4fed6d72): 2842042184, TokenName(89e79630f1a370d4a9dcff62a4b9e733f65d77a189c68cc92b976a8b47ebc458): 124004641, TokenName(a6ae571e2be0904fdf544d2c1050771e23d265fae40e61d5bcb43fb913e1868d): 1140594532, TokenName(b6cb38fa26dd3c6d4e44bd30d92cc0df4ae412db903b3a12c6c562d8830dbcad): 1884238911}, NativeToken(MintingPolicyHash(ScriptHash(6ec5286b5cd9e1d99247cb163669b313fdc2bcd00caf3748bd2cee4b))): {TokenName(0368a5459a02f850ac1a593ce239f37e2c8b086be8af88d965a82f0a67d9d82d): 2103763571, TokenName(4b4d7e8c41ed1e4824ec752ec88a0f5dc5d69ced7b42fa86f12211626aa90053): 1150630860, TokenName(6a845f861fbd500421b52b4d3be75efe66be526061f379c2517f3e30d809ef37): 611065587, TokenName(9581c41d62560ae5e71cdfce8bb299dd3813e640c2929d4fccfb72cf8153f12e): 2733787951, TokenName(c00bfc5e7fd044062e6902173586840a2fffdd4abbf25ff2b42aa1d4b02e41dd): 2640075632}, NativeToken(MintingPolicyHash(ScriptHash(d695c62120cd646fc72784bfb336c3c16d6b42ce98120c34ea8f7886))): {TokenName(0299561ef7c9a456e1780ba3804163bb2d9693e0722c89902b0712c0e12611f6): 3896231851, TokenName(0e6c1a5f6061a79284b3ce2d29bb0db5e06d95921035dc94dd495a0886c40040): 715083743, TokenName(9af7bdc7bbc9c28f9d17174cf8aee887cb08c7f839aeab22b9f680fdd3f0f938): 857505909, TokenName(c3e407bd1fcb3952f0489287ffe4ef81321ff1bbd120b601fe81edae5bd58ac8): 3247714681, TokenName(e5297cdb851b5d5d782a6885c25b2e459a03f14e8b816b40345cd2953af034e3): 67613300}}), mint: Value({NativeToken(MintingPolicyHash(ScriptHash(333113c894fe11a52f1141e3e7b9ee9ead73a981547e952f654e4bcd))): {TokenName(31b5a8c6e22bbf81e0e8580d4419d2a8a9c8410594ddf13a3f587200ff3bf99f): 3510970424, TokenName(39508322dcba87e333b88e27561450e92b9ed21f07c85897d0a5ae27a6328037): 2623597566, TokenName(3f27fbddc77e5f31716cea0741ca384aed2e0beb2f0d10d42e841d6555d416b4): 4223901033, TokenName(bf168eda2ad99e4ec1f18925c00f61ee99764c3849e1c828d332cb6e4d8c2866): 745442573, TokenName(d86514ffb5f7395ac2345689684e2a49efeaa199979ccf366e6303ecae38de2d): 2070654651}, NativeToken(MintingPolicyHash(ScriptHash(4855f437d5b8f64369d4f22448101a2a90d400d6465befceb9f7b644))): {TokenName(329a1bf5d5969a43640a8969f8be7ee09cd2be00534eafcaa963995dfd74bd99): 1939130107, TokenName(a9d2be008e98ad835a4cc68913f50a5ae80b370d78510fe7a1ee488d2aab3589): 2400496195, TokenName(aaa74287e48b6fab53ad1581a6ef7ee6ce2f86692e0175071371e7232c9af9fa): 3336964384, TokenName(b13d68dddeae7aa3eae33ab1929804f9181b521283f7d137d61ba56b91ea7adb): 3587800286, TokenName(da96e9444c0fda9a2bfa20da460fb30cab627a8a3cb912d881e44f062a8076ab): 1083941161}, NativeToken(MintingPolicyHash(ScriptHash(ba30dda1dbcb2af4319fa18f3f97ee4a40b881e94d83f735350212a8))): {TokenName(126b2ba20d350849e97d2ad5535debe2ab61f8192117539aa08a0046786d5184): 2037947589, TokenName(2d2f0c2fab2b10b2b2142ceef43259bc0a33634d19070a63843cfa9f725f6987): 3683714516, TokenName(3f17cbd53d6c15154066c664668fc69664f13a8176ee62d77d91b249844310e9): 1356465783, TokenName(7163f2327a83e4a8e60334cc8359fadd1c4496441631fefea0d3748cd47cb095): 153963067, TokenName(8e849037f18f4144bf0dc017fef9b889c5521f5e635e0dbed6afac762996e0b5): 1439049856}, NativeToken(MintingPolicyHash(ScriptHash(d2887e00d8e7aea32a0b0fd2bdf41f71f06cee73806b40ac6a8aea16))): {TokenName(1178f53dbac3ef33fbb8dd891c8e3576d616bce31de995eae9f666d14f87d538): 3700885807, TokenName(2661ee1a540c4da700f528edfbfaf601f132ab14e4380f5b8ccaeb25bffc8677): 3840572024, TokenName(4a490ddd6dcacdecd2daa50b57463ee62203d3514bee6bdc5801f13529bf868d): 2529075641, TokenName(c36f6439b01b042fedd05714e11d3486e6458c62398a148027be8cf7a70a69a1): 1293554079, TokenName(ca8ba4a96cea31e139f9e7e7cef3769280c7750c44ae24974179c58086912d95): 1370877010}, NativeToken(MintingPolicyHash(ScriptHash(de6e84d8a6687b9d0448ab71958dde1d1f3f3eddd3113862c3216d53))): {TokenName(2b27b7e3ffc5f0fa11809739b7dcfa4f0174375506be1ea4c26ed74a12c4f85f): 1503890893, TokenName(2da2fde1bb357aa579dddd8f57d6c399786519ac3de7a0126e01b3018eaf8b91): 199024162, TokenName(3755b21f2864e630e52af59406dff60761821a7f3da2e59140e41aee956031a9): 1152035766, TokenName(85df67e42252466fd8c73c04155ffda08f1aef716440c8a09e26701f80d78363): 1718120637, TokenName(8f07d214cdcc525faad400498aab4495bbcb2543f388e8c9b9efddac617d6d94): 4225038705}}), d_cert: [DelegDelegate(Hash(Script(ValidatorHash(ScriptHash(2026c1e7a5a9312222e66a86b1df6a56c74f0f54c7380649503be4e9)))), PaymentPubKeyHash(Ed25519PubKeyHash(7eda1c44fd39f1ce8aa1c9502b43dbdd0a1f787c42940a7ab77a588c))), DelegRegKey(Pointer(ChainPointer { slot_number: Slot(2851043036), transaction_index: TransactionIndex(2709126557), certificate_index: CertificateIndex(715274452) })), Genesis, Genesis, DelegDeRegKey(Pointer(ChainPointer { slot_number: Slot(761337367), transaction_index: TransactionIndex(3811942017), certificate_index: CertificateIndex(894925047) }))], wdrl: AssocMap([(Hash(PubKey(Ed25519PubKeyHash(de3d5474477888f52dc73c3219a9df08929721720c1ffbf7778b46a4))), 1188800935), (Pointer(ChainPointer { slot_number: Slot(2561259123), transaction_index: TransactionIndex(4083476119), certificate_index: CertificateIndex(1585308347) }), 263857381), (Hash(PubKey(Ed25519PubKeyHash(87cebed31148f5e0c6434f5b29f19ed709538c4b86addd8930b2aed7))), 1856686000), (Hash(PubKey(Ed25519PubKeyHash(68d692439b1d02991261428f3565deb31e19b207de1670aeb001b348))), 1338798631), (Pointer(ChainPointer { slot_number: Slot(132451218), transaction_index: TransactionIndex(221312802), certificate_index: CertificateIndex(3760676452) }), 3400108145), (Pointer(ChainPointer { slot_number: Slot(2964679271), transaction_index: TransactionIndex(1953655207), certificate_index: CertificateIndex(3832592502) }), 217527895), (Hash(Script(ValidatorHash(ScriptHash(5b2bce504e16c9d1b9f1e72fb9da01aa37f7369823e109516c44c1aa)))), 3742334973), (Hash(Script(ValidatorHash(ScriptHash(939d095936089874fed61fbcb4b6ad1bdc13a2ba2c557fdbbf903732)))), 2677634697), (Hash(Script(ValidatorHash(ScriptHash(f1d99bfe32b36ee4ea5d278329b23a99fb119823517f69277c78c88e)))), 2637902573), (Pointer(ChainPointer { slot_number: Slot(3188648279), transaction_index: TransactionIndex(3069628652), certificate_index: CertificateIndex(2280472759) }), 3561615259)]), valid_range: PlutusInterval { from: LowerBound { bound: Finite(POSIXTime(1947697823)), closed: false }, to: UpperBound { bound: PosInf, closed: true } }, signatories: [PaymentPubKeyHash(Ed25519PubKeyHash(84232c9099056f56e6a0a9f0f749f65ea5c64d2eb528daf7e8799df1)), PaymentPubKeyHash(Ed25519PubKeyHash(6e8667593ac31ae80eb81d65f51f07789992ff9ad7aa8b1691f71f30)), PaymentPubKeyHash(Ed25519PubKeyHash(8ed98e3eb6fc1940eea87da038ee40b0f1b692e2f901638c4577e739)), PaymentPubKeyHash(Ed25519PubKeyHash(a93d3a6ce845817e502b34057e09cd1126cc2003a2cef4ce492889da)), PaymentPubKeyHash(Ed25519PubKeyHash(fbd74df32d509d3534b1eb660bd9b2d756207bfb1e97116134c794ff))], redeemers: AssocMap([(Spending(TransactionInput { transaction_id: TransactionHash(3684758d3317af19ab7e0f19f5f060b1b3d85abea6b07b5c39f2b5494895b7df), index: 402668050 }), Redeemer(Integer(2810963777676229418))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(175fd4d257035282bf6cc6aaf5ecad5e14f33cd271603da5a9023c30)))), Redeemer(Bytes([174, 91, 255, 132, 236, 210, 74, 206, 199, 181, 33, 217, 105, 3, 55, 121, 209, 111, 245]))), (Spending(TransactionInput { transaction_id: TransactionHash(45597a6c4ada1ce6df045684b4ee6c1582930205ab9a922e4e31e9ba5396d984), index: 2195186866 }), Redeemer(Bytes([155, 103, 42, 214, 236, 40, 73, 165, 239, 119, 211, 29, 147, 176, 117, 7, 28, 206, 207, 208, 249, 171, 103, 247, 248, 61, 137, 254, 220, 50, 154, 132, 101, 60, 15, 72, 17, 155, 23, 70, 132, 1, 81, 83, 120, 7, 69, 180, 132, 97, 114, 186, 220, 171, 103, 86, 23, 156, 194, 217, 142, 55, 150, 88, 10, 223]))), (Spending(TransactionInput { transaction_id: TransactionHash(f7060289b31d2eee6dd60a50f49781e9f797c0b393dd60daab103b8d3fb3a889), index: 2516227782 }), Redeemer(Constr(2228932073, [Integer(-10040748169353365345), Integer(-16348844488077936941), Bytes([118, 93, 98, 129, 35, 22, 191, 164, 62, 30, 202, 33, 85, 193, 208, 111, 241, 39, 106, 154, 19, 219, 98, 56, 12, 246, 117, 89, 106, 46, 233, 205, 11, 175, 53, 10, 6, 2, 31, 95, 164, 14, 60, 19, 178, 150, 29, 233, 66, 93, 85, 173, 148, 167, 108, 49, 175, 34, 103, 17, 119, 89, 95, 164, 147, 83, 198, 248, 64, 131, 74, 211, 39, 75, 73, 29, 53, 18, 140, 103, 143, 10, 54, 33, 144, 84, 101, 98, 215, 250, 206, 78, 102]), Constr(158106493, [Bytes([242, 195, 61, 243, 253, 83, 48, 120, 89, 168, 176, 167, 27, 231, 203, 105, 129, 159, 133, 196, 149, 178, 212, 61, 147, 8]), Bytes([121, 26, 202, 42, 214, 164, 29, 215, 24, 55, 57, 90, 30, 226, 5, 155, 51, 187, 84, 51, 73, 214, 246, 152, 53, 233, 111, 179, 151, 54, 188, 164, 72, 17, 55, 221, 183]), Bytes([82, 208, 81, 26, 131, 41, 237, 37, 232, 32, 197, 229, 84, 37, 15, 29, 56, 227, 100, 46, 7, 217, 39, 189, 187, 175, 191, 31, 54, 199, 219]), Bytes([5, 147, 3, 242, 139, 200, 16, 190, 224, 198, 251, 71, 91, 209, 123, 30, 12, 148, 231, 171, 144, 241, 128, 20, 133, 6, 48]), Integer(-16674154303761446734)]), Bytes([20, 244, 82, 105, 235, 25, 226, 247, 129, 240, 230, 48, 237, 54, 191, 180, 45])]))), (Certifying(Genesis), Redeemer(Integer(-6322583901471666111))), (Rewarding(Hash(Script(ValidatorHash(ScriptHash(5a2229d81a04f63baf4be9ce6823eec3f236c98e2f96c2a8f41c7adc))))), Redeemer(Constr(2108123717, [Bytes([48, 143, 62, 144, 22, 28, 118, 97, 5, 243, 108, 134, 212, 235, 67, 31, 91, 156, 207, 64, 227, 71, 29, 152, 79, 46, 155, 69, 96, 133, 136, 90, 108, 212, 102, 152, 80, 253, 230, 208, 247, 38, 230, 128, 173, 79, 132, 251, 104]), Integer(-8068460302907919505), Bytes([230, 22, 48, 43, 56, 31, 65, 114, 46, 61, 233, 217, 124, 158, 221, 38, 8, 156, 148, 9, 210, 198, 197, 224, 133, 20, 221, 192, 28]), Bytes([200, 255, 188, 74, 6, 165, 182, 28, 113, 173, 107, 255, 120, 129, 167, 2, 19, 155, 246, 49, 226, 105, 38, 110, 217, 136, 231, 16, 69, 214]), Integer(14568000902052266110)]))), (Spending(TransactionInput { transaction_id: TransactionHash(e3c73cee29ccc3a93f4908faacd2039c80e6e11f4af461609357150e1ccdc9f7), index: 1997757407 }), Redeemer(Map([(Integer(-12617781173585543840), Integer(707927533030626591)), (Bytes([87, 37, 253, 91, 240, 70, 15, 48, 131, 76, 16, 79, 136, 70, 70, 78, 172, 177, 143, 150, 204, 99, 121, 161, 162, 154]), Bytes([152, 43, 219, 158, 55, 149, 84, 234, 246, 9, 94, 13, 170, 138, 189, 57, 16, 37, 238, 118, 106, 30, 143, 67, 67, 4, 248, 251, 68, 243, 156, 97, 67, 111, 96, 51, 90, 0, 159, 255, 37, 228, 89, 6, 253, 99, 190, 181, 96, 128, 180, 20, 248, 23, 21, 179, 52, 154, 126, 179, 194, 77, 90, 64, 73, 138, 210, 232, 215, 183, 4, 18, 181, 213, 58])), (Bytes([79, 154, 247, 87, 37, 204, 80, 46, 89, 234, 172, 52, 5, 191, 52, 130, 85, 170, 76, 22, 242, 207, 207, 30, 142, 90, 100, 15, 55, 165, 53, 205, 251, 71, 175, 222, 244, 80, 34, 62, 132, 223, 123, 198, 192, 68, 196, 141, 190, 198, 87, 229, 189, 51, 141, 171, 12, 53, 91, 198, 37, 25, 246, 92, 152, 89, 128, 43, 234, 45, 128, 68, 207, 46]), Integer(-14322734530933966339)), (Integer(-3861535558087861398), Bytes([111, 41, 2, 76, 196, 41, 156])), (Bytes([85, 81, 119, 35, 33, 228, 212, 131, 254, 255, 32, 126, 133, 24, 188, 74, 128, 66, 21, 125, 180, 215, 36, 14, 79, 226, 249, 63, 75, 180, 149, 208, 146, 42, 243, 2, 144, 135, 62, 126, 127, 197, 227, 169, 79, 219, 149, 139, 213, 60, 122, 208]), Bytes([118, 214, 241, 123, 244, 200, 9, 151, 218, 221, 87, 178, 16, 107, 48, 16, 192, 199, 131, 111, 9, 182, 13, 37, 202, 47, 135, 184, 246, 146, 245, 12, 215, 67, 167, 172, 223, 212, 149, 99, 144, 182, 16, 178, 188, 146, 235, 109, 215, 116, 233, 23, 82, 149]))]))), (Spending(TransactionInput { transaction_id: TransactionHash(62c42e4202f656c5bc421000ca55519453b3baf0cdd7939350b4714a505b6e63), index: 2111527653 }), Redeemer(Integer(16458574750339611711))), (Minting(NativeToken(MintingPolicyHash(ScriptHash(cfc4818d9f1d2b8846520e2483eac0a3c1e73c74626f767efee3eb30)))), Redeemer(Constr(2140196213, [Integer(15708456767238457497), Bytes([122, 118, 45, 12, 134, 125, 206, 188, 13, 26, 125, 183, 190, 94, 85, 69, 90, 224, 199, 233, 45, 227, 21, 185, 2, 145, 49, 184, 113]), Integer(10944798376073413757), Integer(-5781556765119698737), Integer(-5775803905611332833)]))), (Certifying(DelegDelegate(Pointer(ChainPointer { slot_number: Slot(1535946222), transaction_index: TransactionIndex(973501788), certificate_index: CertificateIndex(1721835424) }), PaymentPubKeyHash(Ed25519PubKeyHash(8da7434927217fad2dbc685e7dad4061ec2446602a443024505e085a)))), Redeemer(Integer(-105968194133868962)))]), datums: AssocMap([(DatumHash(3f13f0f11489a611f86854e1798b705dd42e223dcd41cf122b05b747088df20a), Datum(Map([(Bytes([118, 161, 39, 170, 34, 79, 212, 83, 167, 238, 67, 67, 185, 243, 138, 101, 174, 188, 204, 187, 12, 126, 60, 238, 79, 239, 170, 171, 228, 2, 248, 6, 30, 98, 242, 74, 47, 48, 224, 207, 194, 177, 8, 43, 97, 98, 176, 12, 149, 193, 103, 18]), Integer(1977499462978565508)), (Integer(10862498357460938208), Bytes([])), (Bytes([67, 12, 8, 166, 225, 88, 2, 238, 247, 93, 98, 86, 56, 50, 64, 102, 127, 141, 197, 139, 108, 146, 176, 236, 141, 156, 200, 55, 183, 106, 24, 97, 33, 55, 134, 129, 99, 150, 169, 142, 128, 135, 106, 162, 69, 26, 240, 100, 110, 218, 87, 86, 167, 120, 120, 44, 10, 229, 36, 95, 24, 174, 110, 117, 93, 134, 234, 60, 107, 157, 243, 227, 238, 57, 78, 254, 100]), Bytes([118, 181, 227, 178, 88, 220, 250, 9])), (Bytes([49, 106, 11, 48, 139, 75, 97, 236, 204, 210, 22, 64, 193, 204, 10, 142, 78, 223, 187, 250, 174, 115, 174, 255, 237, 96, 134, 215, 167, 181, 181, 46, 208, 35, 18, 220, 218, 202, 234, 200, 40, 69, 114, 132, 251, 216, 101, 15, 243, 21, 175, 13, 14, 225, 55, 191, 74, 187, 218]), Bytes([158, 73, 152, 185, 193, 123, 92, 130, 151, 32, 167, 168, 198, 205, 25, 174, 41, 76, 41, 187, 76, 26, 243, 192, 137, 127, 166, 40, 164, 253, 40, 21, 224, 55, 145, 89, 166, 140, 219, 94, 46, 213, 40, 183, 164, 44, 64, 211, 69, 108, 31, 162, 223, 59, 190, 37, 228, 74, 200, 146, 193, 210, 63, 12, 18, 21, 219, 188, 65, 211, 8, 150, 10, 202, 79, 62, 120, 79, 166, 175, 235, 221, 86, 233, 90, 56, 133])), (Bytes([167, 85, 73, 175, 24, 104, 70, 32, 188, 82, 35, 33, 38, 46, 206, 145, 16, 109, 229, 184, 122, 246, 16, 104, 137, 149, 13, 161, 11, 81, 119, 34, 174, 95, 234, 93, 187, 208, 174, 42, 15, 116, 27, 30, 23, 195, 184, 134, 138, 141, 153, 84, 122, 173, 49, 31, 157, 228, 111, 132, 171, 29, 249, 213, 125, 51, 162, 171]), Bytes([173, 43, 61, 171, 40, 132, 160, 0, 51, 38, 60, 156, 84, 190, 38, 250, 42, 247, 134, 141, 15, 1, 196, 220, 95, 69, 182, 97, 217, 254, 96, 149, 68, 207, 173]))]))), (DatumHash(2d3b3784524ee6b3209de5f067eafbb855ab2fea6d84520bd4c498ad3bb4a9bf), Datum(List([Integer(8367189122487879926), Bytes([85, 73, 133, 238, 111, 220, 15, 18, 34, 163, 152, 66, 155, 1, 153, 190, 23, 83, 30, 150, 251, 76, 114, 20, 47, 119, 18, 159, 134, 192, 115, 230, 52, 234, 155, 13, 215, 6, 248, 17, 51, 29, 215, 86, 35, 160, 223, 109, 125, 211, 26, 104, 87, 162, 115, 72, 13, 229, 161, 209, 221, 69, 127, 153, 191, 239, 254, 213, 190, 148, 126, 34, 248, 117, 0, 79, 198, 252, 69, 21, 103, 203, 238, 38, 166, 112, 197, 236, 29]), Bytes([39, 11, 165, 215, 13, 7, 168, 38, 171, 158, 216, 76, 205, 219, 175, 173, 48, 249, 55, 120, 163, 252, 3, 212, 100, 14, 72, 36, 250, 217, 182, 224, 86, 144, 68, 194, 171, 125, 18, 95, 195, 61, 107, 252, 44, 39, 245, 35, 250, 44, 178, 100, 200, 35, 0, 48, 63, 66, 113, 222, 254, 104, 87, 211, 218, 133, 146, 5, 79, 181, 128, 131, 143, 239, 41, 184, 153, 133, 201, 49, 186]), Integer(-9962985770080429271), Integer(3300264540542865748)]))), (DatumHash(8ce152b89a27ba57337b595010a34f555046c8c6cd7e3afc906bc4c94a518acd), Datum(Constr(936155300, [Bytes([179, 191, 241, 133, 205, 121, 248, 205, 87, 116, 230, 31, 187, 169, 193, 199, 132, 206, 141, 5, 158, 46, 152, 8]), Integer(-8673110579305453718), Integer(-12537810982799057929), Bytes([236, 213, 37, 205, 7, 12, 74, 160, 98, 55, 208, 158, 197, 160, 241, 14, 9, 245, 193, 187, 17, 154, 236, 190, 39, 221, 146, 248, 86, 217, 88, 64, 68, 89, 51, 163, 48, 73, 250]), Bytes([42, 75, 165, 156, 215, 125, 186, 112, 165, 63, 87, 175, 5, 5, 124, 160, 177, 17, 156, 186, 248, 216, 118, 192, 0, 170, 64, 192, 137, 107, 42, 219, 222, 71, 54, 233, 248, 169, 209, 18, 179, 146, 90, 25, 178, 214, 70, 44, 46, 106, 178, 251, 144, 150, 106, 136, 106, 167, 57, 94, 192, 75, 46, 72, 249, 114, 31, 157, 137, 96, 172, 168, 87, 22, 151, 33, 123, 232, 228, 180])]))), (DatumHash(c8f2f2962fa2008d80d74845ce6e1c9fa07c59a72a7855bbc8327038173d7a14), Datum(Integer(-11014695058603834993))), (DatumHash(feacbf167e7362c034b6094309acfc199eef89c762627afbc3e26c17077498a3), Datum(List([Bytes([114, 25, 55, 213, 115, 15, 223, 38, 109, 128, 137, 138, 28, 217, 153, 135, 174, 69, 209, 57, 123, 255, 187, 27, 170, 28, 30, 141, 116, 75, 200, 255, 29, 219, 73, 40, 84, 123, 56, 231, 12, 208, 17, 101, 51]), Bytes([227, 109, 163, 146, 239, 116, 37, 217, 246, 179, 7, 40, 159, 217, 8, 3, 179, 245, 239, 159, 171, 125, 172, 127, 182, 68, 122, 122, 139, 99, 139, 228, 221, 182, 166, 177, 122, 1, 124, 113, 195, 83, 148]), Bytes([131, 145, 78, 12, 160, 95, 28, 195, 41, 9, 33, 59, 95, 198, 214, 159, 126, 28, 49, 170, 237, 148, 108, 179]), Bytes([45, 124, 127, 231, 243, 103, 86, 59, 47, 155, 129, 97, 177, 66, 26, 11, 184, 40, 133, 137, 192, 84, 185, 181, 211, 85, 130, 6, 77, 126, 112, 73, 89, 51, 29, 13, 120, 196, 78, 3, 194, 122, 8, 196, 136, 165, 175, 203, 155, 142, 255, 31, 25, 227, 119, 233, 226, 126, 140, 150, 236, 212, 12, 232]), Bytes([236, 105, 73, 166, 64, 27, 13, 211, 82, 60, 159, 146, 183, 63, 198, 4, 87, 147, 135, 68, 72, 75, 39, 114, 56, 116, 41, 102, 79, 4, 176, 86, 100, 27, 188, 166, 198, 137, 145])]))), (DatumHash(fcd1cd0c9180a200774e56effadbc3f4ede5fd45dfacf13beae30604ceba4d02), Datum(Map([(Bytes([102, 71, 154, 227, 34, 164, 72, 15, 62, 209, 6, 126, 235, 53, 244, 194, 37, 198, 130, 182, 186, 180, 77, 97, 253, 124, 97, 31, 201, 11, 220, 27, 11, 145, 104, 76, 209, 12, 226, 243, 14, 113, 158, 184, 67]), Bytes([156, 198, 199, 223, 210, 171, 2, 198, 253, 32, 1, 207, 227, 120, 89, 171, 250, 233, 34, 36, 165, 30, 52, 49, 138, 121, 141, 24, 247, 28, 46, 216, 184, 111, 63, 0, 64, 118, 225, 208, 201, 50, 34, 89, 44, 28, 231, 72, 6, 94, 227, 27, 203, 204, 174, 235, 20, 94, 72, 239, 131])), (Integer(-2969090282184661921), Bytes([125, 19, 184, 92, 117, 251, 235, 8, 107, 208, 51, 169, 11, 253, 58, 113, 223, 233, 67, 94, 71, 44, 89, 97])), (Integer(17796746725610530894), Integer(8075163424182805764)), (Bytes([244, 107, 201, 18, 134, 48, 213, 105, 51, 128, 1, 151, 228, 127, 29, 157, 162, 18, 173, 238, 173, 14, 85, 187, 135, 114, 105, 183, 193, 255, 16, 187, 138, 102, 89, 61, 26, 18, 207, 51, 253, 62, 228, 194]), Integer(-14377981926416437422)), (Map([(Bytes([211, 1, 54, 201, 102, 224, 170, 36, 164, 75, 27, 57, 100, 213, 241, 22, 92, 100, 154, 82, 235, 155, 134, 145, 123, 16, 203, 188, 83, 54, 207, 143, 223, 239, 176, 88, 192, 255, 39, 71, 220, 70, 97, 233, 155, 157, 231, 205, 135, 124, 169, 240, 196, 106, 1, 158, 139, 164, 241, 199, 232]), Bytes([97, 117, 12, 196, 123, 121, 85, 214, 54, 1, 0, 226, 26, 217, 1, 111, 149, 2, 54, 65, 205, 48, 254, 235, 250, 195, 18, 127, 224, 102, 88, 162, 103, 248, 130, 233, 9, 239, 166, 90, 42, 82, 13, 220, 111, 61, 140, 118, 242, 118, 235, 113, 159, 60, 116, 140, 136, 40, 61, 250, 217, 9, 89, 136, 191, 17])), (Bytes([85, 213, 155, 19, 60, 53, 46, 3, 226, 168, 46, 67, 46, 129, 230, 122, 209, 62, 9, 124, 98, 175, 31, 63, 167, 107, 39, 103, 167, 216, 54, 247, 244, 26, 25, 89, 13, 22, 207, 97, 234, 33, 25, 59, 74, 206, 115, 30, 66, 219, 189, 121, 73]), Integer(-16621810592565322148)), (Bytes([33, 111, 35, 64, 60, 84, 220, 71, 149, 201, 14, 243, 229, 138, 62, 126, 130, 117, 206, 111, 7, 231, 44, 115, 31, 94, 14, 128, 231, 248, 187, 117, 176, 73, 181, 201, 139, 82, 36, 234, 45, 233, 175, 232, 44, 71, 251, 204, 186, 193, 240, 76, 124, 138, 53, 146, 228, 222, 145, 160, 61, 215, 1]), Integer(-5616026625525347953)), (Integer(-15368326499810788275), Integer(-5411407110371635891)), (Bytes([121, 199, 241, 3, 239, 178, 8, 176, 18, 209, 250, 183, 82, 144, 190, 49, 227, 7, 247, 31, 20, 187, 222, 178, 232, 92, 199, 105, 89, 82, 71, 231, 10, 191, 193, 5, 124, 147, 117, 7, 194, 186, 164, 160, 84, 157, 33, 34, 126, 183, 81, 82, 109]), Integer(5342965962032016216))]), Bytes([13, 23, 139, 158, 175, 64, 255, 73, 159, 124, 122]))]))), (DatumHash(5c5d715d9e3551a9021f822ffd68fc7187a56a796700ec476c7c334e68e65663), Datum(Constr(663131710, [Bytes([214, 101, 129, 57, 237, 61, 223, 147, 236, 225, 27, 252, 144, 165, 96, 38, 69, 64, 226, 43, 226, 234, 102, 200, 44, 93, 233, 91, 151, 226, 72, 127, 164, 161, 28, 251, 104, 202]), Bytes([186, 16, 175, 75, 233, 80, 124, 167, 75, 26, 94, 158, 34, 18, 139, 0, 205, 180, 123, 173, 78, 240, 2, 2, 53, 138, 78, 29, 233, 191, 78, 180, 122]), Integer(12098763251034896583), Bytes([242, 108, 143, 197, 95, 204, 253, 41, 30, 104, 70, 45, 148, 146, 47]), Integer(-18208626424618199086)]))), (DatumHash(0810a61c23167fc11763c0f2cc1c19eb692de08057660dda497ae1324884b03c), Datum(Bytes([187, 176, 217, 74, 224, 238, 227, 18, 12, 163, 119, 220, 90, 66, 86, 87, 111, 21, 188, 160, 247, 201, 51, 130, 216, 45, 71, 40, 12, 85, 23, 82, 226, 157, 103, 187, 254, 242, 214, 83, 76, 121, 67, 246, 65, 215, 160, 242, 165, 225, 232, 246, 86, 26, 185, 194, 21, 95, 125, 84, 155, 11, 137, 232, 51, 115, 207, 22, 217, 121, 240, 91, 0, 100]))), (DatumHash(1077d50c8c9d00b88dab41f27c086fe33cfac17a2659955a2483ea6b037cdc41), Datum(Integer(-11442988182361136122))), (DatumHash(e6d3df05dceb3d55d52dff3d32771cbc5fc3576bac7a9d29f7e7306652d26232), Datum(List([Integer(4619328115424865498), Bytes([114, 27, 219, 211, 103, 182, 175, 216, 124, 11, 156, 134, 35, 249, 243, 233, 125, 92, 89, 196, 75, 209, 196, 168, 123, 219, 153, 135, 11, 90, 205, 73, 182, 249, 220, 75, 105, 72, 146, 98, 38, 46, 231, 8, 52, 128, 129, 209, 250, 80, 7, 255, 251, 99, 216, 75, 2, 75, 156]), Bytes([147, 62, 177, 149, 214, 198, 177, 195, 142, 52, 235, 147, 142, 79, 135, 241, 190, 38, 39, 254, 34, 194, 190, 224, 167, 203, 110, 168, 79, 162, 170, 53, 173, 238, 248, 222, 95, 206, 216, 39, 211, 236, 169]), Bytes([50, 44, 234, 175, 76, 236, 214, 179, 84, 61, 123, 107, 55, 225, 37, 14, 145, 87, 60, 187, 9, 119, 184, 126, 49, 160, 76, 160, 62, 141, 86, 51, 254, 104, 97, 8, 179, 169, 129, 145, 165, 24, 1, 73, 167, 204, 34, 30, 183, 178, 139, 232, 177, 63, 22, 13, 40, 249]), Integer(6130350804586057685)])))]), id: TransactionHash(d6d5074a70133bbb4552745bf3b5acd65b3e47656322b7fefb29ef8627607b47) }, purpose: Minting(Ada) } diff --git a/plutus-ledger-api/tests/serde.rs b/plutus-ledger-api/tests/serde.rs index 8ddf8e3..cc583b9 100644 --- a/plutus-ledger-api/tests/serde.rs +++ b/plutus-ledger-api/tests/serde.rs @@ -158,4 +158,107 @@ mod serde_roundtrip_tests { } } } + mod v3 { + use super::from_to_json; + use plutus_ledger_api::generators::correct::v3::*; + use proptest::prelude::*; + + proptest! { + #[test] + fn test_cold_committee_credential(val in arb_cold_committee_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_hot_committee_credential(val in arb_hot_committee_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_d_rep_credential(val in arb_d_rep_credential()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_delegatee(val in arb_delegatee()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_tx_cert(val in arb_tx_cert()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_voter(val in arb_voter()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_vote(val in arb_vote()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_governance_action_id(val in arb_governance_action_id()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_committee(val in arb_committee()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_rational(val in arb_rational()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_constitution(val in arb_constitution()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_protocol_version(val in arb_protocol_version()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_change_parameters(val in arb_change_parameters()) { + assert_eq!(val, from_to_json(&val)?) + } + + + #[test] + fn test_governance_action(val in arb_governance_action()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_protocol_procedure(val in arb_protocol_procedure()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_purpose(val in arb_script_purpose()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_info(val in arb_script_info()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_transaction_info(val in arb_transaction_info()) { + assert_eq!(val, from_to_json(&val)?) + } + + #[test] + fn test_script_context(val in arb_script_context()) { + assert_eq!(val, from_to_json(&val)?) + } + } + } } From 6864a9a5fe93b6a097e83c1058efdb484635b85c Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Fri, 18 Oct 2024 23:53:46 +0800 Subject: [PATCH 24/38] explicitly mark derive strategies --- plutus-ledger-api/src/v3/transaction.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plutus-ledger-api/src/v3/transaction.rs b/plutus-ledger-api/src/v3/transaction.rs index cb54fb4..649ce00 100644 --- a/plutus-ledger-api/src/v3/transaction.rs +++ b/plutus-ledger-api/src/v3/transaction.rs @@ -41,6 +41,7 @@ pub struct HotCommitteeCredential(pub Credential); pub struct DRepCredential(pub Credential); #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum DRep { @@ -50,6 +51,7 @@ pub enum DRep { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum Delegatee { @@ -59,6 +61,7 @@ pub enum Delegatee { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum TxCert { @@ -76,6 +79,7 @@ pub enum TxCert { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum Voter { @@ -85,6 +89,7 @@ pub enum Voter { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum Vote { @@ -94,6 +99,7 @@ pub enum Vote { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct GovernanceActionId { @@ -102,6 +108,7 @@ pub struct GovernanceActionId { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Committee { @@ -110,6 +117,7 @@ pub struct Committee { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Constitution { @@ -117,6 +125,7 @@ pub struct Constitution { } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ProtocolVersion { @@ -132,6 +141,7 @@ pub struct ProtocolVersion { pub struct ChangeParameters(pub PlutusData); #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum GovernanceAction { @@ -153,6 +163,7 @@ pub enum GovernanceAction { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ProtocolProcedure { @@ -162,6 +173,7 @@ pub struct ProtocolProcedure { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum ScriptPurpose { @@ -174,6 +186,7 @@ pub enum ScriptPurpose { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum ScriptInfo { @@ -186,6 +199,7 @@ pub enum ScriptInfo { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct TransactionInfo { @@ -208,6 +222,7 @@ pub struct TransactionInfo { } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] +#[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptContext { From e7279879d6a2462856e0d103138475278259224c Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 18:52:49 +0800 Subject: [PATCH 25/38] remove true from dependencies --- plutus-ledger-api/Cargo.lock | 7 ------- plutus-ledger-api/Cargo.toml | 1 - 2 files changed, 8 deletions(-) diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 79fed43..007ded4 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -627,7 +627,6 @@ dependencies = [ "serde", "serde_json", "thiserror", - "true", ] [[package]] @@ -1007,12 +1006,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "true" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "548ec159e98411c04bee9b458df4ccd2da2a0a5e50c08cbd7e90b00b154c5a9a" - [[package]] name = "trybuild" version = "1.0.99" diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index 1ece481..0ff63de 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -14,7 +14,6 @@ lbr-prelude = { version = "0.1.1", optional = true } serde_json = { version = "1.0.128", optional = true } num-bigint = "~0.4" serde = { version = "^1.0.189", features = ["derive"], optional = true } -true = { version = "~0.1.0", optional = true } data-encoding = "^2.4.0" thiserror = "^1.0.50" linked-hash-map = "~0.5.6" From 2d51d1cf143916e73c25c911b2749f5f266664e8 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 19:25:22 +0800 Subject: [PATCH 26/38] doc strings --- .../src/generators/correct/v3.rs | 5 +- plutus-ledger-api/src/v3/ratio.rs | 7 ++- plutus-ledger-api/src/v3/transaction.rs | 51 +++++++++++++++++-- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/plutus-ledger-api/src/generators/correct/v3.rs b/plutus-ledger-api/src/generators/correct/v3.rs index 518da68..e77cab2 100644 --- a/plutus-ledger-api/src/generators/correct/v3.rs +++ b/plutus-ledger-api/src/generators/correct/v3.rs @@ -153,9 +153,10 @@ pub fn arb_governance_action() -> impl Strategy { ( option::of(arb_governance_action_id()), vec(arb_cold_committee_credential(), 5), - arb_assoc_map(arb_cold_committee_credential(), arb_integer()) + arb_assoc_map(arb_cold_committee_credential(), arb_integer()), + arb_rational() ) - .prop_map(|(g, c, cm)| GovernanceAction::UpdateCommittee(g, c, cm)), + .prop_map(|(g, c, cm, q)| GovernanceAction::UpdateCommittee(g, c, cm, q)), (option::of(arb_governance_action_id()), arb_constitution()) .prop_map(|(g, c)| GovernanceAction::NewConstitution(g, c)), Just(GovernanceAction::InfoAction) diff --git a/plutus-ledger-api/src/v3/ratio.rs b/plutus-ledger-api/src/v3/ratio.rs index 1433d52..55c4670 100644 --- a/plutus-ledger-api/src/v3/ratio.rs +++ b/plutus-ledger-api/src/v3/ratio.rs @@ -11,7 +11,12 @@ use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] -pub struct Rational(pub BigInt, pub BigInt); +pub struct Rational( + /// numerator + pub BigInt, + /// denominator + pub BigInt, +); impl IsPlutusData for Rational { fn to_plutus_data(&self) -> PlutusData { diff --git a/plutus-ledger-api/src/v3/transaction.rs b/plutus-ledger-api/src/v3/transaction.rs index 649ce00..9772d5b 100644 --- a/plutus-ledger-api/src/v3/transaction.rs +++ b/plutus-ledger-api/src/v3/transaction.rs @@ -65,15 +65,30 @@ pub enum Delegatee { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum TxCert { + /// Register staking credential with an optional deposit amount RegStaking(StakingCredential, Option), + /// Un-Register staking credential with an optional refund amount UnRegStaking(StakingCredential, Option), + /// Delegate staking credential to a Delegatee DelegStaking(StakingCredential, Delegatee), + /// Register and delegate staking credential to a Delegatee in one certificate. Note that deposit is mandatory. RegDeleg(StakingCredential, Delegatee, Lovelace), + /// Register a DRep with a deposit value. The optional anchor is omitted. RegDRep(DRepCredential, Lovelace), + /// Update a DRep. The optional anchor is omitted. UpdateDRep(DRepCredential), + /// UnRegister a DRep with mandatory refund value UnRegDRep(DRepCredential, Lovelace), - PoolRegister(PaymentPubKeyHash, PaymentPubKeyHash), + /// A digest of the PoolParams + PoolRegister( + /// pool id + PaymentPubKeyHash, + // pool vrf + PaymentPubKeyHash, + ), + /// The retirement certificate and the Epoch in which the retirement will take place PoolRetire(PaymentPubKeyHash, BigInt), + /// Authorize a Hot credential for a specific Committee member's cold credential AuthHotCommittee(ColdCommitteeCredential, HotCommitteeCredential), ResignColdCommittee(ColdCommitteeCredential), } @@ -98,6 +113,7 @@ pub enum Vote { Abstain, } +/// Similar to TransactionInput, but for GovernanceAction. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[is_plutus_data_derive_strategy = "Constr"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -112,7 +128,9 @@ pub struct GovernanceActionId { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Committee { + /// Committee members with epoch number when each of them expires pub members: AssocMap, + /// Quorum of the committee that is necessary for a successful vote pub quorum: Rational, } @@ -121,6 +139,7 @@ pub struct Committee { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub struct Constitution { + /// Optional guardrail script pub constitution_script: Option, } @@ -134,6 +153,7 @@ pub struct ProtocolVersion { } // TODO(chfanghr): check invariant according to https://github.com/IntersectMBO/plutus/blob/bb33f082d26f8b6576d3f0d423be53eddfb6abd8/plutus-ledger-api/src/PlutusLedgerApi/V3/Contexts.hs#L338-L364 +/// A Plutus Data object containing proposed parameter changes. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)] #[is_plutus_data_derive_strategy = "Newtype"] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -145,19 +165,34 @@ pub struct ChangeParameters(pub PlutusData); #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "lbf", derive(Json))] pub enum GovernanceAction { + /// Propose to change the protocol parameters ParameterChange( Option, ChangeParameters, + // The hash of the constitution script Option, ), + /// Propose to update protocol version HardForkInitiation(Option, ProtocolVersion), - TreasuryWithdrawals(AssocMap, Option), + /// Propose to withdraw from the cardano treasury + TreasuryWithdrawals( + AssocMap, + // The hash of the constitution script + Option, + ), + /// Propose to create a state of no-confidence in the current constitutional committee NoConfidence(Option), + /// Propose to update the members of the constitutional committee and/or its signature threshold and/or terms UpdateCommittee( Option, + /// Committee members to be removed Vec, + /// Committee members to be added AssocMap, + /// New quorum + Rational, ), + /// Propose to modify the constitution or its guardrail script NewConstitution(Option, Constitution), InfoAction, } @@ -180,9 +215,17 @@ pub enum ScriptPurpose { Minting(CurrencySymbol), Spending(TransactionInput), Rewarding(Credential), - Certifying(BigInt, TxCert), + Certifying( + /// 0-based index of the given `TxCert` in `the `tx_certs` field of the `TransactionInfo` + BigInt, + TxCert, + ), Voting(Voter), - Proposing(BigInt, ProtocolProcedure), + Proposing( + /// 0-based index of the given `ProposalProcedure` in `protocol_procedures` field of the `TransactionInfo` + BigInt, + ProtocolProcedure, + ), } #[derive(Clone, Debug, PartialEq, Eq, IsPlutusData)] From e96c707a6619a38fea8d7dab7c16cce410434906 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 19:46:30 +0800 Subject: [PATCH 27/38] more doc strings --- .../src/generators/correct/v3.rs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plutus-ledger-api/src/generators/correct/v3.rs b/plutus-ledger-api/src/generators/correct/v3.rs index e77cab2..afeea40 100644 --- a/plutus-ledger-api/src/generators/correct/v3.rs +++ b/plutus-ledger-api/src/generators/correct/v3.rs @@ -34,18 +34,22 @@ use super::{ v2::{arb_transaction_output, arb_tx_in_info}, }; +/// Strategy to generate cold committee credentials pub fn arb_cold_committee_credential() -> impl Strategy { arb_credential().prop_map(ColdCommitteeCredential) } +/// Strategy to generate hot committee credentials pub fn arb_hot_committee_credential() -> impl Strategy { arb_credential().prop_map(HotCommitteeCredential) } +/// Strategy to generate DRep credentials pub fn arb_d_rep_credential() -> impl Strategy { arb_credential().prop_map(DRepCredential) } +/// Strategy to generate DReps pub fn arb_d_rep() -> impl Strategy { prop_oneof![ arb_d_rep_credential().prop_map(DRep::DRep), @@ -54,6 +58,7 @@ pub fn arb_d_rep() -> impl Strategy { ] } +/// Strategy to generate delegatees pub fn arb_delegatee() -> impl Strategy { prop_oneof![ arb_stake_pub_key_hash().prop_map(Delegatee::Stake), @@ -62,6 +67,7 @@ pub fn arb_delegatee() -> impl Strategy { ] } +/// Strategy to generate tx certs pub fn arb_tx_cert() -> impl Strategy { prop_oneof![ (arb_staking_credential(), option::of(arb_lovelace())) @@ -86,6 +92,7 @@ pub fn arb_tx_cert() -> impl Strategy { ] } +/// Strategy to generate voters pub fn arb_voter() -> impl Strategy { prop_oneof![ arb_hot_committee_credential().prop_map(Voter::CommitteeVoter), @@ -94,10 +101,12 @@ pub fn arb_voter() -> impl Strategy { ] } +/// Strategy to generate votes pub fn arb_vote() -> impl Strategy { prop_oneof![Just(Vote::VoteNo), Just(Vote::VoteYes), Just(Vote::Abstain)] } +/// Strategy to generate governance action ids pub fn arb_governance_action_id() -> impl Strategy { (arb_transaction_hash(), arb_integer()).prop_map(|(tx_id, gov_action_id)| GovernanceActionId { tx_id, @@ -105,6 +114,7 @@ pub fn arb_governance_action_id() -> impl Strategy { }) } +/// Strategy to generate committees pub fn arb_committee() -> impl Strategy { ( arb_assoc_map(arb_cold_committee_credential(), arb_integer()), @@ -113,24 +123,29 @@ pub fn arb_committee() -> impl Strategy { .prop_map(|(members, quorum)| Committee { members, quorum }) } +/// Strategy to generate rationals pub fn arb_rational() -> impl Strategy { (arb_integer(), arb_integer()).prop_map(|(n, d)| Rational(n, d)) } +/// Strategy to generate constitutions pub fn arb_constitution() -> impl Strategy { option::of(arb_script_hash()).prop_map(|constitution_script| Constitution { constitution_script, }) } +/// Strategy to generate protocol versions pub fn arb_protocol_version() -> impl Strategy { - (arb_integer(), arb_integer()).prop_map(|(major, minor)| ProtocolVersion { major, minor }) + (arb_natural(1), arb_natural(1)).prop_map(|(major, minor)| ProtocolVersion { major, minor }) } +/// Strategy to generate change parameters pub fn arb_change_parameters() -> impl Strategy { arb_plutus_data().prop_map(ChangeParameters) } +/// Strategy to generate governance actions pub fn arb_governance_action() -> impl Strategy { prop_oneof![ ( @@ -163,6 +178,7 @@ pub fn arb_governance_action() -> impl Strategy { ] } +/// Strategy to generate protocol procedures pub fn arb_protocol_procedure() -> impl Strategy { (arb_lovelace(), arb_credential(), arb_governance_action()).prop_map(|(l, c, g)| { ProtocolProcedure { @@ -173,6 +189,7 @@ pub fn arb_protocol_procedure() -> impl Strategy { }) } +/// Strategy to generate script purposes pub fn arb_script_purpose() -> impl Strategy { prop_oneof![ arb_currency_symbol().prop_map(ScriptPurpose::Minting), @@ -184,6 +201,7 @@ pub fn arb_script_purpose() -> impl Strategy { ] } +/// Strategy to generate script info pub fn arb_script_info() -> impl Strategy { prop_oneof![ arb_currency_symbol().prop_map(ScriptInfo::Minting), @@ -196,6 +214,7 @@ pub fn arb_script_info() -> impl Strategy { ] } +/// Strategy to generate transaction info pub fn arb_transaction_info() -> impl Strategy { ( vec(arb_tx_in_info(), 5), @@ -258,6 +277,7 @@ pub fn arb_transaction_info() -> impl Strategy { ) } +/// Strategy to generate script contexts pub fn arb_script_context() -> impl Strategy { (arb_transaction_info(), arb_redeemer(), arb_script_info()).prop_map( |(tx_info, redeemer, script_info)| ScriptContext { From cf119bae80e02641beb5d23e59fbb5027bd1adef Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 19:47:50 +0800 Subject: [PATCH 28/38] even more doc strings --- plutus-ledger-api/src/generators/correct/v3.rs | 4 ++++ plutus-ledger-api/src/v3/ratio.rs | 2 ++ plutus-ledger-api/src/v3/transaction.rs | 2 ++ 3 files changed, 8 insertions(+) diff --git a/plutus-ledger-api/src/generators/correct/v3.rs b/plutus-ledger-api/src/generators/correct/v3.rs index afeea40..6e7f5bc 100644 --- a/plutus-ledger-api/src/generators/correct/v3.rs +++ b/plutus-ledger-api/src/generators/correct/v3.rs @@ -1,3 +1,7 @@ +//! Proptest strategies for Plutus V3 types +//! +//! These strategies always return valid values. + use proptest::{ collection::vec, option, diff --git a/plutus-ledger-api/src/v3/ratio.rs b/plutus-ledger-api/src/v3/ratio.rs index 55c4670..c134719 100644 --- a/plutus-ledger-api/src/v3/ratio.rs +++ b/plutus-ledger-api/src/v3/ratio.rs @@ -1,3 +1,5 @@ +//! Types related to rational values + #[cfg(feature = "lbf")] use lbr_prelude::json::Json; use num_bigint::BigInt; diff --git a/plutus-ledger-api/src/v3/transaction.rs b/plutus-ledger-api/src/v3/transaction.rs index 9772d5b..68cf998 100644 --- a/plutus-ledger-api/src/v3/transaction.rs +++ b/plutus-ledger-api/src/v3/transaction.rs @@ -1,3 +1,5 @@ +//! Types related to Cardano transactions. + #[cfg(feature = "lbf")] use lbr_prelude::json::Json; use num_bigint::BigInt; From 413e2e7515a1d6e1a4fc04d19a676cbca1c34bc2 Mon Sep 17 00:00:00 2001 From: Hongrui Fang Date: Mon, 21 Oct 2024 20:47:54 +0800 Subject: [PATCH 29/38] update changelog --- plutus-ledger-api/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index 325603b..1356792 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -8,6 +8,7 @@ Changelog](https://keepachangelog.com/en/1.1.0). ### Added +- Added v3 plutus ledger types ([#57](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/57)) - Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) ### Changed From 0f7507c236157e598a6ac2b67e88981084840c1d Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 09:43:07 +0100 Subject: [PATCH 30/38] Reexport v2 types in v3 module --- plutus-ledger-api/src/v3/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plutus-ledger-api/src/v3/mod.rs b/plutus-ledger-api/src/v3/mod.rs index 8c73a0c..6350950 100644 --- a/plutus-ledger-api/src/v3/mod.rs +++ b/plutus-ledger-api/src/v3/mod.rs @@ -1,2 +1,15 @@ +//! Plutus types and utilities for Plutus V3 +//! +//! Types and utilities unchanged in the new version are re-exported from the v2 module. pub mod ratio; pub mod transaction; + +// Inherited from v2 +pub use crate::v2::address; +pub use crate::v2::assoc_map; +pub use crate::v2::crypto; +pub use crate::v2::datum; +pub use crate::v2::interval; +pub use crate::v2::redeemer; +pub use crate::v2::script; +pub use crate::v2::value; From 71cf0961d529d28a8b78672224d6a4c260e2a9f4 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 10:30:16 +0100 Subject: [PATCH 31/38] Implement golden tests for Display implementations --- plutus-ledger-api/src/goldens/v1.rs | 2 +- plutus-ledger-api/src/v1/value.rs | 53 +++++++----- plutus-ledger-api/tests/display.rs | 84 +++++++++++++++++++ .../tests/testdata/v1_address_display.golden | 1 + .../testdata/v1_address_display_1.golden | 1 + .../testdata/v1_address_display_2.golden | 1 + .../testdata/v1_asset_class_display.golden | 1 + .../v1_currency_symbol_display_1.golden | 1 + .../v1_currency_symbol_display_2.golden | 0 .../v1_currency_symbol_display_3.golden | 1 + .../testdata/v1_token_name_display_1.golden | 1 + .../testdata/v1_token_name_display_2.golden | 1 + .../testdata/v1_token_name_display_3.golden | 1 + .../testdata/v1_token_name_display_4.golden | 1 + .../v1_transaction_input_display.golden | 1 + .../tests/testdata/v1_value_display_1.golden | 1 + .../tests/testdata/v1_value_display_2.golden | 1 + 17 files changed, 131 insertions(+), 21 deletions(-) create mode 100644 plutus-ledger-api/tests/display.rs create mode 100644 plutus-ledger-api/tests/testdata/v1_address_display.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_address_display_1.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_address_display_2.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_asset_class_display.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_currency_symbol_display_2.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_currency_symbol_display_3.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_token_name_display_1.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_token_name_display_2.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_token_name_display_3.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_token_name_display_4.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_transaction_input_display.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_value_display_1.golden create mode 100644 plutus-ledger-api/tests/testdata/v1_value_display_2.golden diff --git a/plutus-ledger-api/src/goldens/v1.rs b/plutus-ledger-api/src/goldens/v1.rs index 09b24b0..843b25b 100644 --- a/plutus-ledger-api/src/goldens/v1.rs +++ b/plutus-ledger-api/src/goldens/v1.rs @@ -39,7 +39,7 @@ pub fn sample_value() -> Value { &sample_currency_symbol(), &sample_token_name(), &BigInt::from(123), - ) + ) + Value::ada_value(&BigInt::from(234)) } pub fn sample_plutus_interval() -> PlutusInterval { diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index 045d49d..f445a3d 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -41,20 +41,16 @@ pub enum CurrencySymbol { impl fmt::Display for CurrencySymbol { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let asset_class_str = match self { + match self { CurrencySymbol::Ada => { if f.alternate() { - "lovelace".to_string() + write!(f, "lovelace") } else { - "".to_string() + write!(f, "") } } - CurrencySymbol::NativeToken(symbol) => { - format!("{}", symbol.0 .0) - } - }; - - write!(f, "{}", asset_class_str) + CurrencySymbol::NativeToken(symbol) => write!(f, "{}", symbol.0 .0), + } } } @@ -293,26 +289,43 @@ impl Value { .collect(), ) } + + /// Create a vector with each distinct value + pub fn flatten(&self) -> Vec<(&CurrencySymbol, &TokenName, &BigInt)> { + self.0 + .iter() + .flat_map(|(currency_symbol, assets)| { + assets + .iter() + .map(move |(token_name, amount)| (currency_symbol, token_name, amount)) + }) + .collect() + } } impl fmt::Display for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let value_str = self + let mut it = self .0 .iter() .flat_map(|(currency_symbol, assets)| { - assets.iter().map(move |(token_name, amount)| { - if token_name.is_empty() { - format!("{} {}", currency_symbol, amount) - } else { - format!("{}.{} {}", currency_symbol, token_name, amount) - } - }) + assets + .iter() + .map(move |(token_name, amount)| (currency_symbol, token_name, amount)) }) - .collect::>() - .join("+"); + .peekable(); + while let Some((cur_sym, tn, amount)) = it.next() { + if tn.is_empty() { + write!(f, "{} {}", cur_sym, amount)?; + } else { + write!(f, "{}.{} {}", cur_sym, tn, amount)?; + } + if it.peek().is_some() { + write!(f, "+")?; + } + } - write!(f, "{}", value_str) + Ok(()) } } diff --git a/plutus-ledger-api/tests/display.rs b/plutus-ledger-api/tests/display.rs new file mode 100644 index 0000000..a746a62 --- /dev/null +++ b/plutus-ledger-api/tests/display.rs @@ -0,0 +1,84 @@ +#[cfg(test)] +mod display_serialisation_tests { + mod golden_v1 { + use plutus_ledger_api::{ + goldens::v1::{ + sample_address, sample_asset_class, sample_currency_symbol, + sample_transaction_input, sample_value, + }, + v1::value::CurrencySymbol, + v3::value::TokenName, + }; + + #[test] + fn v1_currency_symbol_display_1() { + goldie::assert!(format!("{}", sample_currency_symbol())) + } + + #[test] + fn v1_currency_symbol_display_2() { + goldie::assert!(format!("{}", CurrencySymbol::Ada)) + } + + #[test] + fn v1_currency_symbol_display_3() { + goldie::assert!(format!("{:#}", CurrencySymbol::Ada)) + } + + #[test] + fn v1_token_name_display_1() { + goldie::assert!(format!( + "{}", + TokenName::from_bytes(vec![255, 244, 233, 222]) + )) + } + + #[test] + fn v1_token_name_display_2() { + goldie::assert!(format!("{}", TokenName::from_string("TestToken"))) + } + + #[test] + fn v1_token_name_display_3() { + goldie::assert!(format!( + "{:#}", + TokenName::from_bytes(vec![255, 244, 233, 222]) + )) + } + + #[test] + fn v1_token_name_display_4() { + goldie::assert!(format!("{:#}", TokenName::from_string("TestToken"))) + } + + #[test] + fn v1_asset_class_display() { + goldie::assert!(format!("{}", sample_asset_class())) + } + + #[test] + fn v1_value_display_1() { + goldie::assert!(format!("{}", sample_value())) + } + + #[test] + fn v1_value_display_2() { + goldie::assert!(format!("{:#}", sample_value())) + } + + #[test] + fn v1_address_display_1() { + goldie::assert!(format!("{}", sample_address().with_extra_info(0))) + } + + #[test] + fn v1_address_display_2() { + goldie::assert!(format!("{}", sample_address().with_extra_info(1))) + } + + #[test] + fn v1_transaction_input_display() { + goldie::assert!(format!("{}", sample_transaction_input())) + } + } +} diff --git a/plutus-ledger-api/tests/testdata/v1_address_display.golden b/plutus-ledger-api/tests/testdata/v1_address_display.golden new file mode 100644 index 0000000..f8310f0 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_address_display.golden @@ -0,0 +1 @@ +addr_test1yqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsjen49f \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_address_display_1.golden b/plutus-ledger-api/tests/testdata/v1_address_display_1.golden new file mode 100644 index 0000000..f8310f0 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_address_display_1.golden @@ -0,0 +1 @@ +addr_test1yqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsjen49f \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_address_display_2.golden b/plutus-ledger-api/tests/testdata/v1_address_display_2.golden new file mode 100644 index 0000000..fe6e8e1 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_address_display_2.golden @@ -0,0 +1 @@ +addr1yyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs30w4fk \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden b/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden new file mode 100644 index 0000000..3460266 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden @@ -0,0 +1 @@ +00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden new file mode 100644 index 0000000..f1423ce --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden @@ -0,0 +1 @@ +00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_2.golden b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_2.golden new file mode 100644 index 0000000..e69de29 diff --git a/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_3.golden b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_3.golden new file mode 100644 index 0000000..cf33dc1 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_3.golden @@ -0,0 +1 @@ +lovelace \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_token_name_display_1.golden b/plutus-ledger-api/tests/testdata/v1_token_name_display_1.golden new file mode 100644 index 0000000..488c931 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_token_name_display_1.golden @@ -0,0 +1 @@ +fff4e9de \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_token_name_display_2.golden b/plutus-ledger-api/tests/testdata/v1_token_name_display_2.golden new file mode 100644 index 0000000..820efda --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_token_name_display_2.golden @@ -0,0 +1 @@ +54657374546f6b656e \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_token_name_display_3.golden b/plutus-ledger-api/tests/testdata/v1_token_name_display_3.golden new file mode 100644 index 0000000..9c98efe --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_token_name_display_3.golden @@ -0,0 +1 @@ +0xfff4e9de \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_token_name_display_4.golden b/plutus-ledger-api/tests/testdata/v1_token_name_display_4.golden new file mode 100644 index 0000000..74dc4fb --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_token_name_display_4.golden @@ -0,0 +1 @@ +TestToken \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_transaction_input_display.golden b/plutus-ledger-api/tests/testdata/v1_transaction_input_display.golden new file mode 100644 index 0000000..a7af387 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_transaction_input_display.golden @@ -0,0 +1 @@ +0000000000000000000000000000000000000000000000000000000000000000#3 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_1.golden b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden new file mode 100644 index 0000000..7e19090 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden @@ -0,0 +1 @@ + 234+00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 123 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_2.golden b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden new file mode 100644 index 0000000..7e19090 --- /dev/null +++ b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden @@ -0,0 +1 @@ + 234+00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 123 \ No newline at end of file From ae25646c97a5194cf433d2313c9a178bdf87a865 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 11:31:25 +0100 Subject: [PATCH 32/38] Update goldens --- .../tests/testdata/v1_script_context.golden | 68 +++++++++++++++ .../tests/testdata/v1_transaction_info.golden | 68 +++++++++++++++ .../testdata/v1_transaction_output.golden | 17 ++++ .../tests/testdata/v1_tx_in_info.golden | 17 ++++ .../tests/testdata/v1_value.golden | 17 ++++ .../tests/testdata/v2_script_context.golden | 85 +++++++++++++++++++ .../tests/testdata/v2_transaction_info.golden | 85 +++++++++++++++++++ .../testdata/v2_transaction_output.golden | 17 ++++ .../tests/testdata/v2_tx_in_info.golden | 17 ++++ 9 files changed, 391 insertions(+) diff --git a/plutus-ledger-api/tests/testdata/v1_script_context.golden b/plutus-ledger-api/tests/testdata/v1_script_context.golden index b3be0f2..7bcafe7 100644 --- a/plutus-ledger-api/tests/testdata/v1_script_context.golden +++ b/plutus-ledger-api/tests/testdata/v1_script_context.golden @@ -152,6 +152,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -353,6 +370,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -458,6 +492,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -518,6 +569,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v1_transaction_info.golden b/plutus-ledger-api/tests/testdata/v1_transaction_info.golden index 4d6d21b..65e6ddd 100644 --- a/plutus-ledger-api/tests/testdata/v1_transaction_info.golden +++ b/plutus-ledger-api/tests/testdata/v1_transaction_info.golden @@ -149,6 +149,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -350,6 +367,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -455,6 +489,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -515,6 +566,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v1_transaction_output.golden b/plutus-ledger-api/tests/testdata/v1_transaction_output.golden index 0a98a9d..2cb5107 100644 --- a/plutus-ledger-api/tests/testdata/v1_transaction_output.golden +++ b/plutus-ledger-api/tests/testdata/v1_transaction_output.golden @@ -92,6 +92,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden b/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden index a394d41..0910787 100644 --- a/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden +++ b/plutus-ledger-api/tests/testdata/v1_tx_in_info.golden @@ -144,6 +144,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v1_value.golden b/plutus-ledger-api/tests/testdata/v1_value.golden index ac756e7..d57efd6 100644 --- a/plutus-ledger-api/tests/testdata/v1_value.golden +++ b/plutus-ledger-api/tests/testdata/v1_value.golden @@ -1,5 +1,22 @@ Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v2_script_context.golden b/plutus-ledger-api/tests/testdata/v2_script_context.golden index f44208a..4dc8879 100644 --- a/plutus-ledger-api/tests/testdata/v2_script_context.golden +++ b/plutus-ledger-api/tests/testdata/v2_script_context.golden @@ -152,6 +152,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -424,6 +441,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -644,6 +678,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -768,6 +819,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -828,6 +896,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v2_transaction_info.golden b/plutus-ledger-api/tests/testdata/v2_transaction_info.golden index 9ac751d..9c4381d 100644 --- a/plutus-ledger-api/tests/testdata/v2_transaction_info.golden +++ b/plutus-ledger-api/tests/testdata/v2_transaction_info.golden @@ -149,6 +149,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -421,6 +438,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -641,6 +675,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -765,6 +816,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ @@ -825,6 +893,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v2_transaction_output.golden b/plutus-ledger-api/tests/testdata/v2_transaction_output.golden index e7110a7..373f646 100644 --- a/plutus-ledger-api/tests/testdata/v2_transaction_output.golden +++ b/plutus-ledger-api/tests/testdata/v2_transaction_output.golden @@ -92,6 +92,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ diff --git a/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden b/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden index d07191e..9aa6ad7 100644 --- a/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden +++ b/plutus-ledger-api/tests/testdata/v2_tx_in_info.golden @@ -144,6 +144,23 @@ Constr( ), Map( [ + ( + Bytes( + [], + ), + Map( + [ + ( + Bytes( + [], + ), + Integer( + 234, + ), + ), + ], + ), + ), ( Bytes( [ From 489969676f703a79652d6567436f0fc5181a3694 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 11:39:44 +0100 Subject: [PATCH 33/38] Update deps --- plutus-ledger-api/Cargo.lock | 92 ++++++++++++++++++------------------ plutus-ledger-api/Cargo.toml | 4 +- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 007ded4..31391db 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "autocfg" @@ -97,9 +97,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cardano-serialization-lib" -version = "12.1.0" +version = "12.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfd14f5a2250d86a3c673a70c49851c21207ee8537f9f11b3dba9cc67095ef7" +checksum = "72a6b87191e22d30d2fd9cf52a8db1acd0611d119f432e3dc676650c76f67840" dependencies = [ "bech32", "cbor_event", @@ -137,9 +137,9 @@ checksum = "089a0261d1bc59e54e8e11860031efd88593f0e61b921172c474f1f38c2f2d3c" [[package]] name = "cc" -version = "1.1.24" +version = "1.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" dependencies = [ "shlex", ] @@ -340,9 +340,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hashlink" @@ -361,9 +361,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -395,7 +395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -425,9 +425,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -467,15 +467,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linked-hash-map" @@ -595,12 +595,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -610,7 +607,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "plutus-ledger-api" -version = "2.0.0-beta.1" +version = "2.0.0" dependencies = [ "anyhow", "cardano-serialization-lib", @@ -629,12 +626,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -656,9 +647,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -784,9 +775,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", @@ -839,9 +830,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] @@ -859,9 +850,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -881,9 +872,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -921,15 +912,21 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "target-triple" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078" + [[package]] name = "tempfile" version = "3.13.0" @@ -954,18 +951,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -1008,15 +1005,16 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.99" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" +checksum = "8dcd332a5496c026f1e14b7f3d2b7bd98e509660c04239c58b0ba38a12daded4" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", + "target-triple", "termcolor", "toml", ] diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index 0ff63de..c1788c4 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plutus-ledger-api" -version = "2.0.0-beta.1" +version = "2.0.0" edition = "2021" license = "Apache-2.0" description = "Plutus Ledger types and utilities implemented in Rust" @@ -20,7 +20,7 @@ linked-hash-map = "~0.5.6" num-traits = "~0.2.17" impl_ops = "0.1.1" chrono = { version = "0.4.34", optional = true } -cardano-serialization-lib = "12.1.0" +cardano-serialization-lib = "12.1.1" is-plutus-data-derive = { path = ".extras/is-plutus-data-derive-0" } anyhow = "1.0.86" From d09a7312684e38a26e601809dd26db6562470dcf Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 11:39:54 +0100 Subject: [PATCH 34/38] Update CHANGELOG --- plutus-ledger-api/CHANGELOG.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index 1356792..83f2538 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -4,27 +4,20 @@ This changelog is based on [Keep A Changelog](https://keepachangelog.com/en/1.1.0). -## Unreleased - -### Added - -- Added v3 plutus ledger types ([#57](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/57)) -- Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) - -### Changed - -### Removed - ## v2.0.0 ### Added - Added cardano-serialization-lib conversion traits (`ToCSL` and `FromCSL`) +- Added v3 plutus ledger types ([#57](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/57)) +- Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) +- Added a few utility functions for Values +- Added Display and Debug implementations for CurrencySymbol, TokenName, Value, AddressWithExtraInfo ### Changed - Fixed `serde` serialization of Plutus `Value`s -- Updated cardano-serialization-lib to Conway compatible 12.1.0 +- Updated cardano-serialization-lib to Conway compatible 12.1.1 ## v1.0.0 From 1acaa8b348c02e21880091e2dc372bb01e718a4a Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Tue, 5 Nov 2024 17:36:47 +0100 Subject: [PATCH 35/38] Add FromStr parsers --- plutus-ledger-api/CHANGELOG.md | 5 +- plutus-ledger-api/Cargo.lock | 17 ++ plutus-ledger-api/Cargo.toml | 1 + plutus-ledger-api/src/{utils => }/aux.rs | 31 +++ plutus-ledger-api/src/error.rs | 47 +++++ plutus-ledger-api/src/goldens/v1.rs | 2 +- plutus-ledger-api/src/lib.rs | 3 +- plutus-ledger-api/src/utils/mod.rs | 1 - plutus-ledger-api/src/v1/crypto.rs | 34 +++ plutus-ledger-api/src/v1/script.rs | 43 ++++ plutus-ledger-api/src/v1/transaction.rs | 73 ++++++- plutus-ledger-api/src/v1/value.rs | 197 ++++++++++++++++-- .../tests/display.proptest-regressions | 8 + plutus-ledger-api/tests/display.rs | 67 +++++- .../testdata/v1_asset_class_display.golden | 2 +- .../v1_currency_symbol_display_1.golden | 2 +- .../tests/testdata/v1_value_display_1.golden | 2 +- .../tests/testdata/v1_value_display_2.golden | 2 +- 18 files changed, 506 insertions(+), 31 deletions(-) rename plutus-ledger-api/src/{utils => }/aux.rs (61%) create mode 100644 plutus-ledger-api/src/error.rs delete mode 100644 plutus-ledger-api/src/utils/mod.rs create mode 100644 plutus-ledger-api/tests/display.proptest-regressions diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index 83f2538..2964b75 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -12,7 +12,10 @@ Changelog](https://keepachangelog.com/en/1.1.0). - Added v3 plutus ledger types ([#57](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/57)) - Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) - Added a few utility functions for Values -- Added Display and Debug implementations for CurrencySymbol, TokenName, Value, AddressWithExtraInfo +- Added Display and Debug implementations for + CurrencySymbol, TokenName, Value, AddressWithExtraInfo and some other types +- Added FromStr implementations for CurrencySymbol, TokenName, Value, Address + and some other types ### Changed diff --git a/plutus-ledger-api/Cargo.lock b/plutus-ledger-api/Cargo.lock index 31391db..a4455ab 100644 --- a/plutus-ledger-api/Cargo.lock +++ b/plutus-ledger-api/Cargo.lock @@ -501,6 +501,22 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "noop_proc_macro" version = "0.3.0" @@ -618,6 +634,7 @@ dependencies = [ "is-plutus-data-derive", "lbr-prelude", "linked-hash-map", + "nom", "num-bigint", "num-traits", "proptest", diff --git a/plutus-ledger-api/Cargo.toml b/plutus-ledger-api/Cargo.toml index c1788c4..9164feb 100644 --- a/plutus-ledger-api/Cargo.toml +++ b/plutus-ledger-api/Cargo.toml @@ -23,6 +23,7 @@ chrono = { version = "0.4.34", optional = true } cardano-serialization-lib = "12.1.1" is-plutus-data-derive = { path = ".extras/is-plutus-data-derive-0" } anyhow = "1.0.86" +nom = "7.1.3" [features] default = [] diff --git a/plutus-ledger-api/src/utils/aux.rs b/plutus-ledger-api/src/aux.rs similarity index 61% rename from plutus-ledger-api/src/utils/aux.rs rename to plutus-ledger-api/src/aux.rs index e640842..c98c930 100644 --- a/plutus-ledger-api/src/utils/aux.rs +++ b/plutus-ledger-api/src/aux.rs @@ -1,8 +1,22 @@ use std::{ collections::BTreeMap, iter::{empty, once}, + str::FromStr, }; +use nom::{ + branch::alt, + character::complete::{char, digit1}, + combinator::{map_res, opt, recognize}, + error::VerboseError, + multi::many1, + sequence::tuple, + IResult, +}; +use num_bigint::BigInt; + +use crate::error::ConversionError; + /// Create a container C from one element. pub fn singleton(value: T) -> C where @@ -50,3 +64,20 @@ pub fn union_b_tree_maps_with, expected: usize) -> Result, ConversionError> { + if bytes.len() == expected { + Ok(bytes) + } else { + Err(ConversionError::invalid_bytestring_length( + ctx, expected, "equal to", &bytes, + )) + } +} + +pub(crate) fn big_int(i: &str) -> IResult<&str, BigInt, VerboseError<&str>> { + map_res( + recognize(tuple((opt(alt((char('-'), char('+')))), many1(digit1)))), + |s: &str| BigInt::from_str(s), + )(i) +} diff --git a/plutus-ledger-api/src/error.rs b/plutus-ledger-api/src/error.rs new file mode 100644 index 0000000..ec2cb73 --- /dev/null +++ b/plutus-ledger-api/src/error.rs @@ -0,0 +1,47 @@ +use data_encoding::HEXLOWER; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ConversionError { + #[error("ByteString length must be {relation} {expected} but got {got} with value{value_hex}")] + InvalidByteStringLength { + ctx: String, + expected: usize, + got: usize, + value_hex: String, + relation: String, + }, + + #[error("String cannot be parsed as a hexadecimal value: {value_hex}")] + HexDecodeError { + value_hex: String, + source: data_encoding::DecodeError, + }, + + #[error(transparent)] + ParseError(anyhow::Error), +} + +impl ConversionError { + pub fn invalid_bytestring_length( + ctx: &str, + expected: usize, + relation: &str, + bytes: &[u8], + ) -> Self { + ConversionError::InvalidByteStringLength { + ctx: ctx.to_string(), + expected, + got: bytes.len(), + relation: relation.to_string(), + value_hex: HEXLOWER.encode(bytes), + } + } + + pub fn hex_decode_error(err: data_encoding::DecodeError, value_hex: &str) -> Self { + ConversionError::HexDecodeError { + source: err, + value_hex: value_hex.to_string(), + } + } +} diff --git a/plutus-ledger-api/src/goldens/v1.rs b/plutus-ledger-api/src/goldens/v1.rs index 02fd57a..5413c80 100644 --- a/plutus-ledger-api/src/goldens/v1.rs +++ b/plutus-ledger-api/src/goldens/v1.rs @@ -27,7 +27,7 @@ pub fn sample_currency_symbol() -> CurrencySymbol { } pub fn sample_token_name() -> TokenName { - TokenName::from_string("Something") + TokenName::from_string("Something").unwrap() } pub fn sample_asset_class() -> AssetClass { diff --git a/plutus-ledger-api/src/lib.rs b/plutus-ledger-api/src/lib.rs index e788cad..c65bb28 100644 --- a/plutus-ledger-api/src/lib.rs +++ b/plutus-ledger-api/src/lib.rs @@ -9,8 +9,9 @@ pub mod v2; pub mod v3; #[cfg(feature = "lbf")] pub use lbr_prelude::json; +pub mod aux; pub mod csl; -pub mod utils; +pub mod error; #[macro_use] extern crate impl_ops; diff --git a/plutus-ledger-api/src/utils/mod.rs b/plutus-ledger-api/src/utils/mod.rs deleted file mode 100644 index a8a7dcd..0000000 --- a/plutus-ledger-api/src/utils/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod aux; diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index 6565e1a..c7e7ee8 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -3,10 +3,12 @@ use cardano_serialization_lib as csl; use data_encoding::HEXLOWER; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json}; +use nom::{combinator::map_res, error::VerboseError, IResult}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use crate as plutus_ledger_api; +use crate::error::ConversionError; use crate::{ csl::{ csl_to_pla::FromCSL, @@ -93,6 +95,38 @@ impl std::fmt::Display for LedgerBytes { } } +pub(crate) fn ledger_bytes(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { + map_res(nom::character::complete::hex_digit0, |hex_bytes: &str| { + HEXLOWER + .decode(&hex_bytes.to_owned().to_ascii_lowercase().into_bytes()) + .map(LedgerBytes) + })(input) +} + +pub(crate) fn hash28(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { + map_res(ledger_bytes, |bytes: LedgerBytes| { + if bytes.0.len() == 28 { + Ok(bytes) + } else { + Err(ConversionError::invalid_bytestring_length( + "hash28", 28, "equal to", &bytes.0, + )) + } + })(input) +} + +pub(crate) fn hash32(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { + map_res(ledger_bytes, |bytes: LedgerBytes| { + if bytes.0.len() == 32 { + Ok(bytes) + } else { + Err(ConversionError::invalid_bytestring_length( + "hash32", 32, "equal to", &bytes.0, + )) + } + })(input) +} + #[cfg(feature = "lbf")] impl Json for LedgerBytes { fn to_json(&self) -> serde_json::Value { diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index e3f73b9..f83b398 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -4,15 +4,22 @@ use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; +use nom::combinator::map; +use nom::error::{context, VerboseError}; +use nom::IResult; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use crate as plutus_ledger_api; +use crate::aux::guard_bytes; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::error::ConversionError; use crate::plutus_data::IsPlutusData; use crate::v1::crypto::LedgerBytes; +use super::crypto::hash28; + /////////////////// // ValidatorHash // /////////////////// @@ -30,6 +37,16 @@ impl FromCSL for ValidatorHash { } } +impl ValidatorHash { + pub fn from_bytes(bytes: Vec) -> Result { + Ok(ValidatorHash(ScriptHash::from_bytes(bytes)?)) + } +} + +pub(crate) fn validator_hash(input: &str) -> IResult<&str, ValidatorHash, VerboseError<&str>> { + context("validator_hash", map(script_hash, ValidatorHash))(input) +} + /////////////////////// // MintingPolicyHash // /////////////////////// @@ -41,6 +58,12 @@ impl FromCSL for ValidatorHash { #[cfg_attr(feature = "lbf", derive(Json))] pub struct MintingPolicyHash(pub ScriptHash); +impl MintingPolicyHash { + pub fn from_bytes(bytes: Vec) -> Result { + Ok(MintingPolicyHash(ScriptHash::from_bytes(bytes)?)) + } +} + impl FromCSL for MintingPolicyHash { fn from_csl(value: &csl::PolicyID) -> Self { MintingPolicyHash(ScriptHash(LedgerBytes(value.to_bytes()))) @@ -53,6 +76,12 @@ impl TryFromPLA for csl::PolicyID { } } +pub(crate) fn minting_policy_hash( + input: &str, +) -> IResult<&str, MintingPolicyHash, VerboseError<&str>> { + context("minting_policy_hash", map(script_hash, MintingPolicyHash))(input) +} + //////////////// // ScriptHash // //////////////// @@ -64,6 +93,16 @@ impl TryFromPLA for csl::PolicyID { #[cfg_attr(feature = "lbf", derive(Json))] pub struct ScriptHash(pub LedgerBytes); +impl ScriptHash { + pub fn from_bytes(bytes: Vec) -> Result { + Ok(ScriptHash(LedgerBytes(guard_bytes( + "ScriptHash", + bytes, + 28, + )?))) + } +} + impl FromCSL for ScriptHash { fn from_csl(value: &csl::ScriptHash) -> Self { ScriptHash(LedgerBytes(value.to_bytes())) @@ -76,3 +115,7 @@ impl TryFromPLA for csl::ScriptHash { .map_err(TryFromPLAError::CSLDeserializeError) } } + +pub(crate) fn script_hash(input: &str) -> IResult<&str, ScriptHash, VerboseError<&str>> { + context("script_hash", map(hash28, ScriptHash))(input) +} diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 2ef775e..21c18b6 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -1,27 +1,38 @@ //! Types related to Cardano transactions. -use std::fmt; +use std::{fmt, str::FromStr}; +use anyhow::anyhow; use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; +use nom::{ + character::complete::char, + combinator::{all_consuming, map}, + error::{context, VerboseError}, + sequence::preceded, + Finish, IResult, +}; use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use super::{ address::{Address, StakingCredential}, - crypto::{LedgerBytes, PaymentPubKeyHash}, + crypto::{hash32, LedgerBytes, PaymentPubKeyHash}, datum::{Datum, DatumHash}, interval::PlutusInterval, value::{CurrencySymbol, Value}, }; -use crate as plutus_ledger_api; -use crate::csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}; +use crate::{self as plutus_ledger_api, aux::big_int}; use crate::{ csl::pla_to_csl::{TryFromPLAError, TryToCSL}, plutus_data::IsPlutusData, }; +use crate::{ + csl::{csl_to_pla::FromCSL, pla_to_csl::TryFromPLA}, + error::ConversionError, +}; ////////////////////// // TransactionInput // @@ -82,6 +93,39 @@ impl TryFromPLA> for csl::TransactionInputs { } } +pub(crate) fn transaction_input( + input: &str, +) -> IResult<&str, TransactionInput, VerboseError<&str>> { + let (input, tx_id) = transaction_hash(input)?; + + let (input, idx) = preceded(char('#'), big_int)(input)?; + + Ok(( + input, + TransactionInput { + transaction_id: tx_id, + index: idx, + }, + )) +} + +impl FromStr for TransactionInput { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + all_consuming(transaction_input)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!( + "Error while parsing TransactionInput '{}': {}", + s, + err + )) + }) + .map(|(_, cs)| cs) + } +} + ///////////////////// // TransactionHash // ///////////////////// @@ -115,6 +159,27 @@ impl TryFromPLA for csl::TransactionHash { } } +pub(crate) fn transaction_hash(input: &str) -> IResult<&str, TransactionHash, VerboseError<&str>> { + context("transaction_hash", map(hash32, TransactionHash))(input) +} + +impl FromStr for TransactionHash { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + all_consuming(transaction_hash)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!( + "Error while parsing TransactionHash '{}': {}", + s, + err + )) + }) + .map(|(_, cs)| cs) + } +} + /////////////////////// // TransactionOutput // /////////////////////// diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index f445a3d..a72907d 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -1,5 +1,6 @@ //! Types related to Cardano values, such as Ada and native tokens. +use std::str::FromStr; use std::string::String; use std::{ collections::BTreeMap, @@ -8,9 +9,20 @@ use std::{ }; use std::{fmt, ops}; +use anyhow::anyhow; use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json, JsonType}; +use nom::{ + branch::alt, + character::complete::{char, space0}, + combinator::{all_consuming, eof, map, map_res, success}, + error::{context, VerboseError}, + multi::separated_list0, + sequence::preceded, + sequence::tuple, + Finish, IResult, +}; use num_bigint::BigInt; use num_traits::Zero; #[cfg(feature = "serde")] @@ -19,13 +31,17 @@ use serde::{Deserialize, Serialize}; use serde_json; use crate as plutus_ledger_api; +use crate::aux::{big_int, singleton, union_b_tree_maps_with, union_btree_maps_with}; use crate::csl::csl_to_pla::FromCSL; use crate::csl::pla_to_csl::{TryFromPLA, TryFromPLAError, TryToCSL}; +use crate::error::ConversionError; use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError}; -use crate::utils::aux::{singleton, union_b_tree_maps_with, union_btree_maps_with}; use crate::v1::crypto::LedgerBytes; use crate::v1::script::{MintingPolicyHash, ScriptHash}; +use super::crypto::ledger_bytes; +use super::script::minting_policy_hash; + //////////////////// // CurrencySymbol // //////////////////// @@ -39,6 +55,18 @@ pub enum CurrencySymbol { NativeToken(MintingPolicyHash), } +impl CurrencySymbol { + pub fn from_bytes(bytes: Vec) -> Result { + if bytes.is_empty() { + Ok(CurrencySymbol::Ada) + } else { + Ok(CurrencySymbol::NativeToken(MintingPolicyHash::from_bytes( + bytes, + )?)) + } + } +} + impl fmt::Display for CurrencySymbol { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -54,11 +82,28 @@ impl fmt::Display for CurrencySymbol { } } +impl FromStr for CurrencySymbol { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + all_consuming(currency_symbol)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!( + "Error while parsing CurrencySymbol '{}': {}", + s, + err + )) + }) + .map(|(_, cs)| cs) + } +} + impl IsPlutusData for CurrencySymbol { fn to_plutus_data(&self) -> PlutusData { match self { - CurrencySymbol::Ada => String::from("").to_plutus_data(), CurrencySymbol::NativeToken(policy_hash) => policy_hash.to_plutus_data(), + CurrencySymbol::Ada => String::from("").to_plutus_data(), } } @@ -100,6 +145,27 @@ impl Json for CurrencySymbol { } } +pub(crate) fn currency_symbol(input: &str) -> IResult<&str, CurrencySymbol, VerboseError<&str>> { + context( + "currency symbol", + alt(( + map_res(ledger_bytes, |bytes: LedgerBytes| { + if bytes.0.is_empty() { + Ok(CurrencySymbol::Ada) + } else { + Err(ConversionError::invalid_bytestring_length( + "currency_symbol_ada", + 0, + "equal to", + &bytes.0, + )) + } + }), + map(minting_policy_hash, CurrencySymbol::NativeToken), + )), + )(input) +} + /////////// // Value // /////////// @@ -301,6 +367,11 @@ impl Value { }) .collect() } + + pub fn unflatten(list: &[(CurrencySymbol, TokenName, BigInt)]) -> Self { + list.iter() + .fold(Value::new(), |v, (cs, tn, am)| v.insert_token(cs, tn, am)) + } } impl fmt::Display for Value { @@ -329,6 +400,37 @@ impl fmt::Display for Value { } } +pub(crate) fn flat_value( + input: &str, +) -> IResult<&str, (CurrencySymbol, TokenName, BigInt), VerboseError<&str>> { + let (input, cs) = currency_symbol(input)?; + + let (input, tn) = alt((preceded(char('.'), token_name), success(TokenName::ada())))(input)?; + + let (input, amount) = preceded(char(' '), big_int)(input)?; + + Ok((input, (cs, tn, amount))) +} + +pub(crate) fn value(input: &str) -> IResult<&str, Value, VerboseError<&str>> { + let (input, flat_values) = separated_list0(tuple((space0, char('+'))), flat_value)(input)?; + + Ok((input, Value::unflatten(&flat_values))) +} + +impl FromStr for Value { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + all_consuming(value)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!("Error while parsing Value '{}': {}", s, err)) + }) + .map(|(_, cs)| cs) + } +} + impl Zero for Value { fn zero() -> Self { Default::default() @@ -592,6 +694,7 @@ impl FromCSL for Value { pub struct TokenName(pub LedgerBytes); impl TokenName { + /// Ada tokenname (empty bytestring) pub fn ada() -> TokenName { TokenName(LedgerBytes(Vec::with_capacity(0))) } @@ -600,19 +703,62 @@ impl TokenName { self.0 .0.is_empty() } - pub fn from_bytes(bytes: Vec) -> Self { - TokenName(LedgerBytes(bytes)) + pub fn from_bytes(bytes: Vec) -> Result { + if bytes.len() <= 32 { + Ok(TokenName(LedgerBytes(bytes))) + } else { + Err(ConversionError::invalid_bytestring_length( + "TokenName", + 32, + "less than or equal to", + &bytes, + )) + } } - pub fn from_string(str: &str) -> Self { - TokenName(LedgerBytes(String::from(str).into_bytes())) + /// Convert a UTF8 string into a TokenName (use from_str to convert from a hexadecimal string) + pub fn from_string(str: &str) -> Result { + TokenName::from_bytes(String::from(str).into_bytes()) } + /// Convert TokenName to string if it is a valid UTF8 bytestring pub fn try_into_string(self) -> Result { String::from_utf8(self.0 .0) } } +impl FromStr for TokenName { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + all_consuming(token_name)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!( + "Error while parsing TokenName '{}': {}", + s, + err + )) + }) + .map(|(_, cs)| cs) + } +} + +pub(crate) fn token_name(input: &str) -> IResult<&str, TokenName, VerboseError<&str>> { + map_res(ledger_bytes, |bytes: LedgerBytes| { + if bytes.0.len() <= 32 { + Ok(TokenName(bytes)) + } else { + Err(ConversionError::invalid_bytestring_length( + "token_name", + 32, + "less than or equal to", + &bytes.0, + )) + } + })(input) +} + impl IsPlutusData for TokenName { fn to_plutus_data(&self) -> PlutusData { self.0.to_plutus_data() @@ -673,19 +819,40 @@ impl fmt::Display for AssetClass { } } -#[cfg(test)] -mod test { - use super::*; +impl FromStr for AssetClass { + type Err = ConversionError; - #[test] - fn to_from_string_token_name() { - let name = "Hello"; - let token_name = TokenName::from_string(name); - - assert_eq!(token_name.try_into_string().unwrap(), name); + fn from_str(s: &str) -> Result { + all_consuming(asset_class)(s) + .finish() + .map_err(|err| { + ConversionError::ParseError(anyhow!( + "Error while parsing AssetClass '{}': {}", + s, + err + )) + }) + .map(|(_, cs)| cs) } } +pub(crate) fn asset_class(input: &str) -> IResult<&str, AssetClass, VerboseError<&str>> { + let (input, cs) = currency_symbol(input)?; + + let (input, tn) = alt(( + preceded(eof, success(TokenName::ada())), + preceded(char('.'), token_name), + ))(input)?; + + Ok(( + input, + AssetClass { + currency_symbol: cs, + token_name: tn, + }, + )) +} + //////////////// // Lovelace // //////////////// diff --git a/plutus-ledger-api/tests/display.proptest-regressions b/plutus-ledger-api/tests/display.proptest-regressions new file mode 100644 index 0000000..193e2d7 --- /dev/null +++ b/plutus-ledger-api/tests/display.proptest-regressions @@ -0,0 +1,8 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc f28698f393b1933268f15226ce5938cff4237e12ddbc2a4a043362f4d8b53dd4 # shrinks to val = "ࡀA\u{ec8}a𑵐𞟨𐨀Ø\u{16d70}0ꫛ\u{fe20}" +cc dafca272147ae56cc689fcc524f9eacc984ab5edb7d8a870c3beaccff6c283cd # shrinks to val = Ada diff --git a/plutus-ledger-api/tests/display.rs b/plutus-ledger-api/tests/display.rs index a746a62..c0318aa 100644 --- a/plutus-ledger-api/tests/display.rs +++ b/plutus-ledger-api/tests/display.rs @@ -29,26 +29,29 @@ mod display_serialisation_tests { fn v1_token_name_display_1() { goldie::assert!(format!( "{}", - TokenName::from_bytes(vec![255, 244, 233, 222]) + TokenName::from_bytes(vec![255, 244, 233, 222]).unwrap() )) } #[test] fn v1_token_name_display_2() { - goldie::assert!(format!("{}", TokenName::from_string("TestToken"))) + goldie::assert!(format!("{}", TokenName::from_string("TestToken").unwrap())) } #[test] fn v1_token_name_display_3() { goldie::assert!(format!( "{:#}", - TokenName::from_bytes(vec![255, 244, 233, 222]) + TokenName::from_bytes(vec![255, 244, 233, 222]).unwrap() )) } #[test] fn v1_token_name_display_4() { - goldie::assert!(format!("{:#}", TokenName::from_string("TestToken"))) + goldie::assert!(format!( + "{:#}", + TokenName::from_string("TestToken").unwrap() + )) } #[test] @@ -81,4 +84,60 @@ mod display_serialisation_tests { goldie::assert!(format!("{}", sample_transaction_input())) } } + + mod props_v1 { + use std::{fmt::Display, str::FromStr}; + + use plutus_ledger_api::{ + generators::correct::v1::{ + arb_address, arb_asset_class, arb_currency_symbol, arb_transaction_input, arb_value, + }, + v1::{address::Address, value::TokenName}, + }; + use proptest::{prelude::*, string::string_regex}; + + fn from_to_string(val: &T) -> Result + where + T: FromStr + Display + PartialEq, + { + T::from_str(&val.to_string()) + } + + proptest! { + + #[test] + fn currency_symbol(val in arb_currency_symbol()) { + assert_eq!(val, from_to_string(&val)?); + } + + #[test] + fn token_name(val in string_regex("[a-zA-Z0-9]{0,32}").unwrap()) { + let token_name = TokenName::from_string(&val).unwrap(); + + assert_eq!(token_name.try_into_string().unwrap(), val); + } + + #[test] + fn asset_class(val in arb_asset_class()) { + assert_eq!(val, from_to_string(&val)?); + } + + #[test] + fn value(val in arb_value()) { + assert_eq!(val, from_to_string(&val)?); + } + + #[test] + fn address(val in arb_address()) { + let roundtripped = Address::from_str(&val.with_extra_info(0).to_string()).unwrap(); + + assert_eq!(val, roundtripped); + } + + #[test] + fn transaction_input(val in arb_transaction_input()) { + assert_eq!(val, from_to_string(&val)?); + } + } + } } diff --git a/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden b/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden index 3460266..d77aa17 100644 --- a/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden +++ b/plutus-ledger-api/tests/testdata/v1_asset_class_display.golden @@ -1 +1 @@ -00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 \ No newline at end of file +01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden index f1423ce..45e1797 100644 --- a/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden +++ b/plutus-ledger-api/tests/testdata/v1_currency_symbol_display_1.golden @@ -1 +1 @@ -00000000000000000000000000000000000000000000000000000000 \ No newline at end of file +01010101010101010101010101010101010101010101010101010101 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_1.golden b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden index 7e19090..d3e40d2 100644 --- a/plutus-ledger-api/tests/testdata/v1_value_display_1.golden +++ b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden @@ -1 +1 @@ - 234+00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 123 \ No newline at end of file + 234+01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 123 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_2.golden b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden index 7e19090..d3e40d2 100644 --- a/plutus-ledger-api/tests/testdata/v1_value_display_2.golden +++ b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden @@ -1 +1 @@ - 234+00000000000000000000000000000000000000000000000000000000.536f6d657468696e67 123 \ No newline at end of file + 234+01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 123 \ No newline at end of file From 36c41331f8aa274994525779f82243a03ab13a79 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 7 Nov 2024 14:57:15 +0100 Subject: [PATCH 36/38] Final touches before v2 --- plutus-ledger-api/CHANGELOG.md | 8 +- plutus-ledger-api/src/aux.rs | 9 +- plutus-ledger-api/src/v1/crypto.rs | 28 +--- plutus-ledger-api/src/v1/script.rs | 19 --- plutus-ledger-api/src/v1/transaction.rs | 50 ++++--- plutus-ledger-api/src/v1/value.rs | 127 +++++++++--------- plutus-ledger-api/src/v3/transaction.rs | 8 +- .../tests/display.proptest-regressions | 3 +- .../tests/testdata/v1_value_display_1.golden | 2 +- .../tests/testdata/v1_value_display_2.golden | 2 +- 10 files changed, 118 insertions(+), 138 deletions(-) diff --git a/plutus-ledger-api/CHANGELOG.md b/plutus-ledger-api/CHANGELOG.md index 2964b75..d40ac65 100644 --- a/plutus-ledger-api/CHANGELOG.md +++ b/plutus-ledger-api/CHANGELOG.md @@ -8,14 +8,14 @@ Changelog](https://keepachangelog.com/en/1.1.0). ### Added -- Added cardano-serialization-lib conversion traits (`ToCSL` and `FromCSL`) +- Added cardano-serialization-lib conversion traits (`ToCSL` and `FromCSL`) ([#55](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/55)) - Added v3 plutus ledger types ([#57](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/57)) - Added the ability to derive `IsPlutusData` instances ([#56](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/56)) -- Added a few utility functions for Values +- Added a few utility functions for Values ([#55](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/55)) - Added Display and Debug implementations for - CurrencySymbol, TokenName, Value, AddressWithExtraInfo and some other types + CurrencySymbol, TokenName, Value, AddressWithExtraInfo and some other types ([#55](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/55)) - Added FromStr implementations for CurrencySymbol, TokenName, Value, Address - and some other types + and some other types ([#55](https://github.com/mlabs-haskell/plutus-ledger-api-rust/pull/55)) ### Changed diff --git a/plutus-ledger-api/src/aux.rs b/plutus-ledger-api/src/aux.rs index c98c930..a432982 100644 --- a/plutus-ledger-api/src/aux.rs +++ b/plutus-ledger-api/src/aux.rs @@ -65,7 +65,12 @@ pub fn union_b_tree_maps_with, expected: usize) -> Result, ConversionError> { +/// Verify that a given bytestring has the expected length +pub(crate) fn guard_bytes( + ctx: &str, + bytes: Vec, + expected: usize, +) -> Result, ConversionError> { if bytes.len() == expected { Ok(bytes) } else { @@ -75,6 +80,8 @@ pub fn guard_bytes(ctx: &str, bytes: Vec, expected: usize) -> Result } } +/// Nom parser for BigInt +/// Expects an arbitrary length integer, optionally signed pub(crate) fn big_int(i: &str) -> IResult<&str, BigInt, VerboseError<&str>> { map_res( recognize(tuple((opt(alt((char('-'), char('+')))), many1(digit1)))), diff --git a/plutus-ledger-api/src/v1/crypto.rs b/plutus-ledger-api/src/v1/crypto.rs index c7e7ee8..25ed6bd 100644 --- a/plutus-ledger-api/src/v1/crypto.rs +++ b/plutus-ledger-api/src/v1/crypto.rs @@ -8,7 +8,6 @@ use nom::{combinator::map_res, error::VerboseError, IResult}; use serde::{Deserialize, Serialize}; use crate as plutus_ledger_api; -use crate::error::ConversionError; use crate::{ csl::{ csl_to_pla::FromCSL, @@ -95,6 +94,9 @@ impl std::fmt::Display for LedgerBytes { } } +/// Nom parser for LedgerBytes +/// Expects a hexadecimal string of arbitrary length (0 length is allowed) +/// E.g.: 00112233445566778899aabbcc pub(crate) fn ledger_bytes(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { map_res(nom::character::complete::hex_digit0, |hex_bytes: &str| { HEXLOWER @@ -103,30 +105,6 @@ pub(crate) fn ledger_bytes(input: &str) -> IResult<&str, LedgerBytes, VerboseErr })(input) } -pub(crate) fn hash28(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { - map_res(ledger_bytes, |bytes: LedgerBytes| { - if bytes.0.len() == 28 { - Ok(bytes) - } else { - Err(ConversionError::invalid_bytestring_length( - "hash28", 28, "equal to", &bytes.0, - )) - } - })(input) -} - -pub(crate) fn hash32(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> { - map_res(ledger_bytes, |bytes: LedgerBytes| { - if bytes.0.len() == 32 { - Ok(bytes) - } else { - Err(ConversionError::invalid_bytestring_length( - "hash32", 32, "equal to", &bytes.0, - )) - } - })(input) -} - #[cfg(feature = "lbf")] impl Json for LedgerBytes { fn to_json(&self) -> serde_json::Value { diff --git a/plutus-ledger-api/src/v1/script.rs b/plutus-ledger-api/src/v1/script.rs index f83b398..28dd358 100644 --- a/plutus-ledger-api/src/v1/script.rs +++ b/plutus-ledger-api/src/v1/script.rs @@ -4,9 +4,6 @@ use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::Json; -use nom::combinator::map; -use nom::error::{context, VerboseError}; -use nom::IResult; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -18,8 +15,6 @@ use crate::error::ConversionError; use crate::plutus_data::IsPlutusData; use crate::v1::crypto::LedgerBytes; -use super::crypto::hash28; - /////////////////// // ValidatorHash // /////////////////// @@ -43,10 +38,6 @@ impl ValidatorHash { } } -pub(crate) fn validator_hash(input: &str) -> IResult<&str, ValidatorHash, VerboseError<&str>> { - context("validator_hash", map(script_hash, ValidatorHash))(input) -} - /////////////////////// // MintingPolicyHash // /////////////////////// @@ -76,12 +67,6 @@ impl TryFromPLA for csl::PolicyID { } } -pub(crate) fn minting_policy_hash( - input: &str, -) -> IResult<&str, MintingPolicyHash, VerboseError<&str>> { - context("minting_policy_hash", map(script_hash, MintingPolicyHash))(input) -} - //////////////// // ScriptHash // //////////////// @@ -115,7 +100,3 @@ impl TryFromPLA for csl::ScriptHash { .map_err(TryFromPLAError::CSLDeserializeError) } } - -pub(crate) fn script_hash(input: &str) -> IResult<&str, ScriptHash, VerboseError<&str>> { - context("script_hash", map(hash28, ScriptHash))(input) -} diff --git a/plutus-ledger-api/src/v1/transaction.rs b/plutus-ledger-api/src/v1/transaction.rs index 21c18b6..05f25f5 100644 --- a/plutus-ledger-api/src/v1/transaction.rs +++ b/plutus-ledger-api/src/v1/transaction.rs @@ -7,9 +7,9 @@ use cardano_serialization_lib as csl; use lbr_prelude::json::Json; use nom::{ character::complete::char, - combinator::{all_consuming, map}, + combinator::{all_consuming, map, map_res}, error::{context, VerboseError}, - sequence::preceded, + sequence::{preceded, tuple}, Finish, IResult, }; use num_bigint::BigInt; @@ -18,13 +18,16 @@ use serde::{Deserialize, Serialize}; use super::{ address::{Address, StakingCredential}, - crypto::{hash32, LedgerBytes, PaymentPubKeyHash}, + crypto::{ledger_bytes, LedgerBytes, PaymentPubKeyHash}, datum::{Datum, DatumHash}, interval::PlutusInterval, value::{CurrencySymbol, Value}, }; -use crate::{self as plutus_ledger_api, aux::big_int}; +use crate::{ + self as plutus_ledger_api, + aux::{big_int, guard_bytes}, +}; use crate::{ csl::pla_to_csl::{TryFromPLAError, TryToCSL}, plutus_data::IsPlutusData, @@ -93,20 +96,19 @@ impl TryFromPLA> for csl::TransactionInputs { } } +/// Nom parser for TransactionInput +/// Expects a transaction hash of 32 bytes in hexadecimal followed by a # and an integer index +/// E.g.: 1122334455667788990011223344556677889900112233445566778899001122#1 pub(crate) fn transaction_input( input: &str, ) -> IResult<&str, TransactionInput, VerboseError<&str>> { - let (input, tx_id) = transaction_hash(input)?; - - let (input, idx) = preceded(char('#'), big_int)(input)?; - - Ok(( - input, - TransactionInput { - transaction_id: tx_id, - index: idx, + map( + tuple((transaction_hash, preceded(char('#'), big_int))), + |(transaction_id, index)| TransactionInput { + transaction_id, + index, }, - )) + )(input) } impl FromStr for TransactionInput { @@ -146,6 +148,16 @@ impl fmt::Display for TransactionHash { } } +impl TransactionHash { + pub fn from_bytes(bytes: Vec) -> Result { + Ok(TransactionHash(LedgerBytes(guard_bytes( + "ScriptHash", + bytes, + 32, + )?))) + } +} + impl FromCSL for TransactionHash { fn from_csl(value: &csl::TransactionHash) -> Self { TransactionHash(LedgerBytes(value.to_bytes())) @@ -159,8 +171,16 @@ impl TryFromPLA for csl::TransactionHash { } } +/// Nom parser for TransactionHash +/// Expects a hexadecimal string representation of 32 bytes +/// E.g.: 1122334455667788990011223344556677889900112233445566778899001122 pub(crate) fn transaction_hash(input: &str) -> IResult<&str, TransactionHash, VerboseError<&str>> { - context("transaction_hash", map(hash32, TransactionHash))(input) + context( + "transaction_hash", + map_res(ledger_bytes, |LedgerBytes(bytes)| { + TransactionHash::from_bytes(bytes) + }), + )(input) } impl FromStr for TransactionHash { diff --git a/plutus-ledger-api/src/v1/value.rs b/plutus-ledger-api/src/v1/value.rs index a72907d..41c482f 100644 --- a/plutus-ledger-api/src/v1/value.rs +++ b/plutus-ledger-api/src/v1/value.rs @@ -13,10 +13,11 @@ use anyhow::anyhow; use cardano_serialization_lib as csl; #[cfg(feature = "lbf")] use lbr_prelude::json::{Error, Json, JsonType}; +use nom::combinator::{map, opt}; use nom::{ branch::alt, character::complete::{char, space0}, - combinator::{all_consuming, eof, map, map_res, success}, + combinator::{all_consuming, eof, map_res, success}, error::{context, VerboseError}, multi::separated_list0, sequence::preceded, @@ -40,7 +41,6 @@ use crate::v1::crypto::LedgerBytes; use crate::v1::script::{MintingPolicyHash, ScriptHash}; use super::crypto::ledger_bytes; -use super::script::minting_policy_hash; //////////////////// // CurrencySymbol // @@ -65,6 +65,13 @@ impl CurrencySymbol { )?)) } } + + pub fn is_ada(&self) -> bool { + match self { + CurrencySymbol::Ada => true, + CurrencySymbol::NativeToken(_) => false, + } + } } impl fmt::Display for CurrencySymbol { @@ -103,7 +110,7 @@ impl IsPlutusData for CurrencySymbol { fn to_plutus_data(&self) -> PlutusData { match self { CurrencySymbol::NativeToken(policy_hash) => policy_hash.to_plutus_data(), - CurrencySymbol::Ada => String::from("").to_plutus_data(), + CurrencySymbol::Ada => PlutusData::Bytes(Vec::with_capacity(0)), } } @@ -145,24 +152,14 @@ impl Json for CurrencySymbol { } } +/// Nom parser for CurrencySymbol +/// Expects a hexadecimal string representation of 0 (Ada) or 28 bytes (NativeToken) pub(crate) fn currency_symbol(input: &str) -> IResult<&str, CurrencySymbol, VerboseError<&str>> { context( "currency symbol", - alt(( - map_res(ledger_bytes, |bytes: LedgerBytes| { - if bytes.0.is_empty() { - Ok(CurrencySymbol::Ada) - } else { - Err(ConversionError::invalid_bytestring_length( - "currency_symbol_ada", - 0, - "equal to", - &bytes.0, - )) - } - }), - map(minting_policy_hash, CurrencySymbol::NativeToken), - )), + map_res(ledger_bytes, |LedgerBytes(bytes)| { + CurrencySymbol::from_bytes(bytes) + }), )(input) } @@ -294,22 +291,14 @@ impl Value { pub fn is_subset(&self, b: &Value) -> bool { (b - self) - .clone() .normalize() // Has negative entries? .filter(|_, _, amount| amount < &BigInt::from(0u32)) .is_empty() } - pub fn is_pure_ada(self) -> bool { - let inner = self.normalize().0; - let inner: Vec<_> = inner.into_iter().collect(); - - match inner.as_slice() { - [] => true, - [(cs, _)] => cs == &CurrencySymbol::Ada, - _ => false, - } + pub fn is_pure_ada(&self) -> bool { + self.0.iter().all(|(cs, _)| cs == &CurrencySymbol::Ada) } /// Apply a function to each token of the value, and use its result as the new amount. @@ -357,6 +346,7 @@ impl Value { } /// Create a vector with each distinct value + /// Warning: is the value is not normalized, the same asset class can appear twice pub fn flatten(&self) -> Vec<(&CurrencySymbol, &TokenName, &BigInt)> { self.0 .iter() @@ -386,10 +376,12 @@ impl fmt::Display for Value { }) .peekable(); while let Some((cur_sym, tn, amount)) = it.next() { - if tn.is_empty() { - write!(f, "{} {}", cur_sym, amount)?; + if cur_sym.is_ada() { + write!(f, "{}", amount)?; + } else if tn.is_empty() { + write!(f, "{} {}", amount, cur_sym)?; } else { - write!(f, "{}.{} {}", cur_sym, tn, amount)?; + write!(f, "{} {}.{}", amount, cur_sym, tn)?; } if it.peek().is_some() { write!(f, "+")?; @@ -400,22 +392,33 @@ impl fmt::Display for Value { } } +/// Nom parser for a single entry in a Value +/// Expects an integer quantity, followed by an asset class after a space character +/// (space is not required for Ada) +/// E.g.: 12 11223344556677889900112233445566778899001122334455667788.001122aabbcc pub(crate) fn flat_value( input: &str, ) -> IResult<&str, (CurrencySymbol, TokenName, BigInt), VerboseError<&str>> { - let (input, cs) = currency_symbol(input)?; - - let (input, tn) = alt((preceded(char('.'), token_name), success(TokenName::ada())))(input)?; - - let (input, amount) = preceded(char(' '), big_int)(input)?; - - Ok((input, (cs, tn, amount))) + map( + tuple((big_int, opt(preceded(char(' '), asset_class)))), + |(amount, asset_class)| match asset_class { + None => (CurrencySymbol::Ada, TokenName::ada(), amount), + Some(AssetClass { + currency_symbol, + token_name, + }) => (currency_symbol, token_name, amount), + }, + )(input) } +/// Nom parser for Value +/// Expects flat Value entries divided by a `+` sign +/// E.g.: 123+12 11223344556677889900112233445566778899001122334455667788.001122aabbcc pub(crate) fn value(input: &str) -> IResult<&str, Value, VerboseError<&str>> { - let (input, flat_values) = separated_list0(tuple((space0, char('+'))), flat_value)(input)?; - - Ok((input, Value::unflatten(&flat_values))) + map( + separated_list0(tuple((space0, char('+'))), flat_value), + |flat_values| Value::unflatten(&flat_values), + )(input) } impl FromStr for Value { @@ -636,21 +639,12 @@ impl FromCSL for BTreeMap { impl FromCSL for BTreeMap { fn from_csl(value: &csl::MintsAssets) -> Self { - let mut m_ass_vec = Vec::new(); - - // This is so stupid. `MintsAssets` doesn't have a `len` method for some reason. - for idx in 0.. { - if let Some(m_ass) = value.get(idx) { - m_ass_vec.push(m_ass); - } else { - break; - } - } - - m_ass_vec.into_iter().fold(BTreeMap::new(), |acc, m| { - let ass = BTreeMap::from_csl(&m); - union_b_tree_maps_with(|l, r| l + r, [&acc, &ass]) - }) + (0..value.len()) + .map(|idx| value.get(idx).unwrap()) + .fold(BTreeMap::new(), |acc, m| { + let ass = BTreeMap::from_csl(&m); + union_b_tree_maps_with(|l, r| l + r, [&acc, &ass]) + }) } } @@ -744,18 +738,11 @@ impl FromStr for TokenName { } } +/// Nom parser for TokenName +/// Expects a hexadecimal string representation of up to 32 pub(crate) fn token_name(input: &str) -> IResult<&str, TokenName, VerboseError<&str>> { - map_res(ledger_bytes, |bytes: LedgerBytes| { - if bytes.0.len() <= 32 { - Ok(TokenName(bytes)) - } else { - Err(ConversionError::invalid_bytestring_length( - "token_name", - 32, - "less than or equal to", - &bytes.0, - )) - } + map_res(ledger_bytes, |LedgerBytes(bytes)| { + TokenName::from_bytes(bytes) })(input) } @@ -836,6 +823,12 @@ impl FromStr for AssetClass { } } +/// Nom parser for AssetClass +/// Expects a currency symbol and token name both in hexadecimal format, divided by a `.` +/// In case the token name is empty, the divider is not required +/// E.g.: +/// - 11223344556677889900112233445566778899001122334455667788.001122aabbcc +/// - 11223344556677889900112233445566778899001122334455667788 pub(crate) fn asset_class(input: &str) -> IResult<&str, AssetClass, VerboseError<&str>> { let (input, cs) = currency_symbol(input)?; diff --git a/plutus-ledger-api/src/v3/transaction.rs b/plutus-ledger-api/src/v3/transaction.rs index 68cf998..124a0d5 100644 --- a/plutus-ledger-api/src/v3/transaction.rs +++ b/plutus-ledger-api/src/v3/transaction.rs @@ -6,20 +6,22 @@ use num_bigint::BigInt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +pub use crate::v2::transaction::{ + DCert, POSIXTime, POSIXTimeRange, TransactionHash, TransactionInput, TransactionOutput, + TxInInfo, +}; use crate::{ self as plutus_ledger_api, plutus_data::{IsPlutusData, PlutusData}, - v1::{ + v2::{ address::{Credential, StakingCredential}, assoc_map::AssocMap, crypto::{PaymentPubKeyHash, StakePubKeyHash}, datum::{Datum, DatumHash}, redeemer::Redeemer, script::ScriptHash, - transaction::{POSIXTimeRange, TransactionHash, TransactionInput}, value::{CurrencySymbol, Lovelace, Value}, }, - v2::transaction::{TransactionOutput, TxInInfo}, }; use super::ratio::Rational; diff --git a/plutus-ledger-api/tests/display.proptest-regressions b/plutus-ledger-api/tests/display.proptest-regressions index 193e2d7..8a57c05 100644 --- a/plutus-ledger-api/tests/display.proptest-regressions +++ b/plutus-ledger-api/tests/display.proptest-regressions @@ -4,5 +4,4 @@ # # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. -cc f28698f393b1933268f15226ce5938cff4237e12ddbc2a4a043362f4d8b53dd4 # shrinks to val = "ࡀA\u{ec8}a𑵐𞟨𐨀Ø\u{16d70}0ꫛ\u{fe20}" -cc dafca272147ae56cc689fcc524f9eacc984ab5edb7d8a870c3beaccff6c283cd # shrinks to val = Ada +cc 73e529160154e82412cbfecc3b5a54e6a585c636492eb877021b4c25b26db267 # shrinks to val = Value({NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000002): 0, TokenName(00000000000000000d8229a17eadcd1469253bcf6608a65f314403f587053ff7): 2532403571, TokenName(a1dec97f4b53d0132fe7d16be928c0c0a5011a72c0f9e9a60bb9f132daa07ac2): 3411616235}, NativeToken(MintingPolicyHash(ScriptHash(14feaea1bd1512f19932541c80e80b812cdc077b9aef3029def6a5ff))): {TokenName(1ecc82a9216cd1427121349b5938c84bfef7be11e2e21a6b340efb53bdb45300): 157640827, TokenName(455e7a15711940029516f9c067cb1265a8936e7259cda7eaf31a9762631bd2b9): 1600413667, TokenName(4a15e3aad05949bdc39b8be95c34ef1e62df160ba30d2db99cdb6e4972d8a795): 1073007635, TokenName(bdf633bf616fb212d576c9c20452aafd0aebd75bc3f2777cdbea01390f901edb): 3043700082, TokenName(e55bff3749413a05be28429b438571ac00d22e168b503ecf1013810b211dcf45): 1834019470}, NativeToken(MintingPolicyHash(ScriptHash(1d89f770dd9bd49da8231bb541ecd05d0e3dd236feec524913a555a2))): {TokenName(09e255fc19f1e0df017e7b3f1fb0ac82b01c153ae99797032d8a3e5f59e3cb8b): 4022630384, TokenName(49d5d8a619f37f4f248cfc841048b888a1acda182c755d41c73de2e77ebc5a83): 3987855178, TokenName(9bc27e3f4f41169d57f3a20e1c05a439eb3de67ad6c3ec8abee445cf38f481e5): 3154222365, TokenName(b0a06e6ed40fce0fe5a010bfa90418ddfbd1946112f9aacead0c5c9c3930d56a): 4232555145, TokenName(f81c9b9e7c9d7cf2f2064c7ffa45bec406ff8e64c73af32f895227af0c9c3119): 630069146}, NativeToken(MintingPolicyHash(ScriptHash(1e2f1b28fac0aaa1c3441067c84b627029f457162b09180012130a7e))): {TokenName(252cf7e62a173276b0d3456692f5e8e99ae54add9f431fa6389a4267d7f343ff): 2154752195, TokenName(3d0e87e8d9abb3699a52dcde08a9ae7d0db5d9930a129e93e8a575f410b2c109): 3258224356, TokenName(ca1b2950c30003112df27daf27cb6d2626d7a3703c8aaf9e46387c837f797604): 2836533300, TokenName(d6673a538989a4c2724b8f8209bf598d9b9df7fa975b8e759956a7b783a611c3): 3731206483, TokenName(d68f5b751be1db24cfeb351249099a927ce5fb7f788e028643e19035a2432011): 3732451668}, NativeToken(MintingPolicyHash(ScriptHash(879ffd1e552ce28c55918753e93d727a05aceb6536ab96c56158ec62))): {TokenName(51079e8bfb848c45ba01fa809249a5d9a778dbd8c9460e09ac0a9e1e34b19229): 1211516382, TokenName(8322395ec5772b6951c777489b83f17127f211fa21ceb932548fa2a0cb24dc81): 1518100146, TokenName(94aaf59094956df10dc8e263ee1124bd0b05434029523936dc73a5d553ae3bed): 2119556654, TokenName(b926a6a398efef951640205e5db37df783caa5fde6d5e2c8609db8245dec4efe): 1265886353, TokenName(ca2424736877c1299a8af23e22b86d89ca356ea88b0ea54a1168ac5d06fef7ff): 566447027}}) diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_1.golden b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden index d3e40d2..c7d2241 100644 --- a/plutus-ledger-api/tests/testdata/v1_value_display_1.golden +++ b/plutus-ledger-api/tests/testdata/v1_value_display_1.golden @@ -1 +1 @@ - 234+01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 123 \ No newline at end of file +234+123 01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 \ No newline at end of file diff --git a/plutus-ledger-api/tests/testdata/v1_value_display_2.golden b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden index d3e40d2..c7d2241 100644 --- a/plutus-ledger-api/tests/testdata/v1_value_display_2.golden +++ b/plutus-ledger-api/tests/testdata/v1_value_display_2.golden @@ -1 +1 @@ - 234+01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 123 \ No newline at end of file +234+123 01010101010101010101010101010101010101010101010101010101.536f6d657468696e67 \ No newline at end of file From c21d9ecd4d2f50f94ff378ca2381bd914e07ce08 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 7 Nov 2024 14:57:31 +0100 Subject: [PATCH 37/38] Migrate over csl roundtrip tests --- plutus-ledger-api/tests/csl.rs | 132 +++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 plutus-ledger-api/tests/csl.rs diff --git a/plutus-ledger-api/tests/csl.rs b/plutus-ledger-api/tests/csl.rs new file mode 100644 index 0000000..78a7fa2 --- /dev/null +++ b/plutus-ledger-api/tests/csl.rs @@ -0,0 +1,132 @@ +#[cfg(test)] +mod csl_pla_roundtrip_tests { + use cardano_serialization_lib as csl; + use num_bigint::BigInt; + use plutus_ledger_api::{ + csl::{ + csl_to_pla::{FromCSL, TryFromCSL}, + pla_to_csl::TryToCSL, + }, + generators::correct::v1::{ + arb_address, arb_certificate_index, arb_chain_pointer, arb_credential, arb_datum_hash, + arb_ed25519_pub_key_hash, arb_minting_policy_hash, arb_plutus_data, arb_script_hash, + arb_slot, arb_token_name, arb_transaction_hash, arb_transaction_index, + arb_transaction_input, arb_value, + }, + v1::{ + address::{Address, StakingCredential}, + value::Value, + }, + }; + use proptest::{prop_assert_eq, proptest, strategy::Strategy, test_runner::TestCaseError}; + + fn try_to_from_prop + FromCSL + PartialEq + std::fmt::Debug>( + v: A, + ) -> Result<(), TestCaseError> { + Ok(prop_assert_eq!( + A::from_csl(&>::try_to_csl(&v)?), + v + )) + } + + fn try_to_try_from_prop + TryFromCSL + PartialEq + std::fmt::Debug>( + v: A, + ) -> Result<(), TestCaseError> { + Ok(prop_assert_eq!( + A::try_from_csl(&>::try_to_csl(&v)?)?, + v + )) + } + + proptest! { + #[test] + fn test_token_name(val in arb_token_name()) { + try_to_from_prop(val)? + } + + #[test] + fn test_minting_policy_hash(val in arb_minting_policy_hash()) { + try_to_from_prop(val)? + } + + // This is special because the CSL machinery always puts in at least a zero Ada in the value + // But the arbitrary generated value by PLA does not. + #[test] + fn test_value(val in arb_value()) { + let csl_val: csl::Value = val.try_to_csl()?; + prop_assert_eq!( + Value::from_csl(&csl_val), + // Add a zero ada value. + Value::ada_value(&BigInt::from(0)) + val + ) + } + + #[test] + fn test_transaction_hash(val in arb_transaction_hash()) { + try_to_from_prop(val)? + } + + #[test] + fn test_transaction_input(val in arb_transaction_input()) { + try_to_from_prop(val)? + } + + #[test] + fn test_ed25519_pub_key_hash(val in arb_ed25519_pub_key_hash()) { + try_to_from_prop::(val)? + } + + #[test] + fn test_script_hash(val in arb_script_hash()) { + try_to_from_prop(val)? + } + + #[test] + fn test_staking_credential(val in arb_credential().prop_map(StakingCredential::Hash)) { + try_to_from_prop::(val)? + } + + #[test] + fn test_credential(val in arb_credential()) { + try_to_from_prop(val)? + } + + #[test] + fn test_slot(val in arb_slot()) { + try_to_from_prop(val)? + } + + #[test] + fn test_transaction_index(val in arb_transaction_index()) { + try_to_from_prop(val)? + } + + #[test] + fn test_certificate_index(val in arb_certificate_index()) { + try_to_from_prop(val)? + } + + #[test] + fn test_chain_pointer(val in arb_chain_pointer()) { + try_to_from_prop(val)? + } + + #[test] + fn test_plutus_data(val in arb_plutus_data()) { + try_to_try_from_prop(val)? + } + + #[test] + fn test_datum_hash(val in arb_datum_hash()) { + try_to_from_prop(val)? + } + + #[test] + fn test_address(val in arb_address()) { + prop_assert_eq!( + Address::try_from_csl(&val.with_extra_info(1).try_to_csl()?)?, + val + ) + } + } +} From 12109485e3a525e60e162bcbb4eaa0bc3cfbe3e5 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 7 Nov 2024 15:08:10 +0100 Subject: [PATCH 38/38] Address PR comments --- plutus-ledger-api/src/aux.rs | 2 +- plutus-ledger-api/tests/display.proptest-regressions | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 plutus-ledger-api/tests/display.proptest-regressions diff --git a/plutus-ledger-api/src/aux.rs b/plutus-ledger-api/src/aux.rs index a432982..7c854bd 100644 --- a/plutus-ledger-api/src/aux.rs +++ b/plutus-ledger-api/src/aux.rs @@ -81,7 +81,7 @@ pub(crate) fn guard_bytes( } /// Nom parser for BigInt -/// Expects an arbitrary length integer, optionally signed +/// Expects an arbitrary length decimal integer, optionally signed pub(crate) fn big_int(i: &str) -> IResult<&str, BigInt, VerboseError<&str>> { map_res( recognize(tuple((opt(alt((char('-'), char('+')))), many1(digit1)))), diff --git a/plutus-ledger-api/tests/display.proptest-regressions b/plutus-ledger-api/tests/display.proptest-regressions deleted file mode 100644 index 8a57c05..0000000 --- a/plutus-ledger-api/tests/display.proptest-regressions +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 73e529160154e82412cbfecc3b5a54e6a585c636492eb877021b4c25b26db267 # shrinks to val = Value({NativeToken(MintingPolicyHash(ScriptHash(00000000000000000000000000000000000000000000000000000000))): {TokenName(0000000000000000000000000000000000000000000000000000000000000000): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000001): 0, TokenName(0000000000000000000000000000000000000000000000000000000000000002): 0, TokenName(00000000000000000d8229a17eadcd1469253bcf6608a65f314403f587053ff7): 2532403571, TokenName(a1dec97f4b53d0132fe7d16be928c0c0a5011a72c0f9e9a60bb9f132daa07ac2): 3411616235}, NativeToken(MintingPolicyHash(ScriptHash(14feaea1bd1512f19932541c80e80b812cdc077b9aef3029def6a5ff))): {TokenName(1ecc82a9216cd1427121349b5938c84bfef7be11e2e21a6b340efb53bdb45300): 157640827, TokenName(455e7a15711940029516f9c067cb1265a8936e7259cda7eaf31a9762631bd2b9): 1600413667, TokenName(4a15e3aad05949bdc39b8be95c34ef1e62df160ba30d2db99cdb6e4972d8a795): 1073007635, TokenName(bdf633bf616fb212d576c9c20452aafd0aebd75bc3f2777cdbea01390f901edb): 3043700082, TokenName(e55bff3749413a05be28429b438571ac00d22e168b503ecf1013810b211dcf45): 1834019470}, NativeToken(MintingPolicyHash(ScriptHash(1d89f770dd9bd49da8231bb541ecd05d0e3dd236feec524913a555a2))): {TokenName(09e255fc19f1e0df017e7b3f1fb0ac82b01c153ae99797032d8a3e5f59e3cb8b): 4022630384, TokenName(49d5d8a619f37f4f248cfc841048b888a1acda182c755d41c73de2e77ebc5a83): 3987855178, TokenName(9bc27e3f4f41169d57f3a20e1c05a439eb3de67ad6c3ec8abee445cf38f481e5): 3154222365, TokenName(b0a06e6ed40fce0fe5a010bfa90418ddfbd1946112f9aacead0c5c9c3930d56a): 4232555145, TokenName(f81c9b9e7c9d7cf2f2064c7ffa45bec406ff8e64c73af32f895227af0c9c3119): 630069146}, NativeToken(MintingPolicyHash(ScriptHash(1e2f1b28fac0aaa1c3441067c84b627029f457162b09180012130a7e))): {TokenName(252cf7e62a173276b0d3456692f5e8e99ae54add9f431fa6389a4267d7f343ff): 2154752195, TokenName(3d0e87e8d9abb3699a52dcde08a9ae7d0db5d9930a129e93e8a575f410b2c109): 3258224356, TokenName(ca1b2950c30003112df27daf27cb6d2626d7a3703c8aaf9e46387c837f797604): 2836533300, TokenName(d6673a538989a4c2724b8f8209bf598d9b9df7fa975b8e759956a7b783a611c3): 3731206483, TokenName(d68f5b751be1db24cfeb351249099a927ce5fb7f788e028643e19035a2432011): 3732451668}, NativeToken(MintingPolicyHash(ScriptHash(879ffd1e552ce28c55918753e93d727a05aceb6536ab96c56158ec62))): {TokenName(51079e8bfb848c45ba01fa809249a5d9a778dbd8c9460e09ac0a9e1e34b19229): 1211516382, TokenName(8322395ec5772b6951c777489b83f17127f211fa21ceb932548fa2a0cb24dc81): 1518100146, TokenName(94aaf59094956df10dc8e263ee1124bd0b05434029523936dc73a5d553ae3bed): 2119556654, TokenName(b926a6a398efef951640205e5db37df783caa5fde6d5e2c8609db8245dec4efe): 1265886353, TokenName(ca2424736877c1299a8af23e22b86d89ca356ea88b0ea54a1168ac5d06fef7ff): 566447027}})