///! # 资产元数据管理 ///! ///! Asset Metadata Management ///! 管理资产的元数据和属性 ///! ///! **版本**: v1.0 ///! **模块**: charter-std/asset/metadata.ch use asset::gnacs::GNACSCode; use utils::crypto::sha3_384_hash; // ============================================================================ // 元数据结构 // ============================================================================ /// 资产元数据 /// /// 存储资产的详细信息 struct AssetMetadata { /// 资产ID asset_id: Hash, /// GNACS编码 gnacs_code: u48, /// 资产名称 name: String, /// 资产描述 description: String, /// 创建时间 created_at: Timestamp, /// 更新时间 updated_at: Timestamp, /// 资产URI(指向详细信息) uri: String, /// 自定义属性 attributes: Map, /// 文档哈希(SHA3-384) document_hashes: Vec, /// 估值信息 valuation: Option, /// 所有权历史 ownership_history: Vec } /// 属性值 /// /// 支持多种类型的属性值 enum AttributeValue { String(String), Number(u256), Boolean(bool), Address(Address), Timestamp(Timestamp), Hash(Hash) } /// 估值信息 struct ValuationInfo { /// 估值金额 amount: u256, /// 货币单位 currency: String, /// 估值日期 valuation_date: Timestamp, /// 估值机构 appraiser: Address, /// 估值报告哈希 report_hash: Hash, /// 有效期 valid_until: Timestamp } /// 所有权记录 struct OwnershipRecord { /// 所有者地址 owner: Address, /// 获得时间 acquired_at: Timestamp, /// 转让时间(如果已转让) transferred_at: Option, /// 交易哈希 transaction_hash: Hash } // ============================================================================ // 元数据管理器 // ============================================================================ /// 资产元数据管理器 certificate AssetMetadataManager { /// 元数据存储 (asset_id => metadata) let _metadata: Map; /// 管理员地址 let _admin: Address; /// 估值师白名单 let _approved_appraisers: Set
; // ========== 构造函数 ========== constructor() { self._admin = msg.sender; } // ========== 元数据管理 ========== /// 创建资产元数据 /// /// # 参数 /// - `asset_id`: 资产ID /// - `gnacs_code`: GNACS编码 /// - `name`: 资产名称 /// - `description`: 资产描述 /// - `uri`: 资产URI /// /// # 返回 /// - `bool`: 是否成功 pub fn create_metadata( asset_id: Hash, gnacs_code: u48, name: String, description: String, uri: String ) -> bool { require(!asset_id.is_zero(), "Invalid asset ID"); require(!name.is_empty(), "Name cannot be empty"); require(!self._metadata.contains_key(asset_id), "Metadata already exists"); // 验证GNACS编码 let gnacs = GNACSCode::from_u48(gnacs_code); require(gnacs.validate(), "Invalid GNACS code"); let metadata = AssetMetadata { asset_id: asset_id, gnacs_code: gnacs_code, name: name, description: description, created_at: block.timestamp, updated_at: block.timestamp, uri: uri, attributes: Map::new(), document_hashes: Vec::new(), valuation: None, ownership_history: vec![ OwnershipRecord { owner: msg.sender, acquired_at: block.timestamp, transferred_at: None, transaction_hash: tx.hash } ] }; self._metadata[asset_id] = metadata; return true; } /// 更新资产元数据 /// /// # 参数 /// - `asset_id`: 资产ID /// - `name`: 新名称(可选) /// - `description`: 新描述(可选) /// - `uri`: 新URI(可选) /// /// # 返回 /// - `bool`: 是否成功 pub fn update_metadata( asset_id: Hash, name: Option, description: Option, uri: Option ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); let mut metadata = self._metadata[asset_id]; if let Some(new_name) = name { require(!new_name.is_empty(), "Name cannot be empty"); metadata.name = new_name; } if let Some(new_desc) = description { metadata.description = new_desc; } if let Some(new_uri) = uri { metadata.uri = new_uri; } metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } /// 获取资产元数据 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `AssetMetadata`: 元数据 pub fn get_metadata(asset_id: Hash) -> AssetMetadata { require(self._metadata.contains_key(asset_id), "Metadata not found"); return self._metadata[asset_id]; } // ========== 属性管理 ========== /// 设置属性 /// /// # 参数 /// - `asset_id`: 资产ID /// - `key`: 属性键 /// - `value`: 属性值 /// /// # 返回 /// - `bool`: 是否成功 pub fn set_attribute( asset_id: Hash, key: String, value: AttributeValue ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); require(!key.is_empty(), "Key cannot be empty"); let mut metadata = self._metadata[asset_id]; metadata.attributes[key] = value; metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } /// 获取属性 /// /// # 参数 /// - `asset_id`: 资产ID /// - `key`: 属性键 /// /// # 返回 /// - `AttributeValue`: 属性值 pub fn get_attribute( asset_id: Hash, key: String ) -> Option { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; return metadata.attributes.get(key); } /// 删除属性 /// /// # 参数 /// - `asset_id`: 资产ID /// - `key`: 属性键 /// /// # 返回 /// - `bool`: 是否成功 pub fn remove_attribute( asset_id: Hash, key: String ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); let mut metadata = self._metadata[asset_id]; metadata.attributes.remove(key); metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } // ========== 文档管理 ========== /// 添加文档哈希 /// /// # 参数 /// - `asset_id`: 资产ID /// - `document_hash`: 文档哈希(SHA3-384) /// /// # 返回 /// - `bool`: 是否成功 pub fn add_document_hash( asset_id: Hash, document_hash: Hash ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); require(!document_hash.is_zero(), "Invalid document hash"); let mut metadata = self._metadata[asset_id]; metadata.document_hashes.push(document_hash); metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } /// 获取文档哈希列表 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `Vec`: 文档哈希列表 pub fn get_document_hashes(asset_id: Hash) -> Vec { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; return metadata.document_hashes; } /// 验证文档 /// /// # 参数 /// - `asset_id`: 资产ID /// - `document_hash`: 文档哈希 /// /// # 返回 /// - `bool`: 是否存在 pub fn verify_document( asset_id: Hash, document_hash: Hash ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; for hash in metadata.document_hashes { if hash == document_hash { return true; } } return false; } // ========== 估值管理 ========== /// 设置估值信息 /// /// # 参数 /// - `asset_id`: 资产ID /// - `amount`: 估值金额 /// - `currency`: 货币单位 /// - `report_hash`: 估值报告哈希 /// - `valid_until`: 有效期 /// /// # 返回 /// - `bool`: 是否成功 pub fn set_valuation( asset_id: Hash, amount: u256, currency: String, report_hash: Hash, valid_until: Timestamp ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); require(amount > 0, "Amount must be positive"); require(!currency.is_empty(), "Currency cannot be empty"); require(valid_until > block.timestamp, "Invalid expiry date"); require( self._approved_appraisers.contains(msg.sender), "Not an approved appraiser" ); let valuation = ValuationInfo { amount: amount, currency: currency, valuation_date: block.timestamp, appraiser: msg.sender, report_hash: report_hash, valid_until: valid_until }; let mut metadata = self._metadata[asset_id]; metadata.valuation = Some(valuation); metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } /// 获取估值信息 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `Option`: 估值信息 pub fn get_valuation(asset_id: Hash) -> Option { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; return metadata.valuation; } /// 检查估值是否有效 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `bool`: 是否有效 pub fn is_valuation_valid(asset_id: Hash) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; if let Some(valuation) = metadata.valuation { return valuation.valid_until > block.timestamp; } return false; } // ========== 所有权历史 ========== /// 记录所有权转移 /// /// # 参数 /// - `asset_id`: 资产ID /// - `new_owner`: 新所有者 /// /// # 返回 /// - `bool`: 是否成功 pub fn record_ownership_transfer( asset_id: Hash, new_owner: Address ) -> bool { require(self._metadata.contains_key(asset_id), "Metadata not found"); require(!new_owner.is_zero(), "Invalid new owner"); let mut metadata = self._metadata[asset_id]; // 更新最后一条记录的转让时间 if let Some(last_record) = metadata.ownership_history.last_mut() { last_record.transferred_at = Some(block.timestamp); } // 添加新的所有权记录 metadata.ownership_history.push(OwnershipRecord { owner: new_owner, acquired_at: block.timestamp, transferred_at: None, transaction_hash: tx.hash }); metadata.updated_at = block.timestamp; self._metadata[asset_id] = metadata; return true; } /// 获取所有权历史 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `Vec`: 所有权历史 pub fn get_ownership_history(asset_id: Hash) -> Vec { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; return metadata.ownership_history; } /// 获取当前所有者 /// /// # 参数 /// - `asset_id`: 资产ID /// /// # 返回 /// - `Address`: 当前所有者 pub fn get_current_owner(asset_id: Hash) -> Address { require(self._metadata.contains_key(asset_id), "Metadata not found"); let metadata = self._metadata[asset_id]; if let Some(last_record) = metadata.ownership_history.last() { return last_record.owner; } return Address::zero(); } // ========== 管理函数 ========== /// 添加批准的估值师 /// /// # 参数 /// - `appraiser`: 估值师地址 /// /// # 返回 /// - `bool`: 是否成功 pub fn add_appraiser(appraiser: Address) -> bool { require(msg.sender == self._admin, "Only admin"); require(!appraiser.is_zero(), "Invalid appraiser"); self._approved_appraisers.insert(appraiser); return true; } /// 移除批准的估值师 /// /// # 参数 /// - `appraiser`: 估值师地址 /// /// # 返回 /// - `bool`: 是否成功 pub fn remove_appraiser(appraiser: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._approved_appraisers.remove(appraiser); return true; } /// 检查是否为批准的估值师 /// /// # 参数 /// - `appraiser`: 估值师地址 /// /// # 返回 /// - `bool`: 是否批准 pub fn is_approved_appraiser(appraiser: Address) -> bool { return self._approved_appraisers.contains(appraiser); } }