// NVM-L1 合约定义 use crate::types::{Address, Hash}; use serde::{Deserialize, Serialize}; /// 合约代码 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContractCode { /// 字节码 pub bytecode: Vec, /// 代码哈希 pub code_hash: Hash, } impl ContractCode { /// 创建新的合约代码 pub fn new(bytecode: Vec) -> Self { let code_hash = Hash::sha3_384(&bytecode); Self { bytecode, code_hash, } } /// 获取字节码 pub fn bytecode(&self) -> &[u8] { &self.bytecode } /// 获取代码哈希 pub fn code_hash(&self) -> &Hash { &self.code_hash } /// 获取代码大小 pub fn size(&self) -> usize { self.bytecode.len() } } /// 合约元数据 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContractMetadata { /// 合约名称 pub name: String, /// 合约版本 pub version: String, /// 合约作者 pub author: String, /// 合约描述 pub description: String, /// 创建时间 pub created_at: u64, } impl Default for ContractMetadata { fn default() -> Self { Self { name: String::new(), version: "1.0.0".to_string(), author: String::new(), description: String::new(), created_at: 0, } } } /// 合约状态 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ContractState { /// 活跃 Active, /// 暂停 Paused, /// 已销毁 Destroyed, } /// 合约 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Contract { /// 合约地址 pub address: Address, /// 合约代码 pub code: ContractCode, /// 合约元数据 pub metadata: ContractMetadata, /// 合约状态 pub state: ContractState, /// 合约所有者 pub owner: Address, /// 合约余额 pub holdings: u128, /// 存储根哈希 pub storage_root: Hash, /// Nonce pub nonce: u64, } impl Contract { /// 创建新合约 pub fn new( address: Address, code: ContractCode, owner: Address, metadata: ContractMetadata, ) -> Self { Self { address, code, metadata, state: ContractState::Active, owner, holdings: 0, storage_root: Hash::zero(), nonce: 0, } } /// 检查合约是否活跃 pub fn is_active(&self) -> bool { self.state == ContractState::Active } /// 暂停合约 pub fn pause(&mut self) { self.state = ContractState::Paused; } /// 恢复合约 pub fn resume(&mut self) { self.state = ContractState::Active; } /// 销毁合约 pub fn destroy(&mut self) { self.state = ContractState::Destroyed; } /// 增加余额 pub fn add_balance(&mut self, amount: u128) { self.holdings = self.holdings.saturating_add(amount); } /// 减少余额 pub fn sub_balance(&mut self, amount: u128) -> Result<(), String> { if self.holdings < amount { return Err("Insufficient holdings".to_string()); } self.holdings -= amount; Ok(()) } /// 增加nonce pub fn increment_nonce(&mut self) { self.nonce = self.nonce.saturating_add(1); } /// 更新存储根 pub fn update_storage_root(&mut self, root: Hash) { self.storage_root = root; } } #[cfg(test)] mod tests { use super::*; fn create_test_contract() -> Contract { let address = Address::new([1u8; 20]); let owner = Address::new([2u8; 20]); let code = ContractCode::new(vec![0x60, 0x60, 0x60, 0x40]); let metadata = ContractMetadata::default(); Contract::new(address, code, owner, metadata) } #[test] fn test_contract_creation() { let contract = create_test_contract(); assert!(contract.is_active()); assert_eq!(contract.holdings, 0); assert_eq!(contract.nonce, 0); } #[test] fn test_contract_pause_resume() { let mut contract = create_test_contract(); contract.pause(); assert!(!contract.is_active()); contract.resume(); assert!(contract.is_active()); } #[test] fn test_contract_balance() { let mut contract = create_test_contract(); contract.add_balance(1000); assert_eq!(contract.holdings, 1000); assert!(contract.sub_balance(500).is_ok()); assert_eq!(contract.holdings, 500); } #[test] fn test_contract_nonce() { let mut contract = create_test_contract(); contract.increment_nonce(); assert_eq!(contract.nonce, 1); contract.increment_nonce(); assert_eq!(contract.nonce, 2); } #[test] fn test_contract_destroy() { let mut contract = create_test_contract(); contract.destroy(); assert_eq!(contract.state, ContractState::Destroyed); } }