fix: Plutus V3 NoDatum - Error: missing required inline datum or datum hash in script input
This commit is contained in:
parent
0905146140
commit
defce9be4e
|
@ -1,4 +1,7 @@
|
||||||
use super::{to_plutus_data::MintValue, Error};
|
use super::{
|
||||||
|
to_plutus_data::{MintValue, ToPlutusData},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pallas_addresses::{Address, Network, StakePayload};
|
use pallas_addresses::{Address, Network, StakePayload};
|
||||||
use pallas_codec::utils::{
|
use pallas_codec::utils::{
|
||||||
|
@ -839,6 +842,16 @@ pub fn find_script(
|
||||||
Some(DatumOption::Data(data)) => Ok(data.0.clone()),
|
Some(DatumOption::Data(data)) => Ok(data.0.clone()),
|
||||||
_ => Err(Error::MissingRequiredInlineDatumOrHash),
|
_ => Err(Error::MissingRequiredInlineDatumOrHash),
|
||||||
};
|
};
|
||||||
|
let lookup_datum_v3 = |datum: Option<DatumOption>| match datum {
|
||||||
|
Some(DatumOption::Hash(hash)) => match lookup_table.datum.get(&hash) {
|
||||||
|
Some(d) => Ok(d.clone()),
|
||||||
|
None => Err(Error::MissingRequiredDatum {
|
||||||
|
hash: hash.to_string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
Some(DatumOption::Data(data)) => Ok(data.0.clone()),
|
||||||
|
_ => Ok(None::<PlutusData>.to_plutus_data()),
|
||||||
|
};
|
||||||
|
|
||||||
match redeemer.tag {
|
match redeemer.tag {
|
||||||
RedeemerTag::Mint => get_mint_info(&tx.transaction_body.mint)
|
RedeemerTag::Mint => get_mint_info(&tx.transaction_body.mint)
|
||||||
|
@ -908,12 +921,12 @@ pub fn find_script(
|
||||||
.and_then(|input| match output_address(&input.resolved) {
|
.and_then(|input| match output_address(&input.resolved) {
|
||||||
Address::Shelley(shelley_address) => {
|
Address::Shelley(shelley_address) => {
|
||||||
let hash = shelley_address.payment().as_hash();
|
let hash = shelley_address.payment().as_hash();
|
||||||
|
let (script, _) = lookup_script(hash)?;
|
||||||
let script = lookup_script(hash);
|
let datum = match script {
|
||||||
|
ScriptVersion::V3(_) => lookup_datum_v3(output_datum(&input.resolved)),
|
||||||
let datum = lookup_datum(output_datum(&input.resolved));
|
_ => lookup_datum(output_datum(&input.resolved)),
|
||||||
|
}?;
|
||||||
script.and_then(|(script, _)| Ok((script, Some(datum?))))
|
Ok((script, Some(datum)))
|
||||||
}
|
}
|
||||||
_ => Err(Error::NonScriptStakeCredential),
|
_ => Err(Error::NonScriptStakeCredential),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[
|
||||||
|
{ 0: h'70{{ simple_spend_no_datum.simple_spend.spend.hash }}'
|
||||||
|
, 1: 1000000000
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,33 @@
|
||||||
|
[
|
||||||
|
{ 0:
|
||||||
|
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
|
||||||
|
]
|
||||||
|
|
||||||
|
, 1:
|
||||||
|
[]
|
||||||
|
|
||||||
|
, 2: 42
|
||||||
|
|
||||||
|
, 11: h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
|
||||||
|
|
||||||
|
, 13:
|
||||||
|
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
|
||||||
|
]
|
||||||
|
|
||||||
|
, 16:
|
||||||
|
[ h'6000000000000000000000000000000000000000000000000000000000', 1000000000
|
||||||
|
]
|
||||||
|
|
||||||
|
, 17: 1
|
||||||
|
},
|
||||||
|
|
||||||
|
{ 5: [[0, 0, 121([]), [1000000, 100000000]]]
|
||||||
|
|
||||||
|
, 7: [h'{{ simple_spend_no_datum.simple_spend.spend.cbor }}']
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
true,
|
||||||
|
|
||||||
|
null
|
||||||
|
]
|
|
@ -0,0 +1,99 @@
|
||||||
|
use aiken/collection/dict
|
||||||
|
use cardano/address.{Address, Script}
|
||||||
|
use cardano/assets
|
||||||
|
use cardano/transaction.{
|
||||||
|
Input, NoDatum, Output, OutputReference, ScriptPurpose, Spend, Transaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
validator simple_spend {
|
||||||
|
spend(
|
||||||
|
_datum: Option<Void>,
|
||||||
|
_redeemer: Void,
|
||||||
|
output_ref: OutputReference,
|
||||||
|
transaction: Transaction,
|
||||||
|
) {
|
||||||
|
assert_transaction_id(transaction.id)
|
||||||
|
|
||||||
|
assert_script_info(output_ref)
|
||||||
|
|
||||||
|
assert_inputs(transaction.inputs)
|
||||||
|
|
||||||
|
expect [] = transaction.outputs
|
||||||
|
|
||||||
|
expect [] = transaction.reference_inputs
|
||||||
|
|
||||||
|
expect [] = transaction.extra_signatories
|
||||||
|
|
||||||
|
expect 42 == transaction.fee
|
||||||
|
|
||||||
|
assert_redeemers(transaction.redeemers)
|
||||||
|
|
||||||
|
expect [] == dict.to_pairs(transaction.datums)
|
||||||
|
|
||||||
|
True
|
||||||
|
}
|
||||||
|
|
||||||
|
else(_ctx) {
|
||||||
|
fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_transaction_id(id: ByteArray) {
|
||||||
|
expect
|
||||||
|
#"c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b" == id
|
||||||
|
Void
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_script_info(info: OutputReference) {
|
||||||
|
expect
|
||||||
|
OutputReference {
|
||||||
|
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
output_index: 0,
|
||||||
|
} == info
|
||||||
|
Void
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_inputs(inputs: List<Input>) {
|
||||||
|
expect [
|
||||||
|
Input {
|
||||||
|
output_reference: OutputReference { transaction_id, output_index: 0 },
|
||||||
|
output: Output {
|
||||||
|
address,
|
||||||
|
value: resolved_input_value,
|
||||||
|
datum: NoDatum,
|
||||||
|
reference_script: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] = inputs
|
||||||
|
|
||||||
|
expect
|
||||||
|
transaction_id == #"0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
expect resolved_input_value == assets.from_lovelace(1000000000)
|
||||||
|
|
||||||
|
expect Address { payment_credential: Script(_), stake_credential: None } =
|
||||||
|
address
|
||||||
|
|
||||||
|
Void
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_redeemers(redeemers: Pairs<ScriptPurpose, Data>) {
|
||||||
|
expect
|
||||||
|
[
|
||||||
|
Pair(
|
||||||
|
Spend(
|
||||||
|
OutputReference {
|
||||||
|
transaction_id: #"0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
output_index: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
void(),
|
||||||
|
),
|
||||||
|
] == redeemers
|
||||||
|
Void
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void() -> Data {
|
||||||
|
let void: Data = Void
|
||||||
|
void
|
||||||
|
}
|
Loading…
Reference in New Issue