Add script context translations for voting purpose.
This commit is contained in:
parent
bfc93bf076
commit
7501538053
|
@ -1,13 +1,13 @@
|
||||||
use super::{
|
use super::{
|
||||||
error::Error,
|
error::Error,
|
||||||
script_context::{DataLookupTable, ResolvedInput, ScriptPurpose, ScriptVersion},
|
script_context::{sort_voters, DataLookupTable, ResolvedInput, ScriptPurpose, ScriptVersion},
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pallas_addresses::{Address, ScriptHash, ShelleyPaymentPart, StakePayload};
|
use pallas_addresses::{Address, ScriptHash, ShelleyPaymentPart, StakePayload};
|
||||||
use pallas_codec::utils::Nullable;
|
use pallas_codec::utils::Nullable;
|
||||||
use pallas_primitives::conway::{
|
use pallas_primitives::conway::{
|
||||||
Certificate, GovAction, MintedTx, PolicyId, RedeemerTag, RedeemersKey, RewardAccount,
|
Certificate, GovAction, MintedTx, PolicyId, RedeemerTag, RedeemersKey, RewardAccount,
|
||||||
StakeCredential, TransactionOutput,
|
StakeCredential, TransactionOutput, Voter,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -166,14 +166,29 @@ pub fn scripts_needed(tx: &MintedTx, utxos: &[ResolvedInput]) -> Result<ScriptsN
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// TODO
|
let mut voting = txb
|
||||||
assert!(txb.voting_procedures.is_none());
|
.voting_procedures
|
||||||
|
.as_deref()
|
||||||
|
.map(|m| {
|
||||||
|
m.iter()
|
||||||
|
.filter_map(|(voter, _)| match voter {
|
||||||
|
Voter::ConstitutionalCommitteeScript(hash) | Voter::DRepScript(hash) => {
|
||||||
|
Some((ScriptPurpose::Voting(voter.clone()), *hash))
|
||||||
|
}
|
||||||
|
Voter::ConstitutionalCommitteeKey(_)
|
||||||
|
| Voter::DRepKey(_)
|
||||||
|
| Voter::StakePoolKey(_) => None,
|
||||||
|
})
|
||||||
|
.collect::<ScriptsNeeded>()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
needed.append(&mut spend);
|
needed.append(&mut spend);
|
||||||
needed.append(&mut reward);
|
needed.append(&mut reward);
|
||||||
needed.append(&mut cert);
|
needed.append(&mut cert);
|
||||||
needed.append(&mut mint);
|
needed.append(&mut mint);
|
||||||
needed.append(&mut propose);
|
needed.append(&mut propose);
|
||||||
|
needed.append(&mut voting);
|
||||||
|
|
||||||
Ok(needed)
|
Ok(needed)
|
||||||
}
|
}
|
||||||
|
@ -329,6 +344,24 @@ fn build_redeemer_key(
|
||||||
Ok(redeemer_key)
|
Ok(redeemer_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptPurpose::Voting(v) => {
|
||||||
|
let redeemer_key = tx_body
|
||||||
|
.voting_procedures
|
||||||
|
.as_deref()
|
||||||
|
.map(|m| {
|
||||||
|
m.iter()
|
||||||
|
.sorted_by(|(a, _), (b, _)| sort_voters(a, b))
|
||||||
|
.position(|x| &x.0 == v)
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
.map(|index| RedeemersKey {
|
||||||
|
tag: RedeemerTag::Vote,
|
||||||
|
index: index as u32,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(redeemer_key)
|
||||||
|
}
|
||||||
|
|
||||||
ScriptPurpose::Proposing(_, procedure) => {
|
ScriptPurpose::Proposing(_, procedure) => {
|
||||||
let redeemer_key = tx_body
|
let redeemer_key = tx_body
|
||||||
.proposal_procedures
|
.proposal_procedures
|
||||||
|
|
|
@ -8,12 +8,12 @@ use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::{
|
use pallas_primitives::{
|
||||||
alonzo,
|
alonzo,
|
||||||
conway::{
|
conway::{
|
||||||
AddrKeyhash, Certificate, Coin, DatumHash, DatumOption, GovAction, Mint,
|
AddrKeyhash, Certificate, Coin, DatumHash, DatumOption, GovAction, GovActionId, Mint,
|
||||||
MintedTransactionBody, MintedTransactionOutput, MintedTx, MintedWitnessSet, NativeScript,
|
MintedTransactionBody, MintedTransactionOutput, MintedTx, MintedWitnessSet, NativeScript,
|
||||||
PlutusData, PlutusV1Script, PlutusV2Script, PlutusV3Script, PolicyId,
|
PlutusData, PlutusV1Script, PlutusV2Script, PlutusV3Script, PolicyId,
|
||||||
PostAlonzoTransactionOutput, ProposalProcedure, PseudoDatumOption, PseudoScript, Redeemer,
|
PostAlonzoTransactionOutput, ProposalProcedure, PseudoDatumOption, PseudoScript, Redeemer,
|
||||||
RedeemerTag, RedeemersKey, RequiredSigners, RewardAccount, ScriptHash, StakeCredential,
|
RedeemerTag, RedeemersKey, RequiredSigners, RewardAccount, ScriptHash, StakeCredential,
|
||||||
TransactionInput, TransactionOutput, Value,
|
TransactionInput, TransactionOutput, Value, Voter, VotingProcedure,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use pallas_traverse::{ComputeHash, OriginalHash};
|
use pallas_traverse::{ComputeHash, OriginalHash};
|
||||||
|
@ -53,6 +53,7 @@ pub enum ScriptInfo<T> {
|
||||||
Spending(TransactionInput, T),
|
Spending(TransactionInput, T),
|
||||||
Rewarding(StakeCredential),
|
Rewarding(StakeCredential),
|
||||||
Certifying(usize, Certificate),
|
Certifying(usize, Certificate),
|
||||||
|
Voting(Voter),
|
||||||
Proposing(usize, ProposalProcedure),
|
Proposing(usize, ProposalProcedure),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ impl ScriptPurpose {
|
||||||
}
|
}
|
||||||
Self::Rewarding(stake_credential) => ScriptInfo::Rewarding(stake_credential),
|
Self::Rewarding(stake_credential) => ScriptInfo::Rewarding(stake_credential),
|
||||||
Self::Certifying(ix, certificate) => ScriptInfo::Certifying(ix, certificate),
|
Self::Certifying(ix, certificate) => ScriptInfo::Certifying(ix, certificate),
|
||||||
|
Self::Voting(voter) => ScriptInfo::Voting(voter),
|
||||||
Self::Proposing(ix, procedure) => ScriptInfo::Proposing(ix, procedure),
|
Self::Proposing(ix, procedure) => ScriptInfo::Proposing(ix, procedure),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +222,7 @@ impl TxInfoV1 {
|
||||||
|
|
||||||
let redeemers = get_redeemers_info(
|
let redeemers = get_redeemers_info(
|
||||||
&tx.transaction_witness_set,
|
&tx.transaction_witness_set,
|
||||||
script_purpose_builder(&inputs[..], &mint, &certificates, &withdrawals, &[]),
|
script_purpose_builder(&inputs[..], &mint, &certificates, &withdrawals, &[], &[]),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(TxInfo::V1(TxInfoV1 {
|
Ok(TxInfo::V1(TxInfoV1 {
|
||||||
|
@ -269,7 +271,7 @@ impl TxInfoV2 {
|
||||||
|
|
||||||
let redeemers = get_redeemers_info(
|
let redeemers = get_redeemers_info(
|
||||||
&tx.transaction_witness_set,
|
&tx.transaction_witness_set,
|
||||||
script_purpose_builder(&inputs[..], &mint, &certificates, &withdrawals, &[]),
|
script_purpose_builder(&inputs[..], &mint, &certificates, &withdrawals, &[], &[]),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let reference_inputs = tx
|
let reference_inputs = tx
|
||||||
|
@ -310,12 +312,11 @@ pub struct TxInfoV3 {
|
||||||
pub signatories: Vec<AddrKeyhash>,
|
pub signatories: Vec<AddrKeyhash>,
|
||||||
pub redeemers: KeyValuePairs<ScriptPurpose, Redeemer>,
|
pub redeemers: KeyValuePairs<ScriptPurpose, Redeemer>,
|
||||||
pub data: KeyValuePairs<DatumHash, PlutusData>,
|
pub data: KeyValuePairs<DatumHash, PlutusData>,
|
||||||
pub proposal_procedures: Vec<ProposalProcedure>,
|
|
||||||
pub id: Hash<32>,
|
pub id: Hash<32>,
|
||||||
|
pub votes: KeyValuePairs<Voter, KeyValuePairs<GovActionId, VotingProcedure>>,
|
||||||
|
pub proposal_procedures: Vec<ProposalProcedure>,
|
||||||
pub current_treasury_amount: Option<Coin>,
|
pub current_treasury_amount: Option<Coin>,
|
||||||
pub treasury_donation: Option<PositiveCoin>,
|
pub treasury_donation: Option<PositiveCoin>,
|
||||||
// TODO:
|
|
||||||
// votes : KeyValuePairs<Voter, KeyValuePairs<GovernanceActionId, Vote>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TxInfoV3 {
|
impl TxInfoV3 {
|
||||||
|
@ -336,6 +337,8 @@ impl TxInfoV3 {
|
||||||
let proposal_procedures =
|
let proposal_procedures =
|
||||||
get_proposal_procedures_info(&tx.transaction_body.proposal_procedures);
|
get_proposal_procedures_info(&tx.transaction_body.proposal_procedures);
|
||||||
|
|
||||||
|
let votes = get_votes_info(&tx.transaction_body.voting_procedures);
|
||||||
|
|
||||||
let redeemers = get_redeemers_info(
|
let redeemers = get_redeemers_info(
|
||||||
&tx.transaction_witness_set,
|
&tx.transaction_witness_set,
|
||||||
script_purpose_builder(
|
script_purpose_builder(
|
||||||
|
@ -344,6 +347,7 @@ impl TxInfoV3 {
|
||||||
&certificates,
|
&certificates,
|
||||||
&withdrawals,
|
&withdrawals,
|
||||||
&proposal_procedures,
|
&proposal_procedures,
|
||||||
|
&votes.iter().map(|(k, _v)| k).collect_vec()[..],
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -368,6 +372,7 @@ impl TxInfoV3 {
|
||||||
data: KeyValuePairs::from(get_data_info(&tx.transaction_witness_set)),
|
data: KeyValuePairs::from(get_data_info(&tx.transaction_witness_set)),
|
||||||
redeemers,
|
redeemers,
|
||||||
proposal_procedures,
|
proposal_procedures,
|
||||||
|
votes,
|
||||||
current_treasury_amount: get_current_treasury_amount_info(
|
current_treasury_amount: get_current_treasury_amount_info(
|
||||||
&tx.transaction_body.treasury_value,
|
&tx.transaction_body.treasury_value,
|
||||||
),
|
),
|
||||||
|
@ -713,12 +718,44 @@ pub fn get_redeemers_info<'a>(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_votes_info(
|
||||||
|
votes: &Option<
|
||||||
|
NonEmptyKeyValuePairs<Voter, NonEmptyKeyValuePairs<GovActionId, VotingProcedure>>,
|
||||||
|
>,
|
||||||
|
) -> KeyValuePairs<Voter, KeyValuePairs<GovActionId, VotingProcedure>> {
|
||||||
|
KeyValuePairs::from(
|
||||||
|
votes
|
||||||
|
.as_deref()
|
||||||
|
.map(|votes| {
|
||||||
|
votes
|
||||||
|
.iter()
|
||||||
|
.sorted_by(|(a, _), (b, _)| sort_voters(a, b))
|
||||||
|
.cloned()
|
||||||
|
.map(|(voter, actions)| {
|
||||||
|
(
|
||||||
|
voter,
|
||||||
|
KeyValuePairs::from(
|
||||||
|
actions
|
||||||
|
.iter()
|
||||||
|
.sorted_by(|(a, _), (b, _)| sort_gov_action_id(a, b))
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn script_purpose_builder<'a>(
|
fn script_purpose_builder<'a>(
|
||||||
inputs: &'a [TxInInfo],
|
inputs: &'a [TxInInfo],
|
||||||
mint: &'a MintValue,
|
mint: &'a MintValue,
|
||||||
certificates: &'a [Certificate],
|
certificates: &'a [Certificate],
|
||||||
withdrawals: &'a KeyValuePairs<Address, Coin>,
|
withdrawals: &'a KeyValuePairs<Address, Coin>,
|
||||||
proposal_procedures: &'a [ProposalProcedure],
|
proposal_procedures: &'a [ProposalProcedure],
|
||||||
|
votes: &'a [&'a Voter],
|
||||||
) -> impl Fn(&'a RedeemersKey) -> Result<ScriptPurpose, Error> {
|
) -> impl Fn(&'a RedeemersKey) -> Result<ScriptPurpose, Error> {
|
||||||
move |redeemer: &'a RedeemersKey| {
|
move |redeemer: &'a RedeemersKey| {
|
||||||
let tag = redeemer.tag;
|
let tag = redeemer.tag;
|
||||||
|
@ -754,12 +791,16 @@ fn script_purpose_builder<'a>(
|
||||||
})
|
})
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
|
|
||||||
|
RedeemerTag::Vote => votes
|
||||||
|
.get(index)
|
||||||
|
.cloned()
|
||||||
|
.cloned()
|
||||||
|
.map(ScriptPurpose::Voting),
|
||||||
|
|
||||||
RedeemerTag::Propose => proposal_procedures
|
RedeemerTag::Propose => proposal_procedures
|
||||||
.get(redeemer.index as usize)
|
.get(index)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|p| ScriptPurpose::Proposing(index, p)),
|
.map(|p| ScriptPurpose::Proposing(index, p)),
|
||||||
|
|
||||||
tag => todo!("get_script_purpose for {tag:?}"),
|
|
||||||
}
|
}
|
||||||
.ok_or(Error::ExtraneousRedeemer)
|
.ok_or(Error::ExtraneousRedeemer)
|
||||||
}
|
}
|
||||||
|
@ -867,6 +908,18 @@ pub fn find_script(
|
||||||
_ => Err(Error::NonScriptStakeCredential),
|
_ => Err(Error::NonScriptStakeCredential),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
RedeemerTag::Vote => get_votes_info(&tx.transaction_body.voting_procedures)
|
||||||
|
.get(redeemer.index as usize)
|
||||||
|
.ok_or(Error::MissingScriptForRedeemer)
|
||||||
|
.and_then(|(voter, _)| match voter {
|
||||||
|
Voter::ConstitutionalCommitteeScript(hash) => Ok(hash),
|
||||||
|
Voter::ConstitutionalCommitteeKey(..) => Err(Error::NonScriptStakeCredential),
|
||||||
|
Voter::DRepScript(hash) => Ok(hash),
|
||||||
|
Voter::DRepKey(..) => Err(Error::NonScriptStakeCredential),
|
||||||
|
Voter::StakePoolKey(..) => Err(Error::NonScriptStakeCredential),
|
||||||
|
})
|
||||||
|
.and_then(lookup_script),
|
||||||
|
|
||||||
RedeemerTag::Propose => {
|
RedeemerTag::Propose => {
|
||||||
get_proposal_procedures_info(&tx.transaction_body.proposal_procedures)
|
get_proposal_procedures_info(&tx.transaction_body.proposal_procedures)
|
||||||
.get(redeemer.index as usize)
|
.get(redeemer.index as usize)
|
||||||
|
@ -884,8 +937,6 @@ pub fn find_script(
|
||||||
})
|
})
|
||||||
.and_then(lookup_script)
|
.and_then(lookup_script)
|
||||||
}
|
}
|
||||||
|
|
||||||
RedeemerTag::Vote => todo!("find_script: RedeemerTag::Vote"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,6 +1057,35 @@ fn sort_redeemers(a: &RedeemersKey, b: &RedeemersKey) -> Ordering {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sort_voters(a: &Voter, b: &Voter) -> Ordering {
|
||||||
|
fn explode(voter: &Voter) -> (usize, &Hash<28>) {
|
||||||
|
match voter {
|
||||||
|
Voter::ConstitutionalCommitteeScript(hash) => (0, hash),
|
||||||
|
Voter::ConstitutionalCommitteeKey(hash) => (1, hash),
|
||||||
|
Voter::DRepScript(hash) => (2, hash),
|
||||||
|
Voter::DRepKey(hash) => (3, hash),
|
||||||
|
Voter::StakePoolKey(hash) => (4, hash),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (tag_a, hash_a) = explode(a);
|
||||||
|
let (tag_b, hash_b) = explode(b);
|
||||||
|
|
||||||
|
if tag_a == tag_b {
|
||||||
|
hash_a.cmp(hash_b)
|
||||||
|
} else {
|
||||||
|
tag_a.cmp(&tag_b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sort_gov_action_id(a: &GovActionId, b: &GovActionId) -> Ordering {
|
||||||
|
if a.transaction_id == b.transaction_id {
|
||||||
|
a.action_index.cmp(&b.action_index)
|
||||||
|
} else {
|
||||||
|
a.transaction_id.cmp(&b.transaction_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -1346,4 +1426,57 @@ mod tests {
|
||||||
// from the Haskell ledger / cardano node.
|
// from the Haskell ledger / cardano node.
|
||||||
insta::assert_debug_snapshot!(script_context.to_plutus_data());
|
insta::assert_debug_snapshot!(script_context.to_plutus_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn script_context_voting() {
|
||||||
|
let redeemer = Redeemer {
|
||||||
|
tag: RedeemerTag::Vote,
|
||||||
|
index: 0,
|
||||||
|
data: Data::constr(0, vec![Data::integer(42.into())]),
|
||||||
|
ex_units: ExUnits {
|
||||||
|
mem: 1000000,
|
||||||
|
steps: 100000000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: The transaction also contains treasury donation and current treasury amount
|
||||||
|
let script_context = fixture_tx_info(
|
||||||
|
"84a4008182582000000000000000000000000000000000000000000000000000\
|
||||||
|
0000000000000000018002182a13a58200581c00000000000000000000000000\
|
||||||
|
000000000000000000000000000000a182582099999999999999999999999999\
|
||||||
|
9999999999999999999999999999999999999918988200827668747470733a2f\
|
||||||
|
2f61696b656e2d6c616e672e6f72675820000000000000000000000000000000\
|
||||||
|
00000000000000000000000000000000008202581c0000000000000000000000\
|
||||||
|
0000000000000000000000000000000000a38258209999999999999999999999\
|
||||||
|
999999999999999999999999999999999999999999008202f682582088888888\
|
||||||
|
88888888888888888888888888888888888888888888888888888888018202f6\
|
||||||
|
8258207777777777777777777777777777777777777777777777777777777777\
|
||||||
|
777777028202f68203581c43fa47afc68a7913fbe2f400e3849cb492d9a2610c\
|
||||||
|
85966de0f2ba1ea1825820999999999999999999999999999999999999999999\
|
||||||
|
9999999999999999999999038200f68204581c00000000000000000000000000\
|
||||||
|
000000000000000000000000000000a182582099999999999999999999999999\
|
||||||
|
99999999999999999999999999999999999999048201f68201581c43fa47afc6\
|
||||||
|
8a7913fbe2f400e3849cb492d9a2610c85966de0f2ba1ea18258209999999999\
|
||||||
|
999999999999999999999999999999999999999999999999999999018201f6a2\
|
||||||
|
0582840402d87980821a000f42401a05f5e100840400d87981182a821a000f42\
|
||||||
|
401a05f5e1000781587d587b0101003232323232323225333333008001153330\
|
||||||
|
033370e900018029baa001153330073006375400224a66600894452615330054\
|
||||||
|
911856616c696461746f722072657475726e65642066616c7365001365600200\
|
||||||
|
2002002002002153300249010b5f746d70303a20566f696400165734ae7155ce\
|
||||||
|
aab9e5573eae91f5f6",
|
||||||
|
"8182582000000000000000000000000000000000000000000000000000000000\
|
||||||
|
0000000000",
|
||||||
|
"81a200581d600000000000000000000000000000000000000000000000000000\
|
||||||
|
0000011a000f4240",
|
||||||
|
)
|
||||||
|
.into_script_context(&redeemer, None)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// NOTE: The initial snapshot has been generated using the Haskell
|
||||||
|
// implementation of the ledger library for that same serialized
|
||||||
|
// transactions. It is meant to control that our construction of the
|
||||||
|
// script context and its serialization matches exactly those
|
||||||
|
// from the Haskell ledger / cardano node.
|
||||||
|
insta::assert_debug_snapshot!(script_context.to_plutus_data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,8 @@ use pallas_primitives::conway::{
|
||||||
AssetName, BigInt, Certificate, Coin, Constitution, Constr, DRep, DRepVotingThresholds,
|
AssetName, BigInt, Certificate, Coin, Constitution, Constr, DRep, DRepVotingThresholds,
|
||||||
DatumOption, ExUnitPrices, ExUnits, GovAction, GovActionId, Mint, PlutusData, PolicyId,
|
DatumOption, ExUnitPrices, ExUnits, GovAction, GovActionId, Mint, PlutusData, PolicyId,
|
||||||
PoolVotingThresholds, ProposalProcedure, ProtocolParamUpdate, PseudoScript, RationalNumber,
|
PoolVotingThresholds, ProposalProcedure, ProtocolParamUpdate, PseudoScript, RationalNumber,
|
||||||
Redeemer, ScriptRef, StakeCredential, TransactionInput, TransactionOutput, Value,
|
Redeemer, ScriptRef, StakeCredential, TransactionInput, TransactionOutput, Value, Vote, Voter,
|
||||||
|
VotingProcedure,
|
||||||
};
|
};
|
||||||
use pallas_traverse::ComputeHash;
|
use pallas_traverse::ComputeHash;
|
||||||
|
|
||||||
|
@ -953,6 +954,9 @@ impl ToPlutusData for ScriptPurpose {
|
||||||
ScriptPurpose::Certifying(ix, dcert) => {
|
ScriptPurpose::Certifying(ix, dcert) => {
|
||||||
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
||||||
}
|
}
|
||||||
|
ScriptPurpose::Voting(voter) => {
|
||||||
|
wrap_multiple_with_constr(4, vec![voter.to_plutus_data()])
|
||||||
|
}
|
||||||
ScriptPurpose::Proposing(ix, procedure) => {
|
ScriptPurpose::Proposing(ix, procedure) => {
|
||||||
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
||||||
}
|
}
|
||||||
|
@ -1293,6 +1297,42 @@ impl<'a> ToPlutusData for WithWrappedStakeCredential<'a, KeyValuePairs<Address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for Voter {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
Voter::ConstitutionalCommitteeScript(hash) => {
|
||||||
|
wrap_with_constr(0, StakeCredential::Scripthash(*hash).to_plutus_data())
|
||||||
|
}
|
||||||
|
Voter::ConstitutionalCommitteeKey(hash) => {
|
||||||
|
wrap_with_constr(0, StakeCredential::AddrKeyhash(*hash).to_plutus_data())
|
||||||
|
}
|
||||||
|
Voter::DRepScript(hash) => {
|
||||||
|
wrap_with_constr(1, StakeCredential::Scripthash(*hash).to_plutus_data())
|
||||||
|
}
|
||||||
|
Voter::DRepKey(hash) => {
|
||||||
|
wrap_with_constr(1, StakeCredential::AddrKeyhash(*hash).to_plutus_data())
|
||||||
|
}
|
||||||
|
Voter::StakePoolKey(hash) => wrap_with_constr(2, hash.to_plutus_data()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for VotingProcedure {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
self.vote.to_plutus_data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for Vote {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
Vote::No => empty_constr(0),
|
||||||
|
Vote::Yes => empty_constr(1),
|
||||||
|
Vote::Abstain => empty_constr(2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ToPlutusData for ScriptInfo<T>
|
impl<T> ToPlutusData for ScriptInfo<T>
|
||||||
where
|
where
|
||||||
T: ToPlutusData,
|
T: ToPlutusData,
|
||||||
|
@ -1309,6 +1349,7 @@ where
|
||||||
ScriptInfo::Certifying(ix, dcert) => {
|
ScriptInfo::Certifying(ix, dcert) => {
|
||||||
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
||||||
}
|
}
|
||||||
|
ScriptInfo::Voting(voter) => wrap_multiple_with_constr(4, vec![voter.to_plutus_data()]),
|
||||||
ScriptInfo::Proposing(ix, procedure) => {
|
ScriptInfo::Proposing(ix, procedure) => {
|
||||||
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
||||||
}
|
}
|
||||||
|
@ -1370,7 +1411,7 @@ impl ToPlutusData for TxInfo {
|
||||||
tx_info.redeemers.to_plutus_data(),
|
tx_info.redeemers.to_plutus_data(),
|
||||||
tx_info.data.to_plutus_data(),
|
tx_info.data.to_plutus_data(),
|
||||||
tx_info.id.to_plutus_data(),
|
tx_info.id.to_plutus_data(),
|
||||||
Data::map(vec![]), // TODO tx_info.votes :: Map Voter (Map GovernanceActionId Vote)
|
tx_info.votes.to_plutus_data(),
|
||||||
tx_info.proposal_procedures.to_plutus_data(),
|
tx_info.proposal_procedures.to_plutus_data(),
|
||||||
tx_info.current_treasury_amount.to_plutus_data(),
|
tx_info.current_treasury_amount.to_plutus_data(),
|
||||||
tx_info.treasury_donation.to_plutus_data(),
|
tx_info.treasury_donation.to_plutus_data(),
|
||||||
|
|
|
@ -9,14 +9,36 @@ Because we can't have fully static context (since they contain the validator
|
||||||
and its hash), we define _templates_.
|
and its hash), we define _templates_.
|
||||||
|
|
||||||
Everything is a bit clunky, but steps have been captured in a `test.sh` script
|
Everything is a bit clunky, but steps have been captured in a `test.sh` script
|
||||||
for convenience.
|
for convenience. The test still assumes a few things. For any
|
||||||
|
`VALIDATOR_GROUP`:
|
||||||
|
|
||||||
|
- There's a `ctx/{VALIDATOR_GROUP}/tx.template` and
|
||||||
|
`ctx/{VALIDATOR_GROUP}/resolved_inputs.template` respectively.
|
||||||
|
|
||||||
|
- There's a corresponding validator `validators/{VALIDATOR_GROUP}.ak`
|
||||||
|
|
||||||
|
- Templates may reference variables using a mustache-template-like syntax `{{ ... }}`.
|
||||||
|
Provided variables are:
|
||||||
|
- `{VALIDATOR_GROUP}.{VALIDATOR_TITLE}.hash`
|
||||||
|
- `{VALIDATOR_GROUP}.{VALIDATOR_TITLE}.cbor`
|
||||||
|
|
||||||
|
Where `VALIDATOR_TITLE` corresponds to the validator Aiken's name.
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
```
|
```
|
||||||
./test.sh [VALIDATOR_TITLE]
|
./test.sh VALIDATOR_GROUP
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> ![TIP]
|
||||||
|
> By default, this recompiles the project in --release mode, which can be long
|
||||||
|
> when iterating / testing. You can provide a binary to use as a second
|
||||||
|
> argument. For a dev build, just do:
|
||||||
|
>
|
||||||
|
> ```
|
||||||
|
> ./test.sh VALIDATOR_GROUP "cargo run --"
|
||||||
|
> ```
|
||||||
|
|
||||||
## Test Coverage
|
## Test Coverage
|
||||||
|
|
||||||
- Purpose
|
- Purpose
|
||||||
|
@ -24,7 +46,7 @@ for convenience.
|
||||||
- [x] mint
|
- [x] mint
|
||||||
- [ ] withdraw
|
- [ ] withdraw
|
||||||
- [x] publish
|
- [x] publish
|
||||||
- [ ] voting
|
- [x] voting
|
||||||
- [x] proposing
|
- [x] proposing
|
||||||
|
|
||||||
- Transaction body
|
- Transaction body
|
||||||
|
@ -66,7 +88,7 @@ for convenience.
|
||||||
- [x] datums
|
- [x] datums
|
||||||
- votes
|
- votes
|
||||||
- [x] none
|
- [x] none
|
||||||
- [ ] some
|
- [x] some
|
||||||
- proposal procedures
|
- proposal procedures
|
||||||
- [x] none
|
- [x] none
|
||||||
- [x] some
|
- [x] some
|
||||||
|
@ -122,14 +144,14 @@ for convenience.
|
||||||
- [x] info action
|
- [x] info action
|
||||||
|
|
||||||
- Vote
|
- Vote
|
||||||
- [ ] No
|
- [x] No
|
||||||
- [ ] Yes
|
- [x] Yes
|
||||||
- [ ] Abstain
|
- [x] Abstain
|
||||||
|
|
||||||
- Voter
|
- Voter
|
||||||
- [ ] CC
|
- [x] CC
|
||||||
- [ ] DRep
|
- [x] DRep
|
||||||
- [ ] SPO
|
- [x] SPO
|
||||||
|
|
||||||
- ChangedParameters
|
- ChangedParameters
|
||||||
- [x] txFeePerByte
|
- [x] txFeePerByte
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[
|
||||||
|
{ 0: h'6000000000000000000000000000000000000000000000000000000000'
|
||||||
|
, 1: 1000000
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
[
|
||||||
|
{ 0:
|
||||||
|
[ [h'0000000000000000000000000000000000000000000000000000000000000000', 0]
|
||||||
|
]
|
||||||
|
|
||||||
|
, 1:
|
||||||
|
[]
|
||||||
|
|
||||||
|
, 2: 42
|
||||||
|
|
||||||
|
, 19:
|
||||||
|
{ [ 0, h'00000000000000000000000000000000000000000000000000000000' ]:
|
||||||
|
{ [ h'9999999999999999999999999999999999999999999999999999999999999999', 152 ]:
|
||||||
|
[ 0
|
||||||
|
, [ "https://aiken-lang.org"
|
||||||
|
, h'0000000000000000000000000000000000000000000000000000000000000000'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
, [ 2, h'00000000000000000000000000000000000000000000000000000000' ]:
|
||||||
|
{ [ h'9999999999999999999999999999999999999999999999999999999999999999', 0 ]: [ 2, null ]
|
||||||
|
, [ h'8888888888888888888888888888888888888888888888888888888888888888', 1 ]: [ 2, null ]
|
||||||
|
, [ h'7777777777777777777777777777777777777777777777777777777777777777', 2 ]: [ 2, null ]
|
||||||
|
}
|
||||||
|
|
||||||
|
, [ 3, h'{{ voting.script.hash }}' ]:
|
||||||
|
{ [ h'9999999999999999999999999999999999999999999999999999999999999999', 3 ]: [ 0, null ]
|
||||||
|
}
|
||||||
|
|
||||||
|
, [ 4, h'00000000000000000000000000000000000000000000000000000000' ]:
|
||||||
|
{ [ h'9999999999999999999999999999999999999999999999999999999999999999', 4 ]: [ 1, null ]
|
||||||
|
}
|
||||||
|
|
||||||
|
, [ 1, h'{{ voting.script.hash }}' ]:
|
||||||
|
{ [ h'9999999999999999999999999999999999999999999999999999999999999999', 1 ]: [ 1, null ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ 5: [ [4, 2, 121([]), [1000000, 100000000]]
|
||||||
|
, [4, 0, 121([42]), [1000000, 100000000]]
|
||||||
|
]
|
||||||
|
|
||||||
|
, 7: [h'{{ voting.script.cbor }}']
|
||||||
|
},
|
||||||
|
|
||||||
|
true,
|
||||||
|
|
||||||
|
null
|
||||||
|
]
|
|
@ -6,7 +6,7 @@
|
||||||
"plutusVersion": "v3",
|
"plutusVersion": "v3",
|
||||||
"compiler": {
|
"compiler": {
|
||||||
"name": "Aiken",
|
"name": "Aiken",
|
||||||
"version": "v1.0.31-alpha+81c0152"
|
"version": "v1.0.31-alpha+bfc93bf"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
@ -82,6 +82,17 @@
|
||||||
},
|
},
|
||||||
"compiledCode": "59099f010100323232323232323232323232322533333300e00115332330073001300937540042a66601660146ea8008494cccccc04000454ccc020c008c028dd50008a99980618059baa001125333009323232323253330123758600660226ea8c014c044dd50030a9998091bac3014301530113754600a60226ea801854ccc048dd6180a180a980a980a980a980a980a980a980a98089baa30053011375400c2a66601c66e1d2054375a6028602a602a602a60226ea8c014c044dd5003099299980799baf4c101a0003015301630163016301630163016301630163016301630123754600c60246ea801c5288a9980824932657870656374205b5d203d3d20646963742e746f5f7061697273286374782e7472616e73616374696f6e2e646174756d73290016533300e3375e98012fa1d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8798000301430153015301530153015301530153015301530113754600a60226ea8018526153300f491e86578706563740a202020205b0a20202020202050616972285370656e64280a20202020202020204f75747075745265666572656e6365207b0a202020202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a202020202020202020206f75747075745f696e6465783a20302c0a20202020202020207d2c0a202020202020292c0a202020202020766f69642829292c0a202020205d203d3d2072656465656d6572730016153300f49120657870656374203432203d3d206374782e7472616e73616374696f6e2e6665650016153300f4912d657870656374205b5d203d206374782e7472616e73616374696f6e2e65787472615f7369676e61746f726965730016153300f4912c657870656374205b5d203d206374782e7472616e73616374696f6e2e7265666572656e63655f696e707574730016153300f49123657870656374205b5d203d206374782e7472616e73616374696f6e2e6f757470757473001632533301200100c132533301330160021323232325333013300d375a603260340042646464646464a66603266e1d2004301b3754603e0042a66466034600260386ea800854ccc068cdc7804245200000000000000000000000000000000000000000000000000000000000000000001533301a3375e6e98010dd3299980d25014bd6f7b6300991919800800a5eb7bdb180894ccc0840044cc088cdd82601014000374c00697adef6c60132323232533302133720910100002133026337609801014000374c00e00a2a66604266e3d22100002133026337609801014000374c00e00626604c66ec0dd48011ba600133006006003375660460066eb8c084008c094008c08c004c8cc0040052f5bded8c044a66604000226604266ec130010140004c01051a3b9aca00004bd6f7b630099191919299981019b90489000021330253376098010140004c01051a3b9aca0000005153330203371e9101000021330253376098010140004c01051a3b9aca0000003133025337606ea4008dd4000998030030019bad3022003375c60400046048004604400226464a6660386006603c6ea8c08800854ccc070c00cc078dd50008a4c03603660426044002603a6ea801854cc06d24013f657870656374207265736f6c7665645f696e7075745f76616c7565203d3d206173736574732e66726f6d5f6c6f76656c6163652831303030303030303030290016153301b491606578706563740a202020207472616e73616374696f6e5f6964203d3d20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030220016370e900100b80b980f180f800980f0011bab301c001301c002301a001301637540060226eb8c060004c050dd5180b801180b180b80098091baa00100d30140013758600860206ea8c010c040dd5002a99980619baf4c0132d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffd8799fd87980ffff003001300f37540082930a99806a49cd6578706563740a202020205370656e64696e67280a2020202020204f75747075745265666572656e6365207b0a20202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a20202020202020206f75747075745f696e6465783a20302c0a2020202020207d2c0a202020202020536f6d6528766f69642829292c0a2020202029203d3d20696e666f00162301230133013001533300a3371e910120c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b00375c602060226022602260226022602260226022602260226022601a6ea8c004c034dd50010a4c2a66016921546578706563740a2020202023226336666264333436363831613866383333376636623365353165366563393733663135303933363765616263336134346338343961663538613164383437316222203d3d206964001623010001149854cc0292411856616c696461746f722072657475726e65642066616c73650013656004004004004004004004370e90000018018018018018a99802a4810b5f746d70323a20566f6964001615330044910b5f746d70313a20566f696400161533003491ff657870656374205b0a20202020496e707574207b0a2020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b207472616e73616374696f6e5f69642c206f75747075745f696e6465783a2030207d2c0a2020202020206f75747075743a204f7574707574207b0a2020202020202020616464726573732c0a202020202020202076616c75653a207265736f6c7665645f696e7075745f76616c75652c0a2020202020202020646174756d3a20496e6c696e65446174756d285f292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a202020207d2c0a200b205d203d20696e7075747300161533002491566578706563742041646472657373207b207061796d656e745f63726564656e7469616c3a20536372697074285f292c207374616b655f63726564656e7469616c3a204e6f6e65207d203d0a202020206164647265737300165734ae7155ceaab9e5573eae815d0aba257481",
|
"compiledCode": "59099f010100323232323232323232323232322533333300e00115332330073001300937540042a66601660146ea8008494cccccc04000454ccc020c008c028dd50008a99980618059baa001125333009323232323253330123758600660226ea8c014c044dd50030a9998091bac3014301530113754600a60226ea801854ccc048dd6180a180a980a980a980a980a980a980a980a98089baa30053011375400c2a66601c66e1d2054375a6028602a602a602a60226ea8c014c044dd5003099299980799baf4c101a0003015301630163016301630163016301630163016301630123754600c60246ea801c5288a9980824932657870656374205b5d203d3d20646963742e746f5f7061697273286374782e7472616e73616374696f6e2e646174756d73290016533300e3375e98012fa1d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffffd8798000301430153015301530153015301530153015301530113754600a60226ea8018526153300f491e86578706563740a202020205b0a20202020202050616972285370656e64280a20202020202020204f75747075745265666572656e6365207b0a202020202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a202020202020202020206f75747075745f696e6465783a20302c0a20202020202020207d2c0a202020202020292c0a202020202020766f69642829292c0a202020205d203d3d2072656465656d6572730016153300f49120657870656374203432203d3d206374782e7472616e73616374696f6e2e6665650016153300f4912d657870656374205b5d203d206374782e7472616e73616374696f6e2e65787472615f7369676e61746f726965730016153300f4912c657870656374205b5d203d206374782e7472616e73616374696f6e2e7265666572656e63655f696e707574730016153300f49123657870656374205b5d203d206374782e7472616e73616374696f6e2e6f757470757473001632533301200100c132533301330160021323232325333013300d375a603260340042646464646464a66603266e1d2004301b3754603e0042a66466034600260386ea800854ccc068cdc7804245200000000000000000000000000000000000000000000000000000000000000000001533301a3375e6e98010dd3299980d25014bd6f7b6300991919800800a5eb7bdb180894ccc0840044cc088cdd82601014000374c00697adef6c60132323232533302133720910100002133026337609801014000374c00e00a2a66604266e3d22100002133026337609801014000374c00e00626604c66ec0dd48011ba600133006006003375660460066eb8c084008c094008c08c004c8cc0040052f5bded8c044a66604000226604266ec130010140004c01051a3b9aca00004bd6f7b630099191919299981019b90489000021330253376098010140004c01051a3b9aca0000005153330203371e9101000021330253376098010140004c01051a3b9aca0000003133025337606ea4008dd4000998030030019bad3022003375c60400046048004604400226464a6660386006603c6ea8c08800854ccc070c00cc078dd50008a4c03603660426044002603a6ea801854cc06d24013f657870656374207265736f6c7665645f696e7075745f76616c7565203d3d206173736574732e66726f6d5f6c6f76656c6163652831303030303030303030290016153301b491606578706563740a202020207472616e73616374696f6e5f6964203d3d20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030220016370e900100b80b980f180f800980f0011bab301c001301c002301a001301637540060226eb8c060004c050dd5180b801180b180b80098091baa00100d30140013758600860206ea8c010c040dd5002a99980619baf4c0132d87a9fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffd8799fd87980ffff003001300f37540082930a99806a49cd6578706563740a202020205370656e64696e67280a2020202020204f75747075745265666572656e6365207b0a20202020202020207472616e73616374696f6e5f69643a20232230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a20202020202020206f75747075745f696e6465783a20302c0a2020202020207d2c0a202020202020536f6d6528766f69642829292c0a2020202029203d3d20696e666f00162301230133013001533300a3371e910120c6fbd346681a8f8337f6b3e51e6ec973f1509367eabc3a44c849af58a1d8471b00375c602060226022602260226022602260226022602260226022601a6ea8c004c034dd50010a4c2a66016921546578706563740a2020202023226336666264333436363831613866383333376636623365353165366563393733663135303933363765616263336134346338343961663538613164383437316222203d3d206964001623010001149854cc0292411856616c696461746f722072657475726e65642066616c73650013656004004004004004004004370e90000018018018018018a99802a4810b5f746d70323a20566f6964001615330044910b5f746d70313a20566f696400161533003491ff657870656374205b0a20202020496e707574207b0a2020202020206f75747075745f7265666572656e63653a204f75747075745265666572656e6365207b207472616e73616374696f6e5f69642c206f75747075745f696e6465783a2030207d2c0a2020202020206f75747075743a204f7574707574207b0a2020202020202020616464726573732c0a202020202020202076616c75653a207265736f6c7665645f696e7075745f76616c75652c0a2020202020202020646174756d3a20496e6c696e65446174756d285f292c0a20202020202020207265666572656e63655f7363726970743a204e6f6e652c0a2020202020207d2c0a202020207d2c0a200b205d203d20696e7075747300161533002491566578706563742041646472657373207b207061796d656e745f63726564656e7469616c3a20536372697074285f292c207374616b655f63726564656e7469616c3a204e6f6e65207d203d0a202020206164647265737300165734ae7155ceaab9e5573eae815d0aba257481",
|
||||||
"hash": "cef0769e42ca13a9ffcd71a6ed03e3e03adb72f4cdf81bb28137c55a"
|
"hash": "cef0769e42ca13a9ffcd71a6ed03e3e03adb72f4cdf81bb28137c55a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "voting.script",
|
||||||
|
"redeemer": {
|
||||||
|
"title": "_tmp0",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Void"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compiledCode": "5908e2010100323232323232323232323232322533333300e00115332330073001300937540042a66601660146ea8008494ccc020c8c8c8c8c94ccc034c01cc03cdd500089919192999808180518091baa0021533233011300130133754602e60286ea800c54ccc0540080344c94ccc058c06400c4c8c8c94ccc054c014dd6980d980e0010a99980a9802980b9baa003153330153371e002910120999999999999999999999999999999999999999999999999999999999999999900153330153375e98158d8799f9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa1d8799f582099999999999999999999999999999999999999999999999999999999999999991898ffd87980ffff003300a00c480084c94ccc058c040c060dd50008991919299980c9804980d9baa002153330193009301b3754603e60386ea800854ccc07400405854ccc064cdd7a61abd8799f9fd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffa3d8799f5820777777777777777777777777777777777777777777777777777777777777777702ffd87b80d8799f5820888888888888888888888888888888888888888888888888888888888888888801ffd87b80d8799f5820999999999999999999999999999999999999999999999999999999999999999900ffd87b80ffff003300e010480184c94ccc068c050c070dd50008991919299980e99b8748010c07cdd5001099299981100100e0a99980f19b8f0014891c000000000000000000000000000000000000000000000000000000000014a22a6603e9211865787065637420706f6f6c5f6964203d3d206f6e6c7930730016375c604660406ea800806cdd5980f801180e8009919bb030210013021302200137586040603a6ea8004060cc0380412008153301a491ff6578706563740a202020202020536f6d65280a2020202020202020506169722844656c6567617465526570726573656e74617469766528566572696669636174696f6e4b6579286f6e6c79307329292c0a20202020202020205b0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7937732c2070726f706f73616c5f70726f6365647572653a2032207d2c0a202020202020202020204162737461696e292c0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7938732c2070726f706fb673616c5f70726f6365647572653a2031207d2c0a202020202020202020204162737461696e292c0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e3a206f6e6c7939732c2070726f706f73616c5f70726f6365647572653a2030207d2c0a202020202020202020204162737461696e292c0a20202020202020205d292c0a20202020202029203d3d206c6973742e617428766f7465732c20332900160160163756603600460320026466ec0c074004c074c078004dd6180e180c9baa0010133300a00c4801054cc0592401ff6578706563740a202020202020536f6d65280a20202020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228566572696669636174696f6e4b6579286f6e6c79307329292c0a20202020202020205b0a202020202020202020205061697228476f7665726e616e6365416374696f6e4964207b0a2020202020202020202020207472616e73616374696f6e3a206f6e6c7939732c0a20202020202020202020202070726f706f73616c5f70726f6365647572653a203135322c0a202020202020202020207d2c0a202020202020202020204e6f292c0a20202020202020205d292c0a20202020202029203d3d20116c6973742e617428766f7465732c203129001615330164911c657870656374207472616e73616374696f6e203d3d206f6e6c7939730016011011375c6034002602c6ea8c054008c054004038c05c008dc3a40040180186eacc048008c040004c8cdd8180a000980a180a8009bac301330103754002012660020069000180080091129998088010a60103d87a800013232533300f300900313374a90001980a1ba73301430110023301430120024bd7025eb804ccc014014004cdc0001a4002602a00660260046eacc03cc040c040c040c040c040c040c040c040c040c040c040c040c030dd5180798061baa0023253330093253333330120021533300a3004300c3754004264a66601e002004264a666666028002006006006264a66602260280062a66601a66e1d205400114a20080086eb400400cc044004c034dd500100080080080080089929999998090010a999805180218061baa0021533300e300d375400429440040040040040040045280a4c2a660149210f6578706563742069735f76616c69640016300e300f300b37540022930a99804a491856616c696461746f722072657475726e65642066616c73650013656006370e90000028028028028028a99802a481ab65787065637420536f6d65280a2020202020205061697228436f6e737469747574696f6e616c436f6d6d69747465654d656d62657228536372697074282e2e29292c0a2020202020205b5061697228476f7665726e616e6365416374696f6e4964207b207472616e73616374696f6e2c2070726f706f73616c5f70726f6365647572653a2031207d2c20596573295d292c0a2020202029203d206c6973742e617428766f7465732c203029001615330044915865787065637420536f6d6528506169722844656c6567617465526570726573656e74617469766528536372697074282e2e29292c205b5f2c202e2e5d2929203d0a2020202020206c6973742e617428766f7465732c203229001615330034914265787065637420536f6d652850616972285374616b65506f6f6c28706f6f6c5f6964292c205b5f2c202e2e5d2929203d206c6973742e617428766f7465732c203429001615330024910b5f746d70303a20566f696400165734ae7155ceaab9e5573eae815d0aba257481",
|
||||||
|
"hash": "849324b02de5c5d1cbf2226bd321e7ca5200de4a4c314864dbc24813"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
|
|
@ -56,8 +56,11 @@ for ITEM in ${VALIDATORS[@]}; do
|
||||||
done
|
done
|
||||||
|
|
||||||
echo $RESOLVED_INPUTS | cbor-diag --to hex --from diag > ctx/$TITLE/resolved_inputs.cbor
|
echo $RESOLVED_INPUTS | cbor-diag --to hex --from diag > ctx/$TITLE/resolved_inputs.cbor
|
||||||
|
|
||||||
echo $TRANSACTION | cbor-diag --to hex --from diag > ctx/$TITLE/tx.cbor
|
echo $TRANSACTION | cbor-diag --to hex --from diag > ctx/$TITLE/tx.cbor
|
||||||
|
|
||||||
|
# ogmios inspect transaction $(cat ctx/$TITLE/tx.cbor) | jq ".votes"
|
||||||
|
|
||||||
$AIKEN tx simulate \
|
$AIKEN tx simulate \
|
||||||
ctx/$TITLE/tx.cbor \
|
ctx/$TITLE/tx.cbor \
|
||||||
ctx/inputs.cbor \
|
ctx/inputs.cbor \
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
use aiken/collection/list
|
||||||
|
use cardano/credential.{Script, VerificationKey}
|
||||||
|
use cardano/governance.{
|
||||||
|
Abstain, ConstitutionalCommitteeMember, DelegateRepresentative,
|
||||||
|
GovernanceActionId, No, StakePool, Yes,
|
||||||
|
}
|
||||||
|
use cardano/transaction.{ScriptContext}
|
||||||
|
|
||||||
|
type Foo {
|
||||||
|
Foo(Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
const only0s = #"00000000000000000000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
const only7s =
|
||||||
|
#"7777777777777777777777777777777777777777777777777777777777777777"
|
||||||
|
|
||||||
|
const only8s =
|
||||||
|
#"8888888888888888888888888888888888888888888888888888888888888888"
|
||||||
|
|
||||||
|
const only9s =
|
||||||
|
#"9999999999999999999999999999999999999999999999999999999999999999"
|
||||||
|
|
||||||
|
validator {
|
||||||
|
fn script(_tmp0: Void, ctx: ScriptContext) {
|
||||||
|
assert_redeemer(ctx.redeemer)
|
||||||
|
|
||||||
|
let votes = ctx.transaction.votes
|
||||||
|
|
||||||
|
expect Some(
|
||||||
|
Pair(ConstitutionalCommitteeMember(Script(..)),
|
||||||
|
[Pair(GovernanceActionId { transaction, proposal_procedure: 1 }, Yes)]),
|
||||||
|
) = list.at(votes, 0)
|
||||||
|
expect transaction == only9s
|
||||||
|
|
||||||
|
expect
|
||||||
|
Some(
|
||||||
|
Pair(ConstitutionalCommitteeMember(VerificationKey(only0s)),
|
||||||
|
[
|
||||||
|
Pair(GovernanceActionId {
|
||||||
|
transaction: only9s,
|
||||||
|
proposal_procedure: 152,
|
||||||
|
},
|
||||||
|
No),
|
||||||
|
]),
|
||||||
|
) == list.at(votes, 1)
|
||||||
|
|
||||||
|
expect Some(Pair(DelegateRepresentative(Script(..)), [_, ..])) =
|
||||||
|
list.at(votes, 2)
|
||||||
|
|
||||||
|
expect
|
||||||
|
Some(
|
||||||
|
Pair(DelegateRepresentative(VerificationKey(only0s)),
|
||||||
|
[
|
||||||
|
Pair(GovernanceActionId { transaction: only7s, proposal_procedure: 2 },
|
||||||
|
Abstain),
|
||||||
|
Pair(GovernanceActionId { transaction: only8s, proposal_procedure: 1 },
|
||||||
|
Abstain),
|
||||||
|
Pair(GovernanceActionId { transaction: only9s, proposal_procedure: 0 },
|
||||||
|
Abstain),
|
||||||
|
]),
|
||||||
|
) == list.at(votes, 3)
|
||||||
|
|
||||||
|
expect Some(Pair(StakePool(pool_id), [_, ..])) = list.at(votes, 4)
|
||||||
|
expect pool_id == only0s
|
||||||
|
|
||||||
|
True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_redeemer(data: Data) {
|
||||||
|
let is_valid =
|
||||||
|
if data is Foo(42): Foo {
|
||||||
|
True
|
||||||
|
} else if data is Void {
|
||||||
|
True
|
||||||
|
} else {
|
||||||
|
False
|
||||||
|
}
|
||||||
|
|
||||||
|
expect is_valid
|
||||||
|
Void
|
||||||
|
}
|
Loading…
Reference in New Issue