# ACC-20C 兼容层协议 - 包装器核心合约 # 版本: 1.0 # 路径: charter-std/acc/acc20c_wrapper.ch # --- 核心原则 --- # 1. 状态容器: 本合约仅作为状态容器,不包含任何主动的合规检查逻辑。 # 2. 宪法驱动: 所有关键操作(wrap, unwrap, transfer)都假定已通过 CEE 的宪法审查,并获得了有效的宪法收据(CR)。 # 3. 原生实现: 完全使用 Charter 语言原生特性。 # --- 标准库与接口导入 --- import std::types::{ Address, Uint256, Uint64, Bool, String } import std::collections::{ mapping } import std::events::{ emit } # 导入 ACC-20 标准接口,用于与底层资产交互 # 注意:此处的 IAcc20 接口需要在 charter-std 中有明确定义 import charter-std::acc::i_acc20::{ IAcc20 } # --- 合约状态定义 --- state { # 包装后资产的详细信息 # mapping: wrapper_token_id -> WrappedAsset wrapped_assets: mapping(Uint256 => WrappedAsset), # 从原始 ACC-20 资产到包装后资产的映射 # mapping: acc20_contract_address -> (acc20_token_id -> wrapper_token_id) acc20_to_wrapper: mapping(Address => mapping(Uint256 => Uint256)), # 下一个可用的包装 Token ID next_wrapper_token_id: Uint256, # 合约管理员 admin: Address, } # --- 数据结构定义 --- # 包装资产的状态枚举 enum WrappedStatus { ACTIVE, # 活跃,可交易 FROZEN, # 冻结,由管理员操作,不可交易 PENDING_UNWRAP, # 等待解包中 } # 包装后资产的核心数据结构 struct WrappedAsset { acc20_deed_address: Address, # 原始 ACC-20 权证合约地址 acc20_deed_token_id: Uint256, # 原始 ACC-20 权证代币 ID owner: Address, # 当前包装后资产的所有者 status: WrappedStatus, # 当前状态 wrapped_at: Uint64, # 包装时间戳 unlock_timestamp: Uint64, # 解包冷却期截止时间 } # --- 事件定义 --- # 资产被成功包装事件 event AssetWrapped { wrapper_token_id: Uint256, acc20_contract: Address, acc20_token_id: Uint256, owner: Address, } # 资产被成功解包事件 event AssetUnwrapped { wrapper_token_id: Uint256, owner: Address, } # 包装后资产所有权转移事件 event Transfer { from: Address, to: Address, wrapper_token_id: Uint256, } # --- 合约初始化 --- fn constructor() { state.next_wrapper_token_id = 1; state.admin = msg.sender; } # --- 核心功能函数 --- # @dev 包装一个 ACC-20 资产 # @param acc20_contract 原始 ACC-20 合约地址 # @param acc20_token_id 原始 ACC-20 代币 ID # @returns 新铸造的包装资产 ID fn wrap(acc20_contract: Address, acc20_token_id: Uint256) -> Uint256 { # 前置检查:确保该资产未被包装 require(state.acc20_to_wrapper[acc20_contract][acc20_token_id] == 0, "Asset already wrapped"); # [核心交互] 将底层 ACC-20 资产的所有权安全转移到本合约 # 此操作依赖于 ACC-20 标准接口的 `safe_transfer_from` let acc20 = IAcc20(acc20_contract); acc20.safe_transfer_from(msg.sender, self.address, acc20_token_id); # 分配新的包装资产 ID let wrapper_id = state.next_wrapper_token_id; state.next_wrapper_token_id += 1; # 创建并存储新的包装资产记录 let new_asset = WrappedAsset { acc20_deed_address: acc20_contract, acc20_deed_token_id: acc20_token_id, owner: msg.sender, status: WrappedStatus::ACTIVE, wrapped_at: block.timestamp, # 设置 24 小时解包冷却期 unlock_timestamp: block.timestamp + 86400, }; state.wrapped_assets[wrapper_id] = new_asset; # 记录双向映射关系 state.acc20_to_wrapper[acc20_contract][acc20_token_id] = wrapper_id; # 触发事件 emit AssetWrapped { wrapper_token_id: wrapper_id, acc20_contract: acc20_contract, acc20_token_id: acc20_token_id, owner: msg.sender, }; return wrapper_id; } # @dev 解包一个已包装的资产 # @param wrapper_token_id 要解包的资产 ID fn unwrap(wrapper_token_id: Uint256) { let asset = state.wrapped_assets[wrapper_token_id]; # 前置检查 require(asset.owner == msg.sender, "Caller is not the owner"); require(asset.status == WrappedStatus::ACTIVE, "Asset is not active"); require(block.timestamp >= asset.unlock_timestamp, "Unlock period has not passed"); # [核心交互] 将底层 ACC-20 资产归还给所有者 let acc20 = IAcc20(asset.acc20_deed_address); acc20.safe_transfer_from(self.address, msg.sender, asset.acc20_deed_token_id); # 清理存储 delete state.acc20_to_wrapper[asset.acc20_deed_address][asset.acc20_deed_token_id]; delete state.wrapped_assets[wrapper_token_id]; # 触发事件 emit AssetUnwrapped { wrapper_token_id: wrapper_token_id, owner: msg.sender, }; } # @dev 转移一个包装后资产的所有权 # @param to 接收方地址 # @param wrapper_token_id 被转移的资产 ID fn transfer(to: Address, wrapper_token_id: Uint256) { require(to != Address(0), "Transfer to zero address is not allowed"); let asset = state.wrapped_assets[wrapper_token_id]; # 前置检查 require(asset.owner == msg.sender, "Caller is not the owner"); require(asset.status == WrappedStatus::ACTIVE, "Asset is not active"); # 更新所有者 let from = asset.owner; state.wrapped_assets[wrapper_token_id].owner = to; # 触发事件 emit Transfer { from: from, to: to, wrapper_token_id: wrapper_token_id, }; } # --- 视图函数 --- # @dev 查询包装后资产的详情 fn get_wrapped_asset(wrapper_token_id: Uint256) -> WrappedAsset { return state.wrapped_assets[wrapper_token_id]; } # @dev 查询包装后资产的所有者 fn owner_of(wrapper_token_id: Uint256) -> Address { return state.wrapped_assets[wrapper_token_id].owner; } # @dev 查询原始 ACC-20 资产对应的包装 ID fn get_wrapper_id(acc20_contract: Address, acc20_token_id: Uint256) -> Uint256 { return state.acc20_to_wrapper[acc20_contract][acc20_token_id]; } # --- 管理员函数 --- # @dev 冻结指定的包装资产 fn freeze_asset(wrapper_token_id: Uint256) { require(msg.sender == state.admin, "Only admin can freeze"); state.wrapped_assets[wrapper_token_id].status = WrappedStatus::FROZEN; } # @dev 解冻指定的包装资产 fn unfreeze_asset(wrapper_token_id: Uint256) { require(msg.sender == state.admin, "Only admin can unfreeze"); state.wrapped_assets[wrapper_token_id].status = WrappedStatus::ACTIVE; }