lichen_core/
contract_instruction.rs1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8pub enum ContractInstruction {
9 Deploy {
13 code: Vec<u8>,
15 init_data: Vec<u8>,
17 },
18
19 Call {
23 function: String,
25 args: Vec<u8>,
27 value: u64,
29 },
30
31 Upgrade {
35 code: Vec<u8>,
37 },
38
39 Close,
42
43 SetUpgradeTimelock {
48 epochs: u32,
51 },
52
53 ExecuteUpgrade,
56
57 VetoUpgrade,
60}
61
62impl ContractInstruction {
63 pub fn serialize(&self) -> Result<Vec<u8>, String> {
65 serde_json::to_vec(self).map_err(|e| e.to_string())
66 }
67
68 pub fn deserialize(data: &[u8]) -> Result<Self, String> {
70 serde_json::from_slice(data).map_err(|e| e.to_string())
71 }
72
73 pub fn deploy(code: Vec<u8>, init_data: Vec<u8>) -> Self {
75 ContractInstruction::Deploy { code, init_data }
76 }
77
78 pub fn call(function: String, args: Vec<u8>, value: u64) -> Self {
80 ContractInstruction::Call {
81 function,
82 args,
83 value,
84 }
85 }
86
87 pub fn upgrade(code: Vec<u8>) -> Self {
89 ContractInstruction::Upgrade { code }
90 }
91
92 pub fn close() -> Self {
94 ContractInstruction::Close
95 }
96
97 pub fn set_upgrade_timelock(epochs: u32) -> Self {
99 ContractInstruction::SetUpgradeTimelock { epochs }
100 }
101
102 pub fn execute_upgrade() -> Self {
104 ContractInstruction::ExecuteUpgrade
105 }
106
107 pub fn veto_upgrade() -> Self {
109 ContractInstruction::VetoUpgrade
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_deploy_instruction() {
119 let code = vec![0x00, 0x61, 0x73, 0x6d]; let init_data = vec![1, 2, 3];
121
122 let instr = ContractInstruction::deploy(code.clone(), init_data.clone());
123
124 match instr {
125 ContractInstruction::Deploy {
126 code: c,
127 init_data: d,
128 } => {
129 assert_eq!(c, code);
130 assert_eq!(d, init_data);
131 }
132 _ => panic!("Wrong instruction type"),
133 }
134 }
135
136 #[test]
137 fn test_call_instruction() {
138 let instr = ContractInstruction::call("transfer".to_string(), vec![1, 2, 3, 4], 1000);
139
140 match instr {
141 ContractInstruction::Call { function, .. } => {
142 assert_eq!(function, "transfer");
143 }
144 _ => panic!("Wrong instruction type"),
145 }
146 }
147
148 #[test]
149 fn test_serialization() {
150 let instr = ContractInstruction::call("test".to_string(), vec![1, 2, 3], 0);
151
152 let serialized = instr.serialize().unwrap();
153 let deserialized = ContractInstruction::deserialize(&serialized).unwrap();
154
155 assert_eq!(instr, deserialized);
156 }
157}