added more implementations for ToPlutusData
This commit is contained in:
parent
60d7c52c26
commit
4e51826981
|
@ -1,11 +1,17 @@
|
||||||
use pallas_addresses::{Address, PaymentKeyHash};
|
use pallas_addresses::Address;
|
||||||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
use pallas_codec::{
|
||||||
use pallas_crypto::hash::Hash;
|
minicbor::{bytes::ByteVec, data::Int},
|
||||||
use pallas_primitives::babbage::{
|
utils::{AnyUInt, KeyValuePairs, MaybeIndefArray},
|
||||||
BigInt, Certificate, Constr, DatumHash, PolicyId, PostAlonzoTransactionOutput, Redeemer,
|
};
|
||||||
StakeCredential, TransactionInput, Value, Withdrawals,
|
use pallas_crypto::hash::Hash;
|
||||||
|
use pallas_primitives::{
|
||||||
|
babbage::{
|
||||||
|
AddrKeyhash, AssetName, BigInt, Certificate, Constr, DatumHash, DatumOption, PolicyId,
|
||||||
|
PostAlonzoTransactionOutput, Redeemer, RewardAccount, Script, ScriptRef, StakeCredential,
|
||||||
|
TransactionInput, TransactionOutput, Value, Withdrawals,
|
||||||
|
},
|
||||||
|
ToHash,
|
||||||
};
|
};
|
||||||
use pallas_traverse::OutputRef;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use uplc::PlutusData;
|
use uplc::PlutusData;
|
||||||
|
|
||||||
|
@ -174,30 +180,190 @@ impl ToPlutusData for TransactionInput {
|
||||||
tag: 0,
|
tag: 0,
|
||||||
any_constructor: None,
|
any_constructor: None,
|
||||||
fields: MaybeIndefArray::Indef(vec![
|
fields: MaybeIndefArray::Indef(vec![
|
||||||
PlutusData::BoundedBytes(hex::decode(self.transaction_id.clone()).unwrap().into()),
|
self.transaction_id.to_plutus_data(),
|
||||||
PlutusData::BigInt(BigInt::Int(self.index.into())),
|
PlutusData::BigInt(BigInt::Int(self.index.into())),
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl ToPlutusData for LegacyTransactionOutput {
|
impl<const BYTES: usize> ToPlutusData for Hash<BYTES> {
|
||||||
// fn to_plutus_data(&self) -> PlutusData {}
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
// }
|
PlutusData::BoundedBytes(self.to_vec().into())
|
||||||
|
}
|
||||||
// impl ToPlutusData for PostAlonzoTransactionOutput {
|
}
|
||||||
// fn to_plutus_data(&self) -> PlutusData {}
|
|
||||||
// }
|
impl ToPlutusData for ByteVec {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
pub struct TxInInfo {
|
PlutusData::BoundedBytes(self.clone())
|
||||||
out_ref: OutputRef,
|
}
|
||||||
resolved: PostAlonzoTransactionOutput,
|
}
|
||||||
|
|
||||||
|
impl<A: ToPlutusData> ToPlutusData for Vec<A> {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
PlutusData::Array(MaybeIndefArray::Indef(
|
||||||
|
self.iter().map(|p| p.to_plutus_data()).collect(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: ToPlutusData> ToPlutusData for Option<A> {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
None => PlutusData::Constr(Constr {
|
||||||
|
tag: 1,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![]),
|
||||||
|
}),
|
||||||
|
Some(data) => PlutusData::Constr(Constr {
|
||||||
|
tag: 0,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![data.to_plutus_data()]),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for DatumOption {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
// tag : 0 is NoOutputDatum. Determined after unwrapping Option which is wrapped around DatumOption
|
||||||
|
DatumOption::Hash(hash) => PlutusData::Constr(Constr {
|
||||||
|
tag: 1,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![hash.to_plutus_data()]),
|
||||||
|
}),
|
||||||
|
DatumOption::Data(data) => PlutusData::Constr(Constr {
|
||||||
|
tag: 2,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![data.0.clone()]), // does data need an extra wrapper constructor?
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for AnyUInt {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
AnyUInt::U8(u8) => PlutusData::BigInt(BigInt::Int(Int::from(*u8))),
|
||||||
|
AnyUInt::U16(u16) => PlutusData::BigInt(BigInt::Int(Int::from(*u16))),
|
||||||
|
AnyUInt::U32(u32) => PlutusData::BigInt(BigInt::Int(Int::from(*u32))),
|
||||||
|
AnyUInt::U64(u64) => PlutusData::BigInt(BigInt::Int(Int::from(*u64))),
|
||||||
|
AnyUInt::MajorByte(u8) => PlutusData::BigInt(BigInt::Int(Int::from(*u8))), // is this correct? I don't know exactly what is does
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for Value {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
Value::Coin(coin) => PlutusData::Map(KeyValuePairs::Def(vec![(
|
||||||
|
PolicyId::from(vec![]).to_plutus_data(),
|
||||||
|
PlutusData::Map(KeyValuePairs::Def(vec![(
|
||||||
|
AssetName::from(vec![]).to_plutus_data(),
|
||||||
|
coin.to_plutus_data(),
|
||||||
|
)])),
|
||||||
|
)])),
|
||||||
|
Value::Multiasset(coin, multiassets) => {
|
||||||
|
let mut data_vec: Vec<(PlutusData, PlutusData)> = vec![(
|
||||||
|
PolicyId::from(vec![]).to_plutus_data(),
|
||||||
|
PlutusData::Map(KeyValuePairs::Def(vec![(
|
||||||
|
AssetName::from(vec![]).to_plutus_data(),
|
||||||
|
coin.to_plutus_data(),
|
||||||
|
)])),
|
||||||
|
)];
|
||||||
|
|
||||||
|
for (policy_id, assets) in multiassets.iter() {
|
||||||
|
let mut assets_vec = vec![];
|
||||||
|
for (asset, amount) in assets.iter() {
|
||||||
|
assets_vec.push((asset.to_plutus_data(), amount.to_plutus_data()));
|
||||||
|
}
|
||||||
|
data_vec.push((
|
||||||
|
policy_id.to_plutus_data(),
|
||||||
|
PlutusData::Map(KeyValuePairs::Def(assets_vec)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
PlutusData::Map(KeyValuePairs::Def(data_vec))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for ScriptRef {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match &self.0 {
|
||||||
|
Script::NativeScript(native_script) => native_script.to_hash().to_plutus_data(),
|
||||||
|
Script::PlutusV1Script(plutus_v1) => plutus_v1.to_hash().to_plutus_data(),
|
||||||
|
Script::PlutusV2Script(plutus_v2) => plutus_v2.to_hash().to_plutus_data(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for TransactionOutput {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
TransactionOutput::Legacy(legacy_output) => PlutusData::Constr(Constr {
|
||||||
|
tag: 0,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![
|
||||||
|
Address::from_bytes(&legacy_output.address)
|
||||||
|
.unwrap()
|
||||||
|
.to_plutus_data(),
|
||||||
|
legacy_output.amount.to_plutus_data(),
|
||||||
|
None::<DatumOption>.to_plutus_data(),
|
||||||
|
None::<ScriptRef>.to_plutus_data(),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
TransactionOutput::PostAlonzo(post_alonzo_output) => PlutusData::Constr(Constr {
|
||||||
|
tag: 0,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![
|
||||||
|
Address::from_bytes(&post_alonzo_output.address)
|
||||||
|
.unwrap()
|
||||||
|
.to_plutus_data(),
|
||||||
|
post_alonzo_output.value.to_plutus_data(),
|
||||||
|
// DatumOption needs to be handled differently a bit. In Haskell it's NoOutputDatum | OutputDatumHash DatumHash | OutputDatum Datum
|
||||||
|
// So we unwrap first to check if it's someting. If it is then turn the unwrapped data to PlutusData, otherwise have None and turn that into PlutusData
|
||||||
|
if post_alonzo_output.datum_option.is_some() {
|
||||||
|
post_alonzo_output
|
||||||
|
.datum_option
|
||||||
|
.clone()
|
||||||
|
.unwrap()
|
||||||
|
.to_plutus_data()
|
||||||
|
} else {
|
||||||
|
None::<DatumOption>.to_plutus_data()
|
||||||
|
},
|
||||||
|
post_alonzo_output.script_ref.to_plutus_data(),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for TxInInfo {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
PlutusData::Constr(Constr {
|
||||||
|
tag: 0,
|
||||||
|
any_constructor: None,
|
||||||
|
fields: MaybeIndefArray::Indef(vec![
|
||||||
|
self.out_ref.to_plutus_data(),
|
||||||
|
self.resolved.to_plutus_data(),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plutus V2 only for now
|
||||||
|
|
||||||
|
pub struct TxInInfo {
|
||||||
|
out_ref: TransactionInput,
|
||||||
|
resolved: TransactionOutput,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plutus V2
|
|
||||||
pub enum ScriptPurpose {
|
pub enum ScriptPurpose {
|
||||||
Minting(PolicyId),
|
Minting(PolicyId),
|
||||||
Spending(OutputRef),
|
Spending(TransactionInput),
|
||||||
Reward(StakeCredential),
|
Reward(StakeCredential),
|
||||||
Certifying(Certificate),
|
Certifying(Certificate),
|
||||||
}
|
}
|
||||||
|
@ -205,14 +371,19 @@ pub enum ScriptPurpose {
|
||||||
pub struct TxInfo {
|
pub struct TxInfo {
|
||||||
inputs: Vec<TxInInfo>,
|
inputs: Vec<TxInInfo>,
|
||||||
reference_inputs: Vec<TxInInfo>,
|
reference_inputs: Vec<TxInInfo>,
|
||||||
outputs: Vec<PostAlonzoTransactionOutput>,
|
outputs: Vec<TransactionOutput>,
|
||||||
fee: Value,
|
fee: Value,
|
||||||
mint: Value,
|
mint: Value,
|
||||||
dcert: Vec<Certificate>,
|
dcert: Vec<Certificate>,
|
||||||
wdrl: Withdrawals,
|
wdrl: Withdrawals,
|
||||||
valid_range: PosixTimeRange,
|
valid_range: PosixTimeRange,
|
||||||
signatories: Vec<PaymentKeyHash>,
|
signatories: Vec<AddrKeyhash>,
|
||||||
redeemers: KeyValuePairs<ScriptPurpose, Redeemer>,
|
redeemers: KeyValuePairs<ScriptPurpose, Redeemer>,
|
||||||
data: KeyValuePairs<DatumHash, PlutusData>,
|
data: KeyValuePairs<DatumHash, PlutusData>,
|
||||||
id: Hash<32>,
|
id: Hash<32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ScriptContext {
|
||||||
|
tx_info: TxInfo,
|
||||||
|
purpose: ScriptPurpose,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue