Refactor build steps to generate blueprints instead
The blueprint is generated at the root of the repository and is intended to be versioned with the rest. It acts as a business card that contains many practical information. There's a variety of tools we can then build on top of open-source contracts. And, quite importantly, the blueprint is language-agnostic; it isn't specific to Aiken. So it is really meant as an interop format within the ecosystem.
This commit is contained in:
121
crates/aiken-project/src/blueprint/validator.rs
Normal file
121
crates/aiken-project/src/blueprint/validator.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
use super::schema::Schema;
|
||||
use pallas::ledger::primitives::babbage as cardano;
|
||||
use pallas_traverse::ComputeHash;
|
||||
use serde::{
|
||||
self,
|
||||
ser::{Serialize, SerializeStruct, Serializer},
|
||||
};
|
||||
use std::fmt::{self, Display};
|
||||
use uplc::ast::{NamedDeBruijn, Program};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Validator {
|
||||
pub purpose: Purpose,
|
||||
pub description: Option<String>,
|
||||
pub datum: Option<Schema>,
|
||||
pub redeemer: Schema,
|
||||
pub program: Program<NamedDeBruijn>,
|
||||
}
|
||||
|
||||
impl Serialize for Validator {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let cbor = self.program.to_cbor().unwrap();
|
||||
let source_code = hex::encode(&cbor);
|
||||
let mut s = serializer.serialize_struct("Validator", 5)?;
|
||||
s.serialize_field("purpose", &self.purpose)?;
|
||||
let hash = cardano::PlutusV2Script(cbor.into()).compute_hash();
|
||||
s.serialize_field("hash", &hash)?;
|
||||
if let Some { .. } = self.description {
|
||||
s.serialize_field("description", &self.description)?;
|
||||
}
|
||||
if let Some { .. } = self.datum {
|
||||
s.serialize_field("datum", &self.datum)?;
|
||||
}
|
||||
s.serialize_field("redeemer", &self.redeemer)?;
|
||||
s.serialize_field("compiledCode", &source_code)?;
|
||||
s.end()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Purpose {
|
||||
Spend,
|
||||
Mint,
|
||||
Withdraw,
|
||||
Publish,
|
||||
}
|
||||
|
||||
impl Purpose {
|
||||
pub fn min_arity(&self) -> u8 {
|
||||
match self {
|
||||
Purpose::Spend => 3,
|
||||
Purpose::Mint | Purpose::Withdraw | Purpose::Publish => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Purpose {
|
||||
fn from(purpose: String) -> Purpose {
|
||||
match &purpose[..] {
|
||||
"spend" => Purpose::Spend,
|
||||
"mint" => Purpose::Mint,
|
||||
"withdraw" => Purpose::Withdraw,
|
||||
"publish" => Purpose::Publish,
|
||||
unexpected => panic!("Can't turn '{}' into any Purpose", unexpected),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Purpose {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(match self {
|
||||
Purpose::Spend => "spend",
|
||||
Purpose::Mint => "mint",
|
||||
Purpose::Withdraw => "withdraw",
|
||||
Purpose::Publish => "publish",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::schema::Constructor;
|
||||
use super::*;
|
||||
use serde_json::{self, json};
|
||||
use uplc::parser;
|
||||
|
||||
#[test]
|
||||
fn serialize() {
|
||||
let program = parser::program("(program 1.0.0 (con integer 42))")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let validator = Validator {
|
||||
description: Some("Lorem ipsum".to_string()),
|
||||
purpose: Purpose::Spend,
|
||||
datum: None,
|
||||
redeemer: Schema::AnyOf(vec![Constructor {
|
||||
index: 0,
|
||||
fields: vec![Schema::Bytes],
|
||||
}]),
|
||||
program,
|
||||
};
|
||||
assert_eq!(
|
||||
serde_json::to_value(&validator).unwrap(),
|
||||
json!({
|
||||
"description": "Lorem ipsum",
|
||||
"purpose": "spend",
|
||||
"redeemer": {
|
||||
"dataType": "constructor",
|
||||
"index": 0,
|
||||
"fields": [{
|
||||
"dataType": "bytes"
|
||||
}]
|
||||
},
|
||||
"compiledCode": "46010000481501",
|
||||
"hash": "27dc8e44c17b4ae5f4b9286ab599fffe70e61b49dec61eaca1fc5898"
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user