Crate marlowe_lang
source ·Expand description
An experimental implementation of the Marlowe language for Cardano smart contracts.
Its primary use-case is for creating smart contracts in Rust rather than directly using Marlowe, and instead be able to export the contracts into Marlowe programatically.
§Grammars
This crate uses Pest.rs!
[grammars.rs] Click to expand/collapse
WHITESPACE = _{ " " | "\t" | "\r" | "\n" | "\r\n" }
comma = _{ "," }
lpar = _{ "(" }
rpar = _{ ")" }
lbra = _{ "[" }
rbra = _{ "]" }
Number = @{
"-"{0,1} ~ ASCII_DIGIT+
}
quoted_string = _{ "\"" ~ string ~ "\"" }
string = { str_char* }
str_char = _{
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" )
}
Timeout = _{ TimeoutHole | TimeConstant | TimeParam }
TimeConstant = ${ ASCII_DIGIT+ }
TimeInterval = { lpar ~ "TimeInterval" ~ Timeout ~ Timeout ~ rpar }
TimeParam = { lpar ~ "TimeParam" ~ quoted_string ~ rpar }
Token = _{TokenHole|ADA|Currency}
ADA = { "Token \"\" \"\"" }
Currency = { lpar ~ "Token" ~ quoted_string ~ quoted_string ~ rpar }
ChoiceId = { lpar ~"ChoiceId" ~ quoted_string ~ Party ~ rpar}
Value = _{
AvailableMoney
| ChoiceValue
| MulValue
| DivValue
| SubValue
| AddValue
| NegValue
| UseValue
| TimeIntervalStart
| TimeIntervalEnd
| ValueHole
| ConstantParam
| Constant
| Cond
}
TimeIntervalStart = { "TimeIntervalStart" }
TimeIntervalEnd = { "TimeIntervalEnd" }
Cond = { lpar ~ "Cond" ~ Observation ~ Value ~ Value ~ rpar}
ChoiceValue = { lpar ~ "ChoiceValue" ~ ChoiceId ~ rpar}
MulValue = { lpar ~ "MulValue" ~ Value ~ Value ~ rpar }
DivValue = { lpar ~ "DivValue" ~ Value ~ Value ~ rpar}
SubValue = { lpar ~ "SubValue" ~ Value ~ Value ~ rpar}
AddValue = { lpar ~ "AddValue" ~ Value ~ Value ~ rpar}
NegValue = { lpar ~ "NegValue" ~ Value ~ rpar}
UseValue = { lpar ~ "UseValue" ~ ValueId ~ rpar}
Constant = { lpar ~ "Constant" ~ Number ~ rpar }
ConstantParam = { lpar ~ "ConstantParam" ~ quoted_string ~ rpar }
AvailableMoney = { lpar ~ "AvailableMoney" ~ Party ~ Token ~ rpar}
Observation = _{ ObservationHole | TrueObs | FalseObs | ValueEQ | ValueLE |
ValueLT | ValueGT | ValueGE | OrObs |
NotObs | AndObs | ChoseSomething }
ValueEQ = { lpar ~ "ValueEQ" ~ Value ~ Value ~WHITESPACE* ~ rpar }
ValueLE = { lpar ~ "ValueLE" ~ Value ~ Value ~WHITESPACE* ~ rpar }
ValueLT = { lpar ~ "ValueLT" ~ Value ~ Value ~WHITESPACE* ~ rpar }
ValueGT = { lpar ~ "ValueGT" ~ Value ~ Value ~WHITESPACE* ~ rpar }
ValueGE = { lpar ~ "ValueGE" ~ Value ~ Value ~WHITESPACE* ~ rpar }
TrueObs = { "TrueObs" }
FalseObs = { "FalseObs" }
ChoseSomething = { lpar ~ "ChoseSomething" ~ ChoiceId ~ WHITESPACE* ~ rpar }
NotObs = { lpar ~ "NotObs" ~ Observation ~ rpar }
OrObs = { lpar ~ "OrObs" ~ Observation ~ Observation ~ rpar }
AndObs = { lpar ~ "AndObs" ~ Observation ~ Observation ~ rpar }
Action = _{ ActionHole | Notify | Choice | Deposit }
Deposit = { lpar ~"Deposit" ~ Party ~ FromParty ~ Token ~ Value ~ rpar }
Choice = { lpar ~"Choice" ~ ChoiceId ~ ArrayOfBounds ~ rpar }
Notify = { lpar ~"Notify" ~ Observation ~ rpar }
PossiblyMerkleizedContract = _{ContractHole|NonMerkleizedContract|MerkleizedContract}
NonMerkleizedContract = { WrappedContract }
MerkleizedContract = {
lpar ~ "MerkleizedThen" ~ quoted_string ~ rpar
| "MerkleizedThen" ~ quoted_string
}
Case = {
lpar ~ "Case" ~ Action ~ PossiblyMerkleizedContract ~ rpar
| "Case" ~ Action ~ PossiblyMerkleizedContract
}
Bound = ${
lpar ~ "Bound" ~ WHITESPACE+ ~ Number ~ WHITESPACE+ ~ Number ~ WHITESPACE* ~ rpar
| "Bound" ~ WHITESPACE+ ~ Number ~ WHITESPACE+ ~ Number ~ WHITESPACE*
}
Payee = _{ PayeeHole | PayeeAccount | PayeeParty }
PayeeAccount = { lpar ~ "Account" ~ Party ~ rpar }
PayeeParty = { lpar ~ "Party" ~ Party ~ rpar }
Party = _{ PartyHole | Role | Address }
FromParty = _{ FromPartyHole | Role | Address }
Role = { lpar ~ "Role" ~ quoted_string ~ rpar }
Address = { lpar ~ "Address" ~ quoted_string ~ rpar }
Account = { "Account" ~ Party }
MainContract = _{ Contract ~ EOI }
ValueId = { quoted_string }
Contract = { Close | When | If | Let | Assert | Pay }
When = { "When" ~ ArrayOfCases ~ Timeout ~ WrappedContract }
Pay = { "Pay" ~ Party ~ Payee ~ Token ~ Value ~ WrappedContract }
If = { "If" ~ Observation ~ WrappedContract ~ WrappedContract }
Let = { "Let" ~ ValueId ~ Value ~ WrappedContract }
Assert = { "Assert" ~ Observation ~ WrappedContract }
Close = { "Close" }
WrappedContract = _{
ContractHole | Close | "(" ~ (Assert|Let|If|Pay|When) ~ ")"
}
ArrayOfCases = {
lbra ~ (Case|CaseHole) ~ ("," ~ (Case|CaseHole))* ~ rbra
| lbra ~ rbra
}
ArrayOfBounds = {
lbra ~ (Bound|BoundHole) ~ ("," ~ (Bound|BoundHole))* ~ rbra
| lbra ~ rbra
}
Hole = _ { "?"~("-"|"_"|ASCII_DIGIT|ASCII_ALPHA)* }
PartyHole = { Hole }
FromPartyHole = { Hole }
ContractHole = { Hole }
PayeeHole = { Hole }
ValueHole = { Hole }
ObservationHole = { Hole }
TimeoutHole = { Hole }
TokenHole = { Hole }
BoundHole = { Hole }
RoleHole = { Hole }
CaseHole = { Hole }
ActionHole = { Hole }
AccountHole = { Hole }
§Example usage
use marlowe_lang::types::marlowe::*;
use marlowe_lang::{
deserialization::marlowe::deserialize,
serialization::marlowe::serialize,
};
let my_contract = Contract::When {
when: vec![
Some(PossiblyMerkleizedCase::Raw {
case: Some(Action::Notify {
notify_if: Some(Observation::True)
}),
then: Some(Contract::Close) })
],
timeout: Some(Timeout::TimeParam("test".into())),
timeout_continuation: Some(Contract::Close.boxed()),
};
let serialized = serialize(my_contract);
let deserialized : Contract = deserialize(&serialized).unwrap().contract;
println!("{serialized}");
§Where ‘println!(“{serialized}”)’ would output this:
When [ Case (Notify (True)) Close ] (TimeParam "test") Close
Re-exports§
pub use plutus_data;
Modules§
- Extra features such as plutus encoding/decoding, cli tool etc.
- Where the parsing happens
- Top level types module