Skip to content

Instantly share code, notes, and snippets.

@mgpai22
Created January 23, 2024 16:46
Show Gist options
  • Save mgpai22/638dcd9efdec5f74113a476175c7ee74 to your computer and use it in GitHub Desktop.
Save mgpai22/638dcd9efdec5f74113a476175c7ee74 to your computer and use it in GitHub Desktop.
winter object MVP contract
{
// ===== Contract Information ===== //
// Name: Object Event
// Description: This contract guards the event box that handles object events.
// Version: 1.0.0
// Author: Luca D'Angelo (luca.dangelo@zengate.global)
// ===== Box Contents ===== //
// Tokens
// 1. (EventToken, 1)
// Registers:
// R4[Int] Protocol Version
// R5[Coll[Byte]] Data Reference
// R6[Coll[Byte]] Event Creation Info
// R7[Coll[SigmaProp]] Signers
// ===== Relevant Transactions ===== //
// 1. Class Level Identification
// - Inputs: UserPK, Class1, ... , ClassM
// - DataInputs: None
// - Outputs: ObjectEvent, Class1, ... , ClassM, Object1, ... , ObjectM, WinterFee, MinerFee
// - Context Variables: None
// 2. Lot Level Identification
// - Inputs: UserPK, Lot1, ... , LotM
// - DataInputs: None
// - Outputs: ObjectEvent, Lot1, ... , LotM, Object1, ... , ObjectM, WinterFee, MinerFee
// - Context Variables: None
// 3. Class Instance Identification
// - Inputs: UserPK, Class
// - DataInputs: None
// - Outputs: ObjectEvent, Class, ObjectIssuer1, ... , ObjectIssuerM, WinterFee, MinerFee
// - Context Variables: None
// 4. Lot Instance Identification
// - Inputs: UserPK, Lot
// - DataInputs: None
// - Outputs: ObjectEvent, Lot, ObjectIssuer1, ... , ObjectIssuerM, WinterFee, MinerFee
// - Context Variables: None
// 5. Recreate Event
// - Inputs: UserPK, Event1, ... , EventM
// - DataInputs: None
// - Outputs: Event1, ... , EventM, WinterFee, MinerFee
// - Context Variables: TxType, MinerFee
// 6. Spend Event
// - Inputs: UserPK, Event1, ... , EventM
// - DataInputs: None
// - Outputs: WinterFee, MinerFee
// - Context Variables: TxType, MinerFee
// ===== Tx Types ===== //
// 0: Byte => Recreate Event
// 1: Byte => Spend Event
// ===== Compile Time Constants ($) ===== //
// $winterFeeAddressBytesHash: Coll[Byte]
// $winterFeeNitro: Long
// ===== Context Variables (_) ===== //
// _txType: Byte
// ===== Global Variables ===== //
val minerFeeErgoTreeBytesHash: Coll[Byte] = fromBase16("e540cceffd3b8dd0f401193576cc413467039695969427df94454193dddfb375")
val _txType: Byte = getVar[Byte](0).get
if (_txType == 0.toByte) {
// ===== Recreate Event Tx ===== //
val validRecreateEventTx: Boolean = {
// Outputs
val recreatedEventBoxOUT: Box = OUTPUTS.filter({ (output: Box) => output.tokens(0)._1 == SELF.tokens(0)._1 })(0)
val winterFeeBoxOUT: Box = OUTPUTS.filter({ (output: Box) => blake2b256(output.propositionBytes) == $winterFeeAddressBytesHash })(0)
val minerFeeBoxOUT: Box = OUTPUTS.filter({ (output: Box) => blake2b256(output.propositionBytes) == minerFeeErgoTreeBytesHash })(0)
val validSelfRecreatedEvent: Box = {
val validTxIdReplication: Boolean = {
if (SELF.R6[Coll[Byte]].get == Coll[Byte]()) {
(recreatedEventBoxOUT.R6[Coll[Byte]].get == SELF.creationInfo._2.slice(0, 32))
} else {
(recreatedEventBoxOUT.R6[Coll[Byte]].get == SELF.R6[Coll[Byte]].get)
}
}
allOf(Coll(
(recreatedEventBoxOUT.value == SELF.value),
(recreatedEventBoxOUT.propositionBytes == SELF.propositionBytes),
(recreatedEventBoxOUT.tokens.size == 1),
(recreatedEventBoxOUT.R4[Int].get == SELF.R4[Int].get),
(recreatedEventBoxOUT.R5[Coll[Byte]].get == SELF.R5[Coll[Byte]].get),
(validTxIdReplication),
(recreatedEventBoxOUT.R7[Coll[SigmaProp]].get == SELF.R7[Coll[SigmaProp]].get)
))
}
val validWinterFee: Boolean = {
allOf(Coll(
(winterFeeBoxOUT.value == $winterFeeNitro * minerFeeBoxOUT.value),
(winterFeeBoxOUT.tokens.size == 0)
))
}
val validMinerFee: Boolean = {
allOf(Coll(
(minerFeeBoxOUT.tokens.size == 0)
))
}
allOf(Coll(
validSelfRecreatedEvent,
validWinterFee,
validMinerFee
))
}
sigmaProp(validRecreateEventTx) && atLeast(1, SELF.R7[Coll[SigmaProp]].get) // All event boxes in inputs must have intersecting signer.
} else if (_txType == 1.toByte) {
// ===== Spend Event Tx ===== //
val validSpendEventTx: Boolean = {
// Outputs
val winterFeeBoxOUT: Box = OUTPUTS(0)
val minerFeeBoxOUT: Box = OUTPUTS(1)
val validBurn: Boolean = {
OUTPUTS.forall({ (output: Box) =>
output.tokens.forall({ (t: (Coll[Byte], Long)) => t._1 != SELF.tokens(0)._1 })
})
}
val validWinterFee: Boolean = {
allOf(Coll(
(winterFeeBoxOUT.value == $winterFeeNitro * minerFeeBoxOUT.value),
(blake2b256(winterFeeBoxOUT.propositionBytes) == $winterFeeAddressBytesHash),
(winterFeeBoxOUT.tokens.size == 0)
))
}
val validMinerFee: Boolean = {
allOf(Coll(
(minerFeeBoxOUT.tokens.size == 0),
(blake2b256(minerFeeBoxOUT.propositionBytes) == minerFeeErgoTreeBytesHash)
))
}
allOf(Coll(
validBurn,
validWinterFee,
validMinerFee
))
}
sigmaProp(validSpendEventTx) && atLeast(1, SELF.R7[Coll[SigmaProp]].get) // All event boxes in inputs must have intersecting signer.
} else {
sigmaProp(false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment