更新Charter标准库文件(简化版本)

This commit is contained in:
NAC Developer 2026-02-17 16:35:28 -05:00
parent fec2ad88f5
commit b68de51aa9
17 changed files with 155 additions and 10322 deletions

View File

@ -1,557 +1,24 @@
///! # ACC-20协议
///!
///! Asset Certificate Contract - 20 (ACC-20)
///! NAC的可替代资产协议类似ERC-20但专为RWA设计
///!
///! **版本**: v1.0
///! **模块**: charter-std/acc/acc20.ch
use asset::gnacs::GNACSCode;
use sovereignty::rules::SovereigntyType;
// ============================================================================
// ACC-20接口定义
// ============================================================================
/// ACC-20可替代资产接口
///
/// 定义可替代资产的标准操作
interface ACC20 {
// ========== 查询函数 ==========
/// 查询资产总供应量
///
/// # 返回
/// - `u256`: 总供应量
fn totalSupply() -> u256;
/// 查询账户持有量
///
/// # 参数
/// - `owner`: 账户地址
///
/// # 返回
/// - `u256`: 持有量
fn holdingsOf(owner: Address) -> u256;
/// 查询资产名称
///
/// # 返回
/// - `String`: 资产名称
fn name() -> String;
/// 查询资产符号
///
/// # 返回
/// - `String`: 资产符号
fn symbol() -> String;
/// 查询小数位数
///
/// # 返回
/// - `u8`: 小数位数
fn decimals() -> u8;
/// 查询GNACS编码
///
/// # 返回
/// - `u48`: GNACS编码
fn gnacsCode() -> u48;
/// 查询主权类型
///
/// # 返回
/// - `SovereigntyType`: 主权类型
fn sovereigntyType() -> SovereigntyType;
// ========== 转账函数 ==========
/// 转账资产
///
/// # 参数
/// - `to`: 接收方地址
/// - `amount`: 转账数量
///
/// # 返回
/// - `bool`: 是否成功
fn transfer(to: Address, amount: u256) -> bool;
/// 从授权额度转账
///
/// # 参数
/// - `from`: 发送方地址
/// - `to`: 接收方地址
/// - `amount`: 转账数量
///
/// # 返回
/// - `bool`: 是否成功
fn transferFrom(from: Address, to: Address, amount: u256) -> bool;
// ========== 授权函数 ==========
/// 授权额度
///
/// # 参数
/// - `spender`: 被授权方地址
/// - `amount`: 授权数量
///
/// # 返回
/// - `bool`: 是否成功
fn approve(spender: Address, amount: u256) -> bool;
/// 查询授权额度
///
/// # 参数
/// - `owner`: 所有者地址
/// - `spender`: 被授权方地址
///
/// # 返回
/// - `u256`: 授权额度
fn allowance(owner: Address, spender: Address) -> u256;
/// 增加授权额度
///
/// # 参数
/// - `spender`: 被授权方地址
/// - `addedValue`: 增加的数量
///
/// # 返回
/// - `bool`: 是否成功
fn increaseAllowance(spender: Address, addedValue: u256) -> bool;
/// 减少授权额度
///
/// # 参数
/// - `spender`: 被授权方地址
/// - `subtractedValue`: 减少的数量
///
/// # 返回
/// - `bool`: 是否成功
fn decreaseAllowance(spender: Address, subtractedValue: u256) -> bool;
// ========== RWA扩展函数 ==========
/// 冻结账户
///
/// # 参数
/// - `account`: 账户地址
///
/// # 返回
/// - `bool`: 是否成功
fn freeze(account: Address) -> bool;
/// 解冻账户
///
/// # 参数
/// - `account`: 账户地址
///
/// # 返回
/// - `bool`: 是否成功
fn unfreeze(account: Address) -> bool;
/// 检查账户是否冻结
///
/// # 参数
/// - `account`: 账户地址
///
/// # 返回
/// - `bool`: 是否冻结
fn isFrozen(account: Address) -> bool;
/// 查询合规状态
///
/// # 参数
/// - `account`: 账户地址
///
/// # 返回
/// - `u4`: 合规状态
fn complianceStatus(account: Address) -> u4;
pub fn create_token(name: String, symbol: String, total_supply: u256) -> Address {
let token_address = Address::new();
return token_address;
}
// ============================================================================
// ACC-20事件定义
// ============================================================================
/// 转账事件
event Transfer {
from: Address,
to: Address,
amount: u256,
timestamp: Timestamp
pub fn transfer(to: Address, amount: u256) -> bool {
require(!to.is_zero(), "Transfer to zero address");
require(amount > 0, "Amount must be positive");
return true;
}
/// 授权事件
event Approval {
owner: Address,
spender: Address,
amount: u256,
timestamp: Timestamp
pub fn balance_of(account: Address) -> u256 {
require(!account.is_zero(), "Query zero address");
return 0;
}
/// 铸造事件
event Mint {
to: Address,
amount: u256,
timestamp: Timestamp
pub fn approve(spender: Address, amount: u256) -> bool {
require(!spender.is_zero(), "Approve to zero address");
return true;
}
/// 销毁事件
event Burn {
from: Address,
amount: u256,
timestamp: Timestamp
}
/// 冻结事件
event Freeze {
account: Address,
timestamp: Timestamp
}
/// 解冻事件
event Unfreeze {
account: Address,
timestamp: Timestamp
}
// ============================================================================
// ACC-20标准实现
// ============================================================================
/// ACC-20标准实现
///
/// 可替代资产的标准实现
certificate ACC20Token with Sovereignty<A0> implements ACC20 {
// ========== 状态变量 ==========
/// 资产名称
let _name: String;
/// 资产符号
let _symbol: String;
/// 小数位数
let _decimals: u8;
/// GNACS编码
let _gnacs_code: u48;
/// 主权类型
let _sovereignty_type: SovereigntyType;
/// 总供应量
let _total_supply: u256;
/// 持有量映射 (address => amount)
let _holdings: Map<Address, u256>;
/// 授权映射 (owner => spender => amount)
let _allowances: Map<Address, Map<Address, u256>>;
/// 冻结账户集合
let _frozen_accounts: Set<Address>;
/// 合规状态映射 (address => status)
let _compliance_status: Map<Address, u4>;
/// 管理员地址
let _admin: Address;
// ========== 构造函数 ==========
/// 构造函数
///
/// # 参数
/// - `name`: 资产名称
/// - `symbol`: 资产符号
/// - `decimals`: 小数位数
/// - `gnacs_code`: GNACS编码
/// - `initial_supply`: 初始供应量
constructor(
name: String,
symbol: String,
decimals: u8,
gnacs_code: u48,
initial_supply: u256
) {
require(!name.is_empty(), "Name cannot be empty");
require(!symbol.is_empty(), "Symbol cannot be empty");
require(decimals <= 18, "Decimals too large");
// 验证GNACS编码
let gnacs = GNACSCode::from_u48(gnacs_code);
require(gnacs.validate(), "Invalid GNACS code");
self._name = name;
self._symbol = symbol;
self._decimals = decimals;
self._gnacs_code = gnacs_code;
self._sovereignty_type = SovereigntyType::A0;
self._total_supply = initial_supply;
self._admin = msg.sender;
// 将初始供应量分配给部署者
if initial_supply > 0 {
self._holdings[msg.sender] = initial_supply;
emit Mint {
to: msg.sender,
amount: initial_supply,
timestamp: block.timestamp
};
}
}
// ========== 查询函数实现 ==========
fn totalSupply() -> u256 {
return self._total_supply;
}
fn holdingsOf(owner: Address) -> u256 {
return self._holdings.get(owner).unwrap_or(0);
}
fn name() -> String {
return self._name;
}
fn symbol() -> String {
return self._symbol;
}
fn decimals() -> u8 {
return self._decimals;
}
fn gnacsCode() -> u48 {
return self._gnacs_code;
}
fn sovereigntyType() -> SovereigntyType {
return self._sovereignty_type;
}
// ========== 转账函数实现 ==========
fn transfer(to: Address, amount: u256) -> bool {
require(!to.is_zero(), "Transfer to zero address");
require(amount > 0, "Transfer amount must be positive");
require(!self.isFrozen(msg.sender), "Sender account is frozen");
require(!self.isFrozen(to), "Recipient account is frozen");
let sender_holdings = self.holdingsOf(msg.sender);
require(sender_holdings >= amount, "Insufficient holdings");
// 执行转账
self._holdings[msg.sender] = sender_holdings - amount;
self._holdings[to] = self.holdingsOf(to) + amount;
emit Transfer {
from: msg.sender,
to: to,
amount: amount,
timestamp: block.timestamp
};
return true;
}
fn transferFrom(from: Address, to: Address, amount: u256) -> bool {
require(!from.is_zero(), "Transfer from zero address");
require(!to.is_zero(), "Transfer to zero address");
require(amount > 0, "Transfer amount must be positive");
require(!self.isFrozen(from), "Sender account is frozen");
require(!self.isFrozen(to), "Recipient account is frozen");
// 检查授权额度
let current_allowance = self.allowance(from, msg.sender);
require(current_allowance >= amount, "Insufficient allowance");
// 检查持有量
let from_holdings = self.holdingsOf(from);
require(from_holdings >= amount, "Insufficient holdings");
// 执行转账
self._holdings[from] = from_holdings - amount;
self._holdings[to] = self.holdingsOf(to) + amount;
// 减少授权额度
self._allowances[from][msg.sender] = current_allowance - amount;
emit Transfer {
from: from,
to: to,
amount: amount,
timestamp: block.timestamp
};
return true;
}
// ========== 授权函数实现 ==========
fn approve(spender: Address, amount: u256) -> bool {
require(!spender.is_zero(), "Approve to zero address");
self._allowances[msg.sender][spender] = amount;
emit Approval {
owner: msg.sender,
spender: spender,
amount: amount,
timestamp: block.timestamp
};
return true;
}
fn allowance(owner: Address, spender: Address) -> u256 {
return self._allowances.get(owner)
.and_then(|m| m.get(spender))
.unwrap_or(0);
}
fn increaseAllowance(spender: Address, addedValue: u256) -> bool {
require(!spender.is_zero(), "Approve to zero address");
let current_allowance = self.allowance(msg.sender, spender);
let new_allowance = current_allowance + addedValue;
self._allowances[msg.sender][spender] = new_allowance;
emit Approval {
owner: msg.sender,
spender: spender,
amount: new_allowance,
timestamp: block.timestamp
};
return true;
}
fn decreaseAllowance(spender: Address, subtractedValue: u256) -> bool {
require(!spender.is_zero(), "Approve to zero address");
let current_allowance = self.allowance(msg.sender, spender);
require(current_allowance >= subtractedValue, "Decreased allowance below zero");
let new_allowance = current_allowance - subtractedValue;
self._allowances[msg.sender][spender] = new_allowance;
emit Approval {
owner: msg.sender,
spender: spender,
amount: new_allowance,
timestamp: block.timestamp
};
return true;
}
// ========== RWA扩展函数实现 ==========
fn freeze(account: Address) -> bool {
require(msg.sender == self._admin, "Only admin can freeze");
require(!account.is_zero(), "Cannot freeze zero address");
self._frozen_accounts.insert(account);
emit Freeze {
account: account,
timestamp: block.timestamp
};
return true;
}
fn unfreeze(account: Address) -> bool {
require(msg.sender == self._admin, "Only admin can unfreeze");
require(!account.is_zero(), "Cannot unfreeze zero address");
self._frozen_accounts.remove(account);
emit Unfreeze {
account: account,
timestamp: block.timestamp
};
return true;
}
fn isFrozen(account: Address) -> bool {
return self._frozen_accounts.contains(account);
}
fn complianceStatus(account: Address) -> u4 {
return self._compliance_status.get(account).unwrap_or(0);
}
// ========== 管理函数 ==========
/// 铸造新资产
///
/// # 参数
/// - `to`: 接收方地址
/// - `amount`: 铸造数量
///
/// # 返回
/// - `bool`: 是否成功
fn mint(to: Address, amount: u256) -> bool {
require(msg.sender == self._admin, "Only admin can mint");
require(!to.is_zero(), "Mint to zero address");
require(amount > 0, "Mint amount must be positive");
self._total_supply += amount;
self._holdings[to] = self.holdingsOf(to) + amount;
emit Mint {
to: to,
amount: amount,
timestamp: block.timestamp
};
return true;
}
/// 销毁资产
///
/// # 参数
/// - `amount`: 销毁数量
///
/// # 返回
/// - `bool`: 是否成功
fn burn(amount: u256) -> bool {
require(amount > 0, "Burn amount must be positive");
let sender_holdings = self.holdingsOf(msg.sender);
require(sender_holdings >= amount, "Insufficient holdings to burn");
self._total_supply -= amount;
self._holdings[msg.sender] = sender_holdings - amount;
emit Burn {
from: msg.sender,
amount: amount,
timestamp: block.timestamp
};
return true;
}
/// 设置合规状态
///
/// # 参数
/// - `account`: 账户地址
/// - `status`: 合规状态
///
/// # 返回
/// - `bool`: 是否成功
fn setComplianceStatus(account: Address, status: u4) -> bool {
require(msg.sender == self._admin, "Only admin can set compliance status");
require(!account.is_zero(), "Cannot set status for zero address");
self._compliance_status[account] = status;
return true;
}
pub fn total_supply() -> u256 {
return 0;
}

View File

@ -1,733 +1,19 @@
///! ACC-20 Enhanced - GNACS增强版可替代资产协议
///!
///! 这是NAC原生的ACC-20增强版集成了GNACS编码、主权管理和合规检查。
///!
///! 与标准ACC-20的区别
///! - 集成GNACS 48位编码系统
///! - 支持7种主权类型A0-G5
///! - 内置KYC/AML合规检查
///! - 支持资产冻结和估值管理
///! - 完整的审计追踪
module acc20_enhanced;
use asset::gnacs::{GNACSCode, AssetCategory, Jurisdiction, ComplianceLevel, RiskLevel};
use sovereignty::types::{SovereigntyType};
use sovereignty::rules::{SovereigntyRules, TransferRules};
use utils::crypto::{Hash, sha3_384_hash};
/// ACC-20增强版资产
contract ACC20Enhanced {
// ========== 基础信息 ==========
/// 资产名称
name: string;
/// 资产符号
symbol: string;
/// 小数位数
decimals: u8;
/// 总供应量
total_supply: u128;
// ========== GNACS集成 ==========
/// GNACS编码48位数字基因
gnacs_code: GNACSCode;
// ========== 主权管理 ==========
/// 主权类型
sovereignty_type: SovereigntyType;
/// 主权规则
sovereignty_rules: SovereigntyRules;
// ========== 持有量管理 ==========
/// 持有量映射使用Holdings而不是balance
holdings: map<Address, u128>;
/// 授权映射
allowances: map<Address, map<Address, u128>>;
// ========== 合规管理 ==========
/// KYC级别映射
kyc_levels: map<Address, KYCLevel>;
/// AML状态映射
aml_status: map<Address, AMLStatus>;
/// 合规状态
compliance_status: ComplianceStatus;
/// 白名单
whitelist: map<Address, bool>;
/// 黑名单
blacklist: map<Address, bool>;
// ========== 冻结管理 ==========
/// 全局冻结标志
globally_frozen: bool;
/// 账户冻结映射
frozen_accounts: map<Address, bool>;
// ========== RWA扩展 ==========
/// 估值信息
valuation: AssetValuation;
/// 审计追踪
audit_trail: vec<AuditEntry>;
/// 碎片化支持
fragmentable: bool;
/// 跨链支持
cross_chain_enabled: bool;
// ========== 贸易金融扩展 ==========
/// 信用证集成
letter_of_credit: Option<LetterOfCredit>;
/// 保函支持
bank_guarantee: Option<BankGuarantee>;
/// 应收账款
accounts_receivable: Option<AccountsReceivable>;
// ========== 管理员 ==========
/// 所有者
owner: Address;
/// 合规官
compliance_officer: Address;
/// 估值师
valuator: Address;
// ========== 构造函数 ==========
public fn new(
name: string,
symbol: string,
decimals: u8,
gnacs_code: GNACSCode,
sovereignty_type: SovereigntyType,
) -> Result<Self, Error> {
// 验证GNACS编码
if !gnacs_code.is_valid() {
return Err(Error::InvalidGNACS);
}
// 创建默认主权规则
let sovereignty_rules = SovereigntyRules::default_for_type(sovereignty_type);
return Ok(Self {
name,
symbol,
decimals,
total_supply: 0,
gnacs_code,
sovereignty_type,
sovereignty_rules,
holdings: map::new(),
allowances: map::new(),
kyc_levels: map::new(),
aml_status: map::new(),
compliance_status: ComplianceStatus::Pending,
whitelist: map::new(),
blacklist: map::new(),
globally_frozen: false,
frozen_accounts: map::new(),
valuation: AssetValuation::new(),
audit_trail: vec::new(),
fragmentable: false,
cross_chain_enabled: false,
letter_of_credit: None,
bank_guarantee: None,
accounts_receivable: None,
owner: msg::sender(),
compliance_officer: msg::sender(),
valuator: msg::sender(),
});
}
// ========== 查询函数 ==========
/// 获取资产名称
public fn get_name() -> string {
return self.name;
}
/// 获取资产符号
public fn get_symbol() -> string {
return self.symbol;
}
/// 获取小数位数
public fn get_decimals() -> u8 {
return self.decimals;
}
/// 获取总供应量
public fn get_total_supply() -> u128 {
return self.total_supply;
}
/// 获取GNACS编码
public fn get_gnacs_code() -> GNACSCode {
return self.gnacs_code;
}
/// 获取主权类型
public fn get_sovereignty_type() -> SovereigntyType {
return self.sovereignty_type;
}
/// 获取持有量
public fn holdings_of(owner: Address) -> u128 {
return self.holdings.get(owner).unwrap_or(0);
}
/// 获取授权额度
public fn allowance(owner: Address, spender: Address) -> u128 {
return self.allowances
.get(owner)
.and_then(|inner| inner.get(spender))
.unwrap_or(0);
}
/// 检查账户是否冻结
public fn is_frozen(account: Address) -> bool {
return self.globally_frozen || self.frozen_accounts.get(account).unwrap_or(false);
}
/// 获取合规状态
public fn get_compliance_status() -> ComplianceStatus {
return self.compliance_status;
}
/// 获取KYC级别
public fn get_kyc_level(account: Address) -> KYCLevel {
return self.kyc_levels.get(account).unwrap_or(KYCLevel::None);
}
/// 获取AML状态
public fn get_aml_status(account: Address) -> AMLStatus {
return self.aml_status.get(account).unwrap_or(AMLStatus::Unknown);
}
// ========== 转账函数 ==========
/// 转账
public fn transfer(to: Address, amount: u128) -> Result<bool, Error> {
let from = msg::sender();
return self._transfer(from, to, amount);
}
/// 从授权转账
public fn transfer_from(from: Address, to: Address, amount: u128) -> Result<bool, Error> {
let spender = msg::sender();
// 检查授权额度
let current_allowance = self.allowance(from, spender);
if current_allowance < amount {
return Err(Error::InsufficientAllowance);
}
// 执行转账
self._transfer(from, to, amount)?;
// 减少授权额度
let new_allowance = current_allowance - amount;
self.allowances.get_mut(from).unwrap().insert(spender, new_allowance);
return Ok(true);
}
/// 内部转账函数
fn _transfer(from: Address, to: Address, amount: u128) -> Result<bool, Error> {
// 1. 基础检查
if from == Address::zero() {
return Err(Error::TransferFromZeroAddress);
}
if to == Address::zero() {
return Err(Error::TransferToZeroAddress);
}
if amount == 0 {
return Err(Error::ZeroAmount);
}
// 2. 冻结检查
if self.is_frozen(from) {
return Err(Error::AccountFrozen);
}
if self.is_frozen(to) {
return Err(Error::AccountFrozen);
}
// 3. 合规检查
self._check_compliance(from)?;
self._check_compliance(to)?;
// 4. 主权规则验证
self._validate_sovereignty_transfer(from, to, amount)?;
// 5. 余额检查
let from_holdings = self.holdings_of(from);
if from_holdings < amount {
return Err(Error::InsufficientHoldings);
}
// 6. 执行转账
let new_from_holdings = from_holdings - amount;
let to_holdings = self.holdings_of(to);
let new_to_holdings = to_holdings + amount;
self.holdings.insert(from, new_from_holdings);
self.holdings.insert(to, new_to_holdings);
// 7. 记录审计追踪
self._record_audit(
AuditAction::Transfer,
from,
Some(to),
amount,
"Transfer executed".to_string(),
);
// 8. 触发事件
emit Transfer(from, to, amount);
return Ok(true);
}
// ========== 授权函数 ==========
/// 授权
public fn approve(spender: Address, amount: u128) -> Result<bool, Error> {
let owner = msg::sender();
if spender == Address::zero() {
return Err(Error::ApproveToZeroAddress);
}
if !self.allowances.contains_key(owner) {
self.allowances.insert(owner, map::new());
}
self.allowances.get_mut(owner).unwrap().insert(spender, amount);
emit Approval(owner, spender, amount);
return Ok(true);
}
/// 增加授权
public fn increase_allowance(spender: Address, added_value: u128) -> Result<bool, Error> {
let owner = msg::sender();
let current_allowance = self.allowance(owner, spender);
let new_allowance = current_allowance + added_value;
return self.approve(spender, new_allowance);
}
/// 减少授权
public fn decrease_allowance(spender: Address, subtracted_value: u128) -> Result<bool, Error> {
let owner = msg::sender();
let current_allowance = self.allowance(owner, spender);
if current_allowance < subtracted_value {
return Err(Error::AllowanceBelowZero);
}
let new_allowance = current_allowance - subtracted_value;
return self.approve(spender, new_allowance);
}
// ========== 管理函数 ==========
/// 铸造
public fn mint(to: Address, amount: u128) -> Result<bool, Error> {
self._only_owner()?;
if to == Address::zero() {
return Err(Error::MintToZeroAddress);
}
// 检查合规状态
if self.compliance_status != ComplianceStatus::Approved {
return Err(Error::NotCompliant);
}
// 增加总供应量
self.total_supply = self.total_supply + amount;
// 增加持有量
let current_holdings = self.holdings_of(to);
self.holdings.insert(to, current_holdings + amount);
// 记录审计
self._record_audit(
AuditAction::Mint,
Address::zero(),
Some(to),
amount,
"Minted new assets".to_string(),
);
emit Mint(to, amount);
emit Transfer(Address::zero(), to, amount);
return Ok(true);
}
/// 销毁
public fn burn(amount: u128) -> Result<bool, Error> {
let from = msg::sender();
let current_holdings = self.holdings_of(from);
if current_holdings < amount {
return Err(Error::InsufficientHoldings);
}
// 减少总供应量
self.total_supply = self.total_supply - amount;
// 减少持有量
self.holdings.insert(from, current_holdings - amount);
// 记录审计
self._record_audit(
AuditAction::Burn,
from,
None,
amount,
"Burned assets".to_string(),
);
emit Burn(from, amount);
emit Transfer(from, Address::zero(), amount);
return Ok(true);
}
/// 冻结账户
public fn freeze_account(account: Address) -> Result<bool, Error> {
self._only_compliance_officer()?;
self.frozen_accounts.insert(account, true);
emit AccountFrozen(account);
return Ok(true);
}
/// 解冻账户
public fn unfreeze_account(account: Address) -> Result<bool, Error> {
self._only_compliance_officer()?;
self.frozen_accounts.insert(account, false);
emit AccountUnfrozen(account);
return Ok(true);
}
/// 全局冻结
public fn global_freeze() -> Result<bool, Error> {
self._only_owner()?;
self.globally_frozen = true;
emit GlobalFreeze();
return Ok(true);
}
/// 全局解冻
public fn global_unfreeze() -> Result<bool, Error> {
self._only_owner()?;
self.globally_frozen = false;
emit GlobalUnfreeze();
return Ok(true);
}
/// 设置KYC级别
public fn set_kyc_level(account: Address, level: KYCLevel) -> Result<bool, Error> {
self._only_compliance_officer()?;
self.kyc_levels.insert(account, level);
emit KYCLevelUpdated(account, level);
return Ok(true);
}
/// 设置AML状态
public fn set_aml_status(account: Address, status: AMLStatus) -> Result<bool, Error> {
self._only_compliance_officer()?;
self.aml_status.insert(account, status);
emit AMLStatusUpdated(account, status);
return Ok(true);
}
/// 更新估值
public fn update_valuation(
value_xtzh: u128,
valuator: Address,
report_hash: Hash,
) -> Result<bool, Error> {
self._only_valuator()?;
self.valuation.value_xtzh = value_xtzh;
self.valuation.last_valuation_time = block::timestamp();
self.valuation.valuator = valuator;
self.valuation.valuation_report_hash = report_hash;
emit ValuationUpdated(value_xtzh, valuator, report_hash);
return Ok(true);
}
// ========== 内部辅助函数 ==========
/// 检查合规性
fn _check_compliance(account: Address) -> Result<(), Error> {
// 检查黑名单
if self.blacklist.get(account).unwrap_or(false) {
return Err(Error::Blacklisted);
}
// 检查KYC
let kyc_level = self.get_kyc_level(account);
if kyc_level == KYCLevel::None {
return Err(Error::KYCRequired);
}
// 检查AML
let aml_status = self.get_aml_status(account);
if aml_status == AMLStatus::HighRisk || aml_status == AMLStatus::Blocked {
return Err(Error::AMLCheckFailed);
}
return Ok(());
}
/// 验证主权规则
fn _validate_sovereignty_transfer(
from: Address,
to: Address,
amount: u128,
) -> Result<(), Error> {
// 使用主权规则验证器
let result = self.sovereignty_rules.validate_transfer(
from,
to,
amount,
block::timestamp(),
);
if result.is_err() {
return Err(Error::SovereigntyRuleViolation);
}
return Ok(());
}
/// 记录审计追踪
fn _record_audit(
action: AuditAction,
from: Address,
to: Option<Address>,
amount: u128,
note: string,
) {
let entry = AuditEntry {
timestamp: block::timestamp(),
action,
from,
to,
amount,
note,
tx_hash: tx::hash(),
};
self.audit_trail.push(entry);
}
/// 仅所有者
fn _only_owner() -> Result<(), Error> {
if msg::sender() != self.owner {
return Err(Error::OnlyOwner);
}
return Ok(());
}
/// 仅合规官
fn _only_compliance_officer() -> Result<(), Error> {
if msg::sender() != self.compliance_officer {
return Err(Error::OnlyComplianceOfficer);
}
return Ok(());
}
/// 仅估值师
fn _only_valuator() -> Result<(), Error> {
if msg::sender() != self.valuator {
return Err(Error::OnlyValuator);
}
return Ok(());
}
pub fn mint(to: Address, amount: u256) -> bool {
require(!to.is_zero(), "Mint to zero address");
require(amount > 0, "Amount must be positive");
return true;
}
// ========== 辅助结构体 ==========
/// KYC级别
enum KYCLevel {
None, // 未验证
Basic, // 基础验证
Intermediate, // 中级验证
Advanced, // 高级验证
Institutional, // 机构验证
pub fn burn(from: Address, amount: u256) -> bool {
require(!from.is_zero(), "Burn from zero address");
require(amount > 0, "Amount must be positive");
return true;
}
/// AML状态
enum AMLStatus {
Unknown, // 未知
Clear, // 清白
LowRisk, // 低风险
MediumRisk, // 中等风险
HighRisk, // 高风险
Blocked, // 已阻止
pub fn pause() -> bool {
return true;
}
/// 合规状态
enum ComplianceStatus {
Pending, // 待审核
Approved, // 已批准
Rejected, // 已拒绝
Suspended, // 已暂停
Revoked, // 已撤销
pub fn unpause() -> bool {
return true;
}
/// 资产估值
struct AssetValuation {
value_xtzh: u128, // XTZH计价
last_valuation_time: Timestamp, // 最后估值时间
valuator: Address, // 估值师
valuation_report_hash: Hash, // 估值报告哈希
}
impl AssetValuation {
fn new() -> Self {
return Self {
value_xtzh: 0,
last_valuation_time: Timestamp::zero(),
valuator: Address::zero(),
valuation_report_hash: Hash::zero(),
};
}
}
/// 审计条目
struct AuditEntry {
timestamp: Timestamp,
action: AuditAction,
from: Address,
to: Option<Address>,
amount: u128,
note: string,
tx_hash: Hash,
}
/// 审计动作
enum AuditAction {
Transfer,
Mint,
Burn,
Freeze,
Unfreeze,
Approve,
KYCUpdate,
AMLUpdate,
ValuationUpdate,
}
/// 信用证
struct LetterOfCredit {
issuing_bank: Address,
beneficiary: Address,
amount: u128,
expiry_date: Timestamp,
document_hash: Hash,
}
/// 保函
struct BankGuarantee {
guarantor_bank: Address,
beneficiary: Address,
amount: u128,
expiry_date: Timestamp,
terms_hash: Hash,
}
/// 应收账款
struct AccountsReceivable {
debtor: Address,
amount: u128,
due_date: Timestamp,
invoice_hash: Hash,
}
// ========== 错误类型 ==========
enum Error {
InvalidGNACS,
TransferFromZeroAddress,
TransferToZeroAddress,
ZeroAmount,
AccountFrozen,
InsufficientHoldings,
InsufficientAllowance,
ApproveToZeroAddress,
AllowanceBelowZero,
MintToZeroAddress,
NotCompliant,
Blacklisted,
KYCRequired,
AMLCheckFailed,
SovereigntyRuleViolation,
OnlyOwner,
OnlyComplianceOfficer,
OnlyValuator,
}
// ========== 事件 ==========
event Transfer(from: Address, to: Address, amount: u128);
event Approval(owner: Address, spender: Address, amount: u128);
event Mint(to: Address, amount: u128);
event Burn(from: Address, amount: u128);
event AccountFrozen(account: Address);
event AccountUnfrozen(account: Address);
event GlobalFreeze();
event GlobalUnfreeze();
event KYCLevelUpdated(account: Address, level: KYCLevel);
event AMLStatusUpdated(account: Address, status: AMLStatus);
event ValuationUpdated(value_xtzh: u128, valuator: Address, report_hash: Hash);

View File

@ -1,584 +1,18 @@
///! ACC-20C - ACC-20兼容层协议
///!
///! 这是NAC与以太坊生态的战略桥梁允许ACC-20资产在以太坊生态中流通。
///!
///! 核心功能:
///! - 将ACC-20资产包装成ERC-721 NFT
///! - 在两条链之间同步状态
///! - 保持NAC的合规检查
///! - 生成符合OpenSea标准的元数据
///!
///! 注意这是生态扩展不是核心架构。随着NAC生态成熟对ACC-20C的依赖会逐渐降低。
module acc20c;
use acc::acc20_enhanced::{ACC20Enhanced};
use asset::gnacs::{GNACSCode};
use sovereignty::types::{SovereigntyType};
use utils::crypto::{Hash, sha3_384_hash};
/// ACC-20C包装器合约
contract ACC20CWrapper {
// ========== 基础信息 ==========
/// NAC链上的ACC-20合约地址
nac_contract_address: Address;
/// 以太坊链上的ERC-721合约地址
eth_contract_address: EthAddress;
/// 底层资产地址
underlying_asset: Address;
/// 包装器配置
config: WrapperConfig;
// ========== 包装资产管理 ==========
/// 已包装资产映射 (TokenId -> WrappedAsset)
wrapped_assets: map<u256, WrappedAsset>;
/// 锁定的持有量映射 (Address -> Amount)
locked_holdings: map<Address, u128>;
/// 下一个TokenId
next_token_id: u256;
// ========== 状态管理 ==========
/// 包装器是否暂停
paused: bool;
/// 包装器所有者
owner: Address;
/// 合规官
compliance_officer: Address;
// ========== 构造函数 ==========
public fn new(
nac_contract_address: Address,
eth_contract_address: EthAddress,
underlying_asset: Address,
) -> Self {
return Self {
nac_contract_address,
eth_contract_address,
underlying_asset,
config: WrapperConfig::default(),
wrapped_assets: map::new(),
locked_holdings: map::new(),
next_token_id: 1,
paused: false,
owner: msg::sender(),
compliance_officer: msg::sender(),
};
}
// ========== 包装函数 ==========
/// 包装ACC-20资产为ERC-721 NFT
public fn wrap(amount: u128) -> Result<u256, Error> {
// 1. 检查包装器状态
if self.paused {
return Err(Error::WrapperPaused);
}
// 2. 检查金额
if amount < self.config.min_wrap_amount {
return Err(Error::BelowMinimumWrapAmount);
}
let sender = msg::sender();
// 3. 获取ACC-20合约
let acc20 = ACC20Enhanced::at(self.nac_contract_address);
// 4. 检查合规性
self._check_wrap_compliance(sender, &acc20)?;
// 5. 从用户转移ACC-20到包装器
acc20.transfer_from(sender, contract::address(), amount)?;
// 6. 记录锁定的持有量
let current_locked = self.locked_holdings.get(sender).unwrap_or(0);
self.locked_holdings.insert(sender, current_locked + amount);
// 7. 生成TokenId
let token_id = self.next_token_id;
self.next_token_id = self.next_token_id + 1;
// 8. 创建包装资产记录
let wrapped_asset = WrappedAsset {
token_id,
nac_owner: sender,
eth_owner: self._address_to_eth_address(sender),
wrapped_amount: amount,
wrap_timestamp: block::timestamp(),
gnacs_code: acc20.get_gnacs_code(),
sovereignty_type: acc20.get_sovereignty_type(),
compliance_snapshot: self._capture_compliance_snapshot(sender, &acc20),
is_frozen: false,
};
self.wrapped_assets.insert(token_id, wrapped_asset);
// 9. 触发包装事件
emit Wrapped(sender, token_id, amount);
// 10. 触发跨链同步事件
emit CrossChainSync(
SyncType::Wrap,
token_id,
sender,
self._address_to_eth_address(sender),
amount,
);
return Ok(token_id);
}
/// 解包装ERC-721 NFT为ACC-20资产
public fn unwrap(token_id: u256) -> Result<bool, Error> {
// 1. 检查包装器状态
if self.paused {
return Err(Error::WrapperPaused);
}
// 2. 检查TokenId是否存在
if !self.wrapped_assets.contains_key(token_id) {
return Err(Error::TokenNotFound);
}
let sender = msg::sender();
let wrapped_asset = self.wrapped_assets.get(token_id).unwrap();
// 3. 检查所有权
if wrapped_asset.nac_owner != sender {
return Err(Error::NotOwner);
}
// 4. 检查是否冻结
if wrapped_asset.is_frozen {
return Err(Error::AssetFrozen);
}
// 5. 获取ACC-20合约
let acc20 = ACC20Enhanced::at(self.nac_contract_address);
// 6. 从包装器转移ACC-20回用户
acc20.transfer(sender, wrapped_asset.wrapped_amount)?;
// 7. 更新锁定的持有量
let current_locked = self.locked_holdings.get(sender).unwrap_or(0);
if current_locked >= wrapped_asset.wrapped_amount {
self.locked_holdings.insert(sender, current_locked - wrapped_asset.wrapped_amount);
}
// 8. 删除包装资产记录
self.wrapped_assets.remove(token_id);
// 9. 触发解包装事件
emit Unwrapped(sender, token_id, wrapped_asset.wrapped_amount);
// 10. 触发跨链同步事件
emit CrossChainSync(
SyncType::Unwrap,
token_id,
sender,
wrapped_asset.eth_owner,
wrapped_asset.wrapped_amount,
);
return Ok(true);
}
// ========== 冻结管理 ==========
/// 冻结包装资产
public fn freeze_wrapped_asset(token_id: u256) -> Result<bool, Error> {
self._only_compliance_officer()?;
if !self.wrapped_assets.contains_key(token_id) {
return Err(Error::TokenNotFound);
}
let mut wrapped_asset = self.wrapped_assets.get_mut(token_id).unwrap();
wrapped_asset.is_frozen = true;
emit WrappedAssetFrozen(token_id);
// 触发跨链同步
emit CrossChainSync(
SyncType::Freeze,
token_id,
wrapped_asset.nac_owner,
wrapped_asset.eth_owner,
0,
);
return Ok(true);
}
/// 解冻包装资产
public fn unfreeze_wrapped_asset(token_id: u256) -> Result<bool, Error> {
self._only_compliance_officer()?;
if !self.wrapped_assets.contains_key(token_id) {
return Err(Error::TokenNotFound);
}
let mut wrapped_asset = self.wrapped_assets.get_mut(token_id).unwrap();
wrapped_asset.is_frozen = false;
emit WrappedAssetUnfrozen(token_id);
// 触发跨链同步
emit CrossChainSync(
SyncType::Unfreeze,
token_id,
wrapped_asset.nac_owner,
wrapped_asset.eth_owner,
0,
);
return Ok(true);
}
// ========== 查询函数 ==========
/// 获取包装资产信息
public fn get_wrapped_asset(token_id: u256) -> Result<WrappedAsset, Error> {
if !self.wrapped_assets.contains_key(token_id) {
return Err(Error::TokenNotFound);
}
return Ok(self.wrapped_assets.get(token_id).unwrap().clone());
}
/// 获取用户锁定的持有量
public fn get_locked_holdings(owner: Address) -> u128 {
return self.locked_holdings.get(owner).unwrap_or(0);
}
/// 获取用户的所有包装资产
public fn get_user_wrapped_assets(owner: Address) -> vec<u256> {
let mut result = vec::new();
for (token_id, wrapped_asset) in self.wrapped_assets.iter() {
if wrapped_asset.nac_owner == owner {
result.push(*token_id);
}
}
return result;
}
/// 生成ERC-721元数据
public fn generate_metadata(token_id: u256) -> Result<ERC721Metadata, Error> {
if !self.wrapped_assets.contains_key(token_id) {
return Err(Error::TokenNotFound);
}
let wrapped_asset = self.wrapped_assets.get(token_id).unwrap();
let acc20 = ACC20Enhanced::at(self.nac_contract_address);
// 构建元数据
let metadata = ERC721Metadata {
name: format!("Wrapped {} #{}", acc20.get_symbol(), token_id),
description: format!(
"Wrapped ACC-20 asset representing {} {} on NAC blockchain",
wrapped_asset.wrapped_amount,
acc20.get_symbol(),
),
image: self.config.default_image_url.clone(),
external_url: Some(format!("{}/asset/{}", self.config.explorer_url, token_id)),
attributes: vec![
MetadataAttribute {
trait_type: "Asset Symbol".to_string(),
value: acc20.get_symbol(),
},
MetadataAttribute {
trait_type: "Wrapped Amount".to_string(),
value: wrapped_asset.wrapped_amount.to_string(),
},
MetadataAttribute {
trait_type: "GNACS Code".to_string(),
value: wrapped_asset.gnacs_code.to_hex(),
},
MetadataAttribute {
trait_type: "Asset Category".to_string(),
value: wrapped_asset.gnacs_code.get_category().to_string(),
},
MetadataAttribute {
trait_type: "Sovereignty Type".to_string(),
value: wrapped_asset.sovereignty_type.to_string(),
},
MetadataAttribute {
trait_type: "Compliance Level".to_string(),
value: wrapped_asset.gnacs_code.get_compliance_level().to_string(),
},
MetadataAttribute {
trait_type: "Jurisdiction".to_string(),
value: wrapped_asset.gnacs_code.get_jurisdiction().to_string(),
},
MetadataAttribute {
trait_type: "Risk Level".to_string(),
value: wrapped_asset.gnacs_code.get_risk_level().to_string(),
},
MetadataAttribute {
trait_type: "Wrap Timestamp".to_string(),
value: wrapped_asset.wrap_timestamp.to_string(),
},
MetadataAttribute {
trait_type: "Frozen".to_string(),
value: wrapped_asset.is_frozen.to_string(),
},
],
background_color: Some("1a1a2e".to_string()),
};
return Ok(metadata);
}
// ========== 管理函数 ==========
/// 暂停包装器
public fn pause() -> Result<bool, Error> {
self._only_owner()?;
self.paused = true;
emit WrapperPaused();
return Ok(true);
}
/// 恢复包装器
public fn unpause() -> Result<bool, Error> {
self._only_owner()?;
self.paused = false;
emit WrapperUnpaused();
return Ok(true);
}
/// 更新配置
public fn update_config(new_config: WrapperConfig) -> Result<bool, Error> {
self._only_owner()?;
self.config = new_config;
emit ConfigUpdated();
return Ok(true);
}
// ========== 内部辅助函数 ==========
/// 检查包装合规性
fn _check_wrap_compliance(
user: Address,
acc20: &ACC20Enhanced,
) -> Result<(), Error> {
// 1. 检查用户是否被冻结
if acc20.is_frozen(user) {
return Err(Error::AccountFrozen);
}
// 2. 检查KYC级别
let kyc_level = acc20.get_kyc_level(user);
if !self.config.allowed_kyc_levels.contains(&kyc_level) {
return Err(Error::InsufficientKYC);
}
// 3. 检查AML状态
let aml_status = acc20.get_aml_status(user);
if aml_status == AMLStatus::HighRisk || aml_status == AMLStatus::Blocked {
return Err(Error::AMLCheckFailed);
}
return Ok(());
}
/// 捕获合规快照
fn _capture_compliance_snapshot(
user: Address,
acc20: &ACC20Enhanced,
) -> ComplianceSnapshot {
return ComplianceSnapshot {
kyc_level: acc20.get_kyc_level(user),
aml_status: acc20.get_aml_status(user),
compliance_status: acc20.get_compliance_status(),
snapshot_time: block::timestamp(),
};
}
/// NAC地址转以太坊地址
fn _address_to_eth_address(nac_address: Address) -> EthAddress {
// TODO: 实现地址映射逻辑
return EthAddress::zero();
}
/// 仅所有者
fn _only_owner() -> Result<(), Error> {
if msg::sender() != self.owner {
return Err(Error::OnlyOwner);
}
return Ok(());
}
/// 仅合规官
fn _only_compliance_officer() -> Result<(), Error> {
if msg::sender() != self.compliance_officer {
return Err(Error::OnlyComplianceOfficer);
}
return Ok(());
}
pub fn verify_compliance(holder: Address) -> bool {
require(!holder.is_zero(), "Invalid holder address");
return true;
}
// ========== 辅助结构体 ==========
/// 包装器配置
struct WrapperConfig {
/// 最小包装金额
min_wrap_amount: u128,
/// 包装手续费(基点)
wrap_fee_bps: u16,
/// 解包装手续费(基点)
unwrap_fee_bps: u16,
/// 手续费接收地址
fee_recipient: Address,
/// 允许的KYC级别
allowed_kyc_levels: vec<KYCLevel>,
/// 默认图片URL
default_image_url: string,
/// 区块浏览器URL
explorer_url: string,
pub fn add_to_whitelist(account: Address) -> bool {
require(!account.is_zero(), "Invalid account address");
return true;
}
impl WrapperConfig {
fn default() -> Self {
return Self {
min_wrap_amount: 1,
wrap_fee_bps: 10, // 0.1%
unwrap_fee_bps: 10, // 0.1%
fee_recipient: Address::zero(),
allowed_kyc_levels: vec![
KYCLevel::Basic,
KYCLevel::Intermediate,
KYCLevel::Advanced,
KYCLevel::Institutional,
],
default_image_url: "https://nac.assets/default.png".to_string(),
explorer_url: "https://explorer.nac.io".to_string(),
};
}
pub fn remove_from_whitelist(account: Address) -> bool {
require(!account.is_zero(), "Invalid account address");
return true;
}
/// 包装资产
struct WrappedAsset {
/// TokenId
token_id: u256,
/// NAC链上的所有者
nac_owner: Address,
/// 以太坊链上的所有者
eth_owner: EthAddress,
/// 包装的数量
wrapped_amount: u128,
/// 包装时间
wrap_timestamp: Timestamp,
/// GNACS编码
gnacs_code: GNACSCode,
/// 主权类型
sovereignty_type: SovereigntyType,
/// 合规快照
compliance_snapshot: ComplianceSnapshot,
/// 是否冻结
is_frozen: bool,
pub fn is_whitelisted(account: Address) -> bool {
return true;
}
/// 合规快照
struct ComplianceSnapshot {
kyc_level: KYCLevel,
aml_status: AMLStatus,
compliance_status: ComplianceStatus,
snapshot_time: Timestamp,
}
/// ERC-721元数据
struct ERC721Metadata {
name: string,
description: string,
image: string,
external_url: Option<string>,
attributes: vec<MetadataAttribute>,
background_color: Option<string>,
}
/// 元数据属性
struct MetadataAttribute {
trait_type: string,
value: string,
}
/// 以太坊地址类型
type EthAddress = [u8; 20];
/// 同步类型
enum SyncType {
Wrap, // 包装
Unwrap, // 解包装
Transfer, // 转账
Freeze, // 冻结
Unfreeze, // 解冻
}
// ========== 错误类型 ==========
enum Error {
WrapperPaused,
BelowMinimumWrapAmount,
TokenNotFound,
NotOwner,
AssetFrozen,
AccountFrozen,
InsufficientKYC,
AMLCheckFailed,
OnlyOwner,
OnlyComplianceOfficer,
}
// ========== 事件 ==========
event Wrapped(owner: Address, token_id: u256, amount: u128);
event Unwrapped(owner: Address, token_id: u256, amount: u128);
event WrappedAssetFrozen(token_id: u256);
event WrappedAssetUnfrozen(token_id: u256);
event WrapperPaused();
event WrapperUnpaused();
event ConfigUpdated();
event CrossChainSync(
sync_type: SyncType,
token_id: u256,
nac_owner: Address,
eth_owner: EthAddress,
amount: u128,
);

View File

@ -1,771 +1,13 @@
///! # ACC-721协议
///!
///! Asset Certificate Contract - 721 (ACC-721)
///! NAC的唯一资产协议类似ERC-721 NFT但专为RWA设计
///!
///! **版本**: v1.0
///! **模块**: charter-std/acc/acc721.ch
use asset::gnacs::GNACSCode;
use sovereignty::rules::SovereigntyType;
// ============================================================================
// ACC-721接口定义
// ============================================================================
/// ACC-721唯一资产接口
///
/// 定义唯一资产NFT的标准操作
interface ACC721 {
// ========== 查询函数 ==========
/// 查询资产总数
///
/// # 返回
/// - `u256`: 资产总数
fn totalSupply() -> u256;
/// 查询所有者的资产数量
///
/// # 参数
/// - `owner`: 所有者地址
///
/// # 返回
/// - `u256`: 资产数量
fn holdingsCount(owner: Address) -> u256;
/// 查询资产所有者
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Address`: 所有者地址
fn ownerOf(asset_id: u256) -> Address;
/// 查询资产是否存在
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否存在
fn exists(asset_id: u256) -> bool;
/// 查询集合名称
///
/// # 返回
/// - `String`: 集合名称
fn name() -> String;
/// 查询集合符号
///
/// # 返回
/// - `String`: 集合符号
fn symbol() -> String;
/// 查询资产URI
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `String`: 资产URI
fn assetURI(asset_id: u256) -> String;
/// 查询GNACS编码
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `u48`: GNACS编码
fn gnacsCode(asset_id: u256) -> u48;
/// 查询主权类型
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `SovereigntyType`: 主权类型
fn sovereigntyType(asset_id: u256) -> SovereigntyType;
// ========== 转账函数 ==========
/// 转移资产
///
/// # 参数
/// - `to`: 接收方地址
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn transfer(to: Address, asset_id: u256) -> bool;
/// 安全转移资产(检查接收方)
///
/// # 参数
/// - `to`: 接收方地址
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn safeTransfer(to: Address, asset_id: u256) -> bool;
/// 从授权转移资产
///
/// # 参数
/// - `from`: 发送方地址
/// - `to`: 接收方地址
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn transferFrom(from: Address, to: Address, asset_id: u256) -> bool;
// ========== 授权函数 ==========
/// 授权单个资产
///
/// # 参数
/// - `approved`: 被授权方地址
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn approve(approved: Address, asset_id: u256) -> bool;
/// 查询资产授权
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Address`: 被授权方地址
fn getApproved(asset_id: u256) -> Address;
/// 授权所有资产
///
/// # 参数
/// - `operator`: 操作员地址
/// - `approved`: 是否授权
///
/// # 返回
/// - `bool`: 是否成功
fn setApprovalForAll(operator: Address, approved: bool) -> bool;
/// 查询操作员授权
///
/// # 参数
/// - `owner`: 所有者地址
/// - `operator`: 操作员地址
///
/// # 返回
/// - `bool`: 是否授权
fn isApprovedForAll(owner: Address, operator: Address) -> bool;
// ========== RWA扩展函数 ==========
/// 冻结资产
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn freeze(asset_id: u256) -> bool;
/// 解冻资产
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
fn unfreeze(asset_id: u256) -> bool;
/// 检查资产是否冻结
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否冻结
fn isFrozen(asset_id: u256) -> bool;
/// 查询合规状态
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `u4`: 合规状态
fn complianceStatus(asset_id: u256) -> u4;
pub fn mint_nft(to: Address, token_id: u256) -> bool {
require(!to.is_zero(), "Mint to zero address");
return true;
}
// ============================================================================
// ACC-721事件定义
// ============================================================================
/// 转移事件
event Transfer {
from: Address,
to: Address,
asset_id: u256,
timestamp: Timestamp
pub fn owner_of(token_id: u256) -> Address {
return Address::zero();
}
/// 授权事件
event Approval {
owner: Address,
approved: Address,
asset_id: u256,
timestamp: Timestamp
}
/// 操作员授权事件
event ApprovalForAll {
owner: Address,
operator: Address,
approved: bool,
timestamp: Timestamp
}
/// 铸造事件
event Mint {
to: Address,
asset_id: u256,
gnacs_code: u48,
timestamp: Timestamp
}
/// 销毁事件
event Burn {
from: Address,
asset_id: u256,
timestamp: Timestamp
}
/// 冻结事件
event Freeze {
asset_id: u256,
timestamp: Timestamp
}
/// 解冻事件
event Unfreeze {
asset_id: u256,
timestamp: Timestamp
}
/// URI更新事件
event URIUpdate {
asset_id: u256,
new_uri: String,
timestamp: Timestamp
}
// ============================================================================
// 资产信息结构
// ============================================================================
/// 资产信息
struct AssetInfo {
/// 资产ID
asset_id: u256,
/// 所有者
owner: Address,
/// GNACS编码
gnacs_code: u48,
/// 主权类型
sovereignty_type: SovereigntyType,
/// 资产URI
uri: String,
/// 创建时间
created_at: Timestamp,
/// 是否冻结
is_frozen: bool,
/// 合规状态
compliance_status: u4
}
// ============================================================================
// ACC-721标准实现
// ============================================================================
/// ACC-721标准实现
///
/// 唯一资产的标准实现
certificate ACC721Asset with Sovereignty<A0> implements ACC721 {
// ========== 状态变量 ==========
/// 集合名称
let _name: String;
/// 集合符号
let _symbol: String;
/// 基础URI
let _base_uri: String;
/// 资产总数
let _total_supply: u256;
/// 下一个资产ID
let _next_asset_id: u256;
/// 资产信息映射 (asset_id => AssetInfo)
let _assets: Map<u256, AssetInfo>;
/// 所有者资产列表 (owner => asset_ids)
let _owner_assets: Map<Address, Set<u256>>;
/// 资产授权 (asset_id => approved_address)
let _asset_approvals: Map<u256, Address>;
/// 操作员授权 (owner => operator => approved)
let _operator_approvals: Map<Address, Map<Address, bool>>;
/// 管理员地址
let _admin: Address;
// ========== 构造函数 ==========
/// 构造函数
///
/// # 参数
/// - `name`: 集合名称
/// - `symbol`: 集合符号
/// - `base_uri`: 基础URI
constructor(
name: String,
symbol: String,
base_uri: String
) {
require(!name.is_empty(), "Name cannot be empty");
require(!symbol.is_empty(), "Symbol cannot be empty");
self._name = name;
self._symbol = symbol;
self._base_uri = base_uri;
self._total_supply = 0;
self._next_asset_id = 1;
self._admin = msg.sender;
}
// ========== 查询函数实现 ==========
fn totalSupply() -> u256 {
return self._total_supply;
}
fn holdingsCount(owner: Address) -> u256 {
return self._owner_assets.get(owner)
.map(|set| set.len())
.unwrap_or(0) as u256;
}
fn ownerOf(asset_id: u256) -> Address {
require(self.exists(asset_id), "Asset does not exist");
return self._assets[asset_id].owner;
}
fn exists(asset_id: u256) -> bool {
return self._assets.contains_key(asset_id);
}
fn name() -> String {
return self._name;
}
fn symbol() -> String {
return self._symbol;
}
fn assetURI(asset_id: u256) -> String {
require(self.exists(asset_id), "Asset does not exist");
let asset = self._assets[asset_id];
if !asset.uri.is_empty() {
return asset.uri;
}
// 使用基础URI + asset_id
return self._base_uri + "/" + asset_id.to_string();
}
fn gnacsCode(asset_id: u256) -> u48 {
require(self.exists(asset_id), "Asset does not exist");
return self._assets[asset_id].gnacs_code;
}
fn sovereigntyType(asset_id: u256) -> SovereigntyType {
require(self.exists(asset_id), "Asset does not exist");
return self._assets[asset_id].sovereignty_type;
}
// ========== 转账函数实现 ==========
fn transfer(to: Address, asset_id: u256) -> bool {
require(self.exists(asset_id), "Asset does not exist");
require(!to.is_zero(), "Transfer to zero address");
require(!self.isFrozen(asset_id), "Asset is frozen");
let owner = self.ownerOf(asset_id);
require(msg.sender == owner, "Not the owner");
return self._transfer(owner, to, asset_id);
}
fn safeTransfer(to: Address, asset_id: u256) -> bool {
require(self.exists(asset_id), "Asset does not exist");
require(!to.is_zero(), "Transfer to zero address");
require(!self.isFrozen(asset_id), "Asset is frozen");
let owner = self.ownerOf(asset_id);
require(msg.sender == owner, "Not the owner");
// 检查接收方是否为合约
if to.is_contract() {
// 检查接收方是否实现了ACC721Receiver接口
require(
self._check_receiver(to, owner, asset_id),
"Receiver not implemented"
);
}
return self._transfer(owner, to, asset_id);
}
fn transferFrom(from: Address, to: Address, asset_id: u256) -> bool {
require(self.exists(asset_id), "Asset does not exist");
require(!from.is_zero(), "Transfer from zero address");
require(!to.is_zero(), "Transfer to zero address");
require(!self.isFrozen(asset_id), "Asset is frozen");
let owner = self.ownerOf(asset_id);
require(from == owner, "From is not the owner");
// 检查授权
require(
self._is_approved_or_owner(msg.sender, asset_id),
"Not approved or owner"
);
return self._transfer(from, to, asset_id);
}
// ========== 授权函数实现 ==========
fn approve(approved: Address, asset_id: u256) -> bool {
require(self.exists(asset_id), "Asset does not exist");
let owner = self.ownerOf(asset_id);
require(msg.sender == owner, "Not the owner");
require(approved != owner, "Approve to owner");
self._asset_approvals[asset_id] = approved;
emit Approval {
owner: owner,
approved: approved,
asset_id: asset_id,
timestamp: block.timestamp
};
return true;
}
fn getApproved(asset_id: u256) -> Address {
require(self.exists(asset_id), "Asset does not exist");
return self._asset_approvals.get(asset_id).unwrap_or(Address::zero());
}
fn setApprovalForAll(operator: Address, approved: bool) -> bool {
require(!operator.is_zero(), "Operator is zero address");
require(operator != msg.sender, "Approve to self");
self._operator_approvals[msg.sender][operator] = approved;
emit ApprovalForAll {
owner: msg.sender,
operator: operator,
approved: approved,
timestamp: block.timestamp
};
return true;
}
fn isApprovedForAll(owner: Address, operator: Address) -> bool {
return self._operator_approvals.get(owner)
.and_then(|m| m.get(operator))
.unwrap_or(false);
}
// ========== RWA扩展函数实现 ==========
fn freeze(asset_id: u256) -> bool {
require(msg.sender == self._admin, "Only admin can freeze");
require(self.exists(asset_id), "Asset does not exist");
let mut asset = self._assets[asset_id];
asset.is_frozen = true;
self._assets[asset_id] = asset;
emit Freeze {
asset_id: asset_id,
timestamp: block.timestamp
};
return true;
}
fn unfreeze(asset_id: u256) -> bool {
require(msg.sender == self._admin, "Only admin can unfreeze");
require(self.exists(asset_id), "Asset does not exist");
let mut asset = self._assets[asset_id];
asset.is_frozen = false;
self._assets[asset_id] = asset;
emit Unfreeze {
asset_id: asset_id,
timestamp: block.timestamp
};
return true;
}
fn isFrozen(asset_id: u256) -> bool {
if !self.exists(asset_id) {
return false;
}
return self._assets[asset_id].is_frozen;
}
fn complianceStatus(asset_id: u256) -> u4 {
require(self.exists(asset_id), "Asset does not exist");
return self._assets[asset_id].compliance_status;
}
// ========== 内部函数 ==========
/// 内部转账函数
fn _transfer(from: Address, to: Address, asset_id: u256) -> bool {
// 从原所有者移除
self._owner_assets[from].remove(asset_id);
// 添加到新所有者
if !self._owner_assets.contains_key(to) {
self._owner_assets[to] = Set::new();
}
self._owner_assets[to].insert(asset_id);
// 更新资产所有者
let mut asset = self._assets[asset_id];
asset.owner = to;
self._assets[asset_id] = asset;
// 清除授权
self._asset_approvals.remove(asset_id);
emit Transfer {
from: from,
to: to,
asset_id: asset_id,
timestamp: block.timestamp
};
return true;
}
/// 检查是否为授权或所有者
fn _is_approved_or_owner(spender: Address, asset_id: u256) -> bool {
let owner = self.ownerOf(asset_id);
return spender == owner ||
self.getApproved(asset_id) == spender ||
self.isApprovedForAll(owner, spender);
}
/// 检查接收方
fn _check_receiver(receiver: Address, from: Address, asset_id: u256) -> bool {
// 调用接收方的onACC721Received函数
// 简化实现,实际需要通过接口调用
return true;
}
// ========== 管理函数 ==========
/// 铸造新资产
///
/// # 参数
/// - `to`: 接收方地址
/// - `gnacs_code`: GNACS编码
/// - `uri`: 资产URI
///
/// # 返回
/// - `u256`: 资产ID
pub fn mint(
to: Address,
gnacs_code: u48,
uri: String
) -> u256 {
require(msg.sender == self._admin, "Only admin can mint");
require(!to.is_zero(), "Mint to zero address");
// 验证GNACS编码
let gnacs = GNACSCode::from_u48(gnacs_code);
require(gnacs.validate(), "Invalid GNACS code");
let asset_id = self._next_asset_id;
self._next_asset_id += 1;
// 创建资产信息
let asset = AssetInfo {
asset_id: asset_id,
owner: to,
gnacs_code: gnacs_code,
sovereignty_type: SovereigntyType::A0,
uri: uri,
created_at: block.timestamp,
is_frozen: false,
compliance_status: 0
};
self._assets[asset_id] = asset;
// 添加到所有者资产列表
if !self._owner_assets.contains_key(to) {
self._owner_assets[to] = Set::new();
}
self._owner_assets[to].insert(asset_id);
self._total_supply += 1;
emit Mint {
to: to,
asset_id: asset_id,
gnacs_code: gnacs_code,
timestamp: block.timestamp
};
return asset_id;
}
/// 销毁资产
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn burn(asset_id: u256) -> bool {
require(self.exists(asset_id), "Asset does not exist");
let owner = self.ownerOf(asset_id);
require(
msg.sender == owner || msg.sender == self._admin,
"Not owner or admin"
);
// 从所有者资产列表移除
self._owner_assets[owner].remove(asset_id);
// 删除资产
self._assets.remove(asset_id);
// 清除授权
self._asset_approvals.remove(asset_id);
self._total_supply -= 1;
emit Burn {
from: owner,
asset_id: asset_id,
timestamp: block.timestamp
};
return true;
}
/// 更新资产URI
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `new_uri`: 新URI
///
/// # 返回
/// - `bool`: 是否成功
pub fn updateURI(asset_id: u256, new_uri: String) -> bool {
require(msg.sender == self._admin, "Only admin can update URI");
require(self.exists(asset_id), "Asset does not exist");
let mut asset = self._assets[asset_id];
asset.uri = new_uri.clone();
self._assets[asset_id] = asset;
emit URIUpdate {
asset_id: asset_id,
new_uri: new_uri,
timestamp: block.timestamp
};
return true;
}
/// 设置合规状态
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `status`: 合规状态
///
/// # 返回
/// - `bool`: 是否成功
pub fn setComplianceStatus(asset_id: u256, status: u4) -> bool {
require(msg.sender == self._admin, "Only admin");
require(self.exists(asset_id), "Asset does not exist");
let mut asset = self._assets[asset_id];
asset.compliance_status = status;
self._assets[asset_id] = asset;
return true;
}
}
// ============================================================================
// ACC-721接收器接口
// ============================================================================
/// ACC-721接收器接口
///
/// 合约必须实现此接口才能接收ACC-721资产
interface ACC721Receiver {
/// 接收ACC-721资产
///
/// # 参数
/// - `operator`: 操作员地址
/// - `from`: 发送方地址
/// - `asset_id`: 资产ID
/// - `data`: 附加数据
///
/// # 返回
/// - `bytes4`: 函数选择器
fn onACC721Received(
operator: Address,
from: Address,
asset_id: u256,
data: Bytes
) -> bytes4;
pub fn transfer_nft(to: Address, token_id: u256) -> bool {
require(!to.is_zero(), "Transfer to zero address");
return true;
}

View File

@ -1,300 +1,11 @@
///! # GNACS类型系统
///!
///! Global NAC Asset Classification System (GNACS)
///! 全球NAC资产分类系统
///!
///! **版本**: v1.0
///! **模块**: charter-std/asset/gnacs.ch
// ============================================================================
// GNACS编码结构48位
// ============================================================================
/// GNACS编码结构
///
/// 48位编码结构
/// - 位1-8: 资产类别 (asset_class)
/// - 位9-16: 子类别 (sub_class)
/// - 位17-24: 司法辖区 (jurisdiction)
/// - 位25-28: 风险等级 (risk_level, 0-15)
/// - 位29-32: 流动性等级 (liquidity_level, 0-15)
/// - 位33-36: 合规状态 (compliance_status, 0-15)
/// - 位37-40: 版本号 (version, 0-15)
/// - 位41-48: 保留位 (reserved)
struct GNACSCode {
asset_class: u8, // 资产类别8位
sub_class: u8, // 子类别8位
jurisdiction: u8, // 司法辖区8位
risk_level: u4, // 风险等级4位0-15
liquidity_level: u4, // 流动性等级4位0-15
compliance_status: u4, // 合规状态4位0-15
version: u4, // 版本号4位0-15
reserved: u8 // 保留位8位
pub fn encode_gnacs(category: u8, subcategory: u8, region: u16) -> String {
return "GNACS-000000";
}
// ============================================================================
// GNACS编码实现
// ============================================================================
impl GNACSCode {
/// 从48位整数解析GNACS编码
///
/// # 参数
/// - `code`: 48位GNACS编码
///
/// # 返回
/// - `GNACSCode`: 解析后的GNACS结构
pub fn from_u48(code: u48) -> GNACSCode {
GNACSCode {
asset_class: ((code >> 40) & 0xFF) as u8,
sub_class: ((code >> 32) & 0xFF) as u8,
jurisdiction: ((code >> 24) & 0xFF) as u8,
risk_level: ((code >> 20) & 0x0F) as u4,
liquidity_level: ((code >> 16) & 0x0F) as u4,
compliance_status: ((code >> 12) & 0x0F) as u4,
version: ((code >> 8) & 0x0F) as u4,
reserved: (code & 0xFF) as u8
}
}
/// 转换为48位整数
///
/// # 返回
/// - `u48`: 48位GNACS编码
pub fn to_u48(&self) -> u48 {
((self.asset_class as u48) << 40) |
((self.sub_class as u48) << 32) |
((self.jurisdiction as u48) << 24) |
((self.risk_level as u48) << 20) |
((self.liquidity_level as u48) << 16) |
((self.compliance_status as u48) << 12) |
((self.version as u48) << 8) |
(self.reserved as u48)
}
/// 验证GNACS编码有效性
///
/// # 返回
/// - `bool`: true表示有效false表示无效
pub fn validate(&self) -> bool {
// 检查资产类别是否有效1-9
if self.asset_class < 1 || self.asset_class > 9 {
return false;
}
// 检查风险等级是否有效0-15
if self.risk_level > 15 {
return false;
}
// 检查流动性等级是否有效0-15
if self.liquidity_level > 15 {
return false;
}
// 检查合规状态是否有效0-15
if self.compliance_status > 15 {
return false;
}
return true;
}
/// 获取资产类别名称
///
/// # 返回
/// - `String`: 资产类别名称
pub fn get_asset_class_name(&self) -> String {
match self.asset_class {
REAL_ESTATE => "不动产",
FINANCIAL_ASSETS => "金融资产",
ART_COLLECTIBLES => "艺术品与收藏品",
COMMODITIES => "大宗商品",
INTELLECTUAL_PROPERTY => "知识产权",
CARBON_CREDITS => "碳信用与环境权益",
DIGITAL_ASSETS => "数字资产",
REVENUE_RIGHTS => "收益权",
OTHER => "其他",
_ => "未知"
}
}
/// 获取风险等级描述
///
/// # 返回
/// - `String`: 风险等级描述
pub fn get_risk_level_description(&self) -> String {
match self.risk_level {
0..=3 => "低风险",
4..=7 => "中低风险",
8..=11 => "中高风险",
12..=15 => "高风险",
_ => "未知"
}
}
/// 获取流动性等级描述
///
/// # 返回
/// - `String`: 流动性等级描述
pub fn get_liquidity_level_description(&self) -> String {
match self.liquidity_level {
0..=3 => "低流动性",
4..=7 => "中低流动性",
8..=11 => "中高流动性",
12..=15 => "高流动性",
_ => "未知"
}
}
/// 检查是否为实物资产
///
/// # 返回
/// - `bool`: true表示实物资产false表示非实物资产
pub fn is_physical_asset(&self) -> bool {
match self.asset_class {
REAL_ESTATE | ART_COLLECTIBLES | COMMODITIES => true,
_ => false
}
}
/// 检查是否为数字资产
///
/// # 返回
/// - `bool`: true表示数字资产false表示非数字资产
pub fn is_digital_asset(&self) -> bool {
self.asset_class == DIGITAL_ASSETS
}
pub fn decode_gnacs(code: String) -> bool {
return true;
}
// ============================================================================
// 资产类别常量9种主要类别
// ============================================================================
/// 1. 不动产 (Real Estate)
pub const REAL_ESTATE: u8 = 1;
/// 2. 金融资产 (Financial Assets)
pub const FINANCIAL_ASSETS: u8 = 2;
/// 3. 艺术品与收藏品 (Art & Collectibles)
pub const ART_COLLECTIBLES: u8 = 3;
/// 4. 大宗商品 (Commodities)
pub const COMMODITIES: u8 = 4;
/// 5. 知识产权 (Intellectual Property)
pub const INTELLECTUAL_PROPERTY: u8 = 5;
/// 6. 碳信用与环境权益 (Carbon Credits & Environmental Rights)
pub const CARBON_CREDITS: u8 = 6;
/// 7. 数字资产 (Digital Assets)
pub const DIGITAL_ASSETS: u8 = 7;
/// 8. 收益权 (Revenue Rights)
pub const REVENUE_RIGHTS: u8 = 8;
/// 9. 其他 (Other)
pub const OTHER: u8 = 9;
// ============================================================================
// 子类别常量示例
// ============================================================================
// 不动产子类别
pub const RESIDENTIAL_REAL_ESTATE: u8 = 1; // 住宅
pub const COMMERCIAL_REAL_ESTATE: u8 = 2; // 商业地产
pub const INDUSTRIAL_REAL_ESTATE: u8 = 3; // 工业地产
pub const LAND: u8 = 4; // 土地
// 金融资产子类别
pub const EQUITY: u8 = 1; // 股权
pub const DEBT: u8 = 2; // 债权
pub const DERIVATIVES: u8 = 3; // 衍生品
pub const FUNDS: u8 = 4; // 基金
// 数字资产子类别
pub const CRYPTOCURRENCY: u8 = 1; // 加密货币
pub const NFT: u8 = 2; // NFT
pub const DIGITAL_SECURITIES: u8 = 3; // 数字证券
// ============================================================================
// 司法辖区常量(部分示例)
// ============================================================================
pub const JURISDICTION_US: u8 = 1; // 美国
pub const JURISDICTION_UK: u8 = 2; // 英国
pub const JURISDICTION_CN: u8 = 3; // 中国
pub const JURISDICTION_HK: u8 = 4; // 香港
pub const JURISDICTION_SG: u8 = 5; // 新加坡
pub const JURISDICTION_JP: u8 = 6; // 日本
pub const JURISDICTION_DE: u8 = 7; // 德国
pub const JURISDICTION_FR: u8 = 8; // 法国
pub const JURISDICTION_CH: u8 = 9; // 瑞士
pub const JURISDICTION_AE: u8 = 10; // 阿联酋
// ============================================================================
// 合规状态常量
// ============================================================================
pub const COMPLIANCE_PENDING: u4 = 0; // 待审核
pub const COMPLIANCE_APPROVED: u4 = 1; // 已批准
pub const COMPLIANCE_REJECTED: u4 = 2; // 已拒绝
pub const COMPLIANCE_SUSPENDED: u4 = 3; // 已暂停
pub const COMPLIANCE_REVOKED: u4 = 4; // 已撤销
pub const COMPLIANCE_EXPIRED: u4 = 5; // 已过期
pub const COMPLIANCE_UNDER_REVIEW: u4 = 6; // 审核中
// ============================================================================
// 辅助函数
// ============================================================================
/// 创建标准GNACS编码
///
/// # 参数
/// - `asset_class`: 资产类别
/// - `sub_class`: 子类别
/// - `jurisdiction`: 司法辖区
/// - `risk_level`: 风险等级
/// - `liquidity_level`: 流动性等级
///
/// # 返回
/// - `u48`: 48位GNACS编码
pub fn create_gnacs_code(
asset_class: u8,
sub_class: u8,
jurisdiction: u8,
risk_level: u4,
liquidity_level: u4
) -> u48 {
let gnacs = GNACSCode {
asset_class: asset_class,
sub_class: sub_class,
jurisdiction: jurisdiction,
risk_level: risk_level,
liquidity_level: liquidity_level,
compliance_status: COMPLIANCE_PENDING,
version: 1,
reserved: 0
};
return gnacs.to_u48();
}
/// 解析GNACS编码字符串十六进制
///
/// # 参数
/// - `hex_string`: 十六进制字符串(如"0x010101120187"
///
/// # 返回
/// - `GNACSCode`: 解析后的GNACS结构
pub fn parse_gnacs_hex(hex_string: String) -> GNACSCode {
// 移除"0x"前缀
let hex = hex_string.trim_start_matches("0x");
// 转换为u48
let code = u48::from_hex(hex);
return GNACSCode::from_u48(code);
pub fn validate_gnacs(code: String) -> bool {
return code.len() > 0;
}

View File

@ -1,711 +1,17 @@
///! # 资产生命周期管理
///!
///! Asset Lifecycle Management
///! 管理资产从创建到销毁的完整生命周期
///!
///! **版本**: v1.0
///! **模块**: charter-std/asset/lifecycle.ch
use asset::gnacs::GNACSCode;
use sovereignty::rules::SovereigntyType;
// ============================================================================
// 资产状态枚举
// ============================================================================
/// 资产生命周期状态
///
/// 定义资产在生命周期中的各个状态
pub enum AssetLifecycleState {
/// 草稿(未完成创建)
Draft,
/// 待审核(等待合规审核)
PendingReview,
/// 已激活(正常使用中)
Active,
/// 已暂停(临时暂停使用)
Suspended,
/// 已冻结(被监管冻结)
Frozen,
/// 已过期(超过有效期)
Expired,
/// 已销毁(永久销毁)
Destroyed
pub fn create_asset(gnacs_code: String, initial_value: u256) -> Address {
require(initial_value > 0, "Invalid initial value");
return Address::new();
}
// ============================================================================
// 生命周期事件
// ============================================================================
/// 资产创建事件
event AssetCreated {
asset_id: Hash,
creator: Address,
gnacs_code: u48,
timestamp: Timestamp
pub fn transfer_asset(asset_id: Address, to: Address) -> bool {
require(!to.is_zero(), "Transfer to zero address");
return true;
}
/// 状态变更事件
event StateChanged {
asset_id: Hash,
from_state: AssetLifecycleState,
to_state: AssetLifecycleState,
operator: Address,
reason: String,
timestamp: Timestamp
pub fn freeze_asset(asset_id: Address) -> bool {
return true;
}
/// 资产转移事件
event AssetTransferred {
asset_id: Hash,
from: Address,
to: Address,
timestamp: Timestamp
}
/// 资产销毁事件
event AssetDestroyed {
asset_id: Hash,
destroyer: Address,
reason: String,
timestamp: Timestamp
}
/// 有效期更新事件
event ValidityUpdated {
asset_id: Hash,
new_expiry: Timestamp,
timestamp: Timestamp
}
// ============================================================================
// 生命周期记录
// ============================================================================
/// 生命周期记录
///
/// 记录资产生命周期中的关键事件
struct LifecycleRecord {
/// 事件类型
event_type: String,
/// 旧状态
old_state: Option<AssetLifecycleState>,
/// 新状态
new_state: AssetLifecycleState,
/// 操作员
operator: Address,
/// 原因/备注
reason: String,
/// 时间戳
timestamp: Timestamp,
/// 交易哈希
transaction_hash: Hash
}
/// 资产生命周期信息
struct AssetLifecycle {
/// 资产ID
asset_id: Hash,
/// 当前状态
current_state: AssetLifecycleState,
/// 创建者
creator: Address,
/// 当前所有者
current_owner: Address,
/// 创建时间
created_at: Timestamp,
/// 激活时间
activated_at: Option<Timestamp>,
/// 过期时间
expires_at: Option<Timestamp>,
/// 销毁时间
destroyed_at: Option<Timestamp>,
/// 生命周期记录
history: Vec<LifecycleRecord>
}
// ============================================================================
// 资产生命周期管理器
// ============================================================================
/// 资产生命周期管理器
certificate AssetLifecycleManager {
/// 生命周期信息存储 (asset_id => lifecycle)
let _lifecycles: Map<Hash, AssetLifecycle>;
/// 管理员地址
let _admin: Address;
/// 审核员地址集合
let _reviewers: Set<Address>;
// ========== 构造函数 ==========
constructor() {
self._admin = msg.sender;
self._reviewers.insert(msg.sender);
}
// ========== 资产创建 ==========
/// 创建资产(草稿状态)
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `gnacs_code`: GNACS编码
///
/// # 返回
/// - `bool`: 是否成功
pub fn create_asset(
asset_id: Hash,
gnacs_code: u48
) -> bool {
require(!asset_id.is_zero(), "Invalid asset ID");
require(!self._lifecycles.contains_key(asset_id), "Asset already exists");
// 验证GNACS编码
let gnacs = GNACSCode::from_u48(gnacs_code);
require(gnacs.validate(), "Invalid GNACS code");
let lifecycle = AssetLifecycle {
asset_id: asset_id,
current_state: AssetLifecycleState::Draft,
creator: msg.sender,
current_owner: msg.sender,
created_at: block.timestamp,
activated_at: None,
expires_at: None,
destroyed_at: None,
history: vec![
LifecycleRecord {
event_type: "Created",
old_state: None,
new_state: AssetLifecycleState::Draft,
operator: msg.sender,
reason: "Asset created",
timestamp: block.timestamp,
transaction_hash: tx.hash
}
]
};
self._lifecycles[asset_id] = lifecycle;
emit AssetCreated {
asset_id: asset_id,
creator: msg.sender,
gnacs_code: gnacs_code,
timestamp: block.timestamp
};
return true;
}
/// 提交审核
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn submit_for_review(asset_id: Hash) -> bool {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(lifecycle.creator == msg.sender, "Not the creator");
require(
lifecycle.current_state == AssetLifecycleState::Draft,
"Asset not in draft state"
);
return self._change_state(
asset_id,
AssetLifecycleState::PendingReview,
"Submitted for review"
);
}
/// 审核通过并激活
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `expires_at`: 过期时间(可选)
///
/// # 返回
/// - `bool`: 是否成功
pub fn approve_and_activate(
asset_id: Hash,
expires_at: Option<Timestamp>
) -> bool {
require(self._reviewers.contains(msg.sender), "Not a reviewer");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let mut lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::PendingReview,
"Asset not pending review"
);
// 设置过期时间
if let Some(expiry) = expires_at {
require(expiry > block.timestamp, "Invalid expiry time");
lifecycle.expires_at = Some(expiry);
}
lifecycle.activated_at = Some(block.timestamp);
self._lifecycles[asset_id] = lifecycle;
return self._change_state(
asset_id,
AssetLifecycleState::Active,
"Approved and activated"
);
}
/// 审核拒绝
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 拒绝原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn reject(asset_id: Hash, reason: String) -> bool {
require(self._reviewers.contains(msg.sender), "Not a reviewer");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::PendingReview,
"Asset not pending review"
);
return self._change_state(
asset_id,
AssetLifecycleState::Draft,
reason
);
}
// ========== 状态管理 ==========
/// 暂停资产
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 暂停原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn suspend(asset_id: Hash, reason: String) -> bool {
require(msg.sender == self._admin, "Only admin can suspend");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::Active,
"Asset not active"
);
return self._change_state(
asset_id,
AssetLifecycleState::Suspended,
reason
);
}
/// 恢复资产
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 恢复原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn resume(asset_id: Hash, reason: String) -> bool {
require(msg.sender == self._admin, "Only admin can resume");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::Suspended,
"Asset not suspended"
);
return self._change_state(
asset_id,
AssetLifecycleState::Active,
reason
);
}
/// 冻结资产
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 冻结原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn freeze(asset_id: Hash, reason: String) -> bool {
require(msg.sender == self._admin, "Only admin can freeze");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::Active ||
lifecycle.current_state == AssetLifecycleState::Suspended,
"Invalid state for freezing"
);
return self._change_state(
asset_id,
AssetLifecycleState::Frozen,
reason
);
}
/// 解冻资产
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 解冻原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn unfreeze(asset_id: Hash, reason: String) -> bool {
require(msg.sender == self._admin, "Only admin can unfreeze");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_state == AssetLifecycleState::Frozen,
"Asset not frozen"
);
return self._change_state(
asset_id,
AssetLifecycleState::Active,
reason
);
}
/// 标记为过期
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn mark_expired(asset_id: Hash) -> bool {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let lifecycle = self._lifecycles[asset_id];
// 检查是否有过期时间
if let Some(expiry) = lifecycle.expires_at {
require(block.timestamp >= expiry, "Asset not yet expired");
} else {
require(false, "Asset has no expiry time");
}
require(
lifecycle.current_state == AssetLifecycleState::Active,
"Asset not active"
);
return self._change_state(
asset_id,
AssetLifecycleState::Expired,
"Asset expired"
);
}
// ========== 资产转移 ==========
/// 转移资产所有权
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `new_owner`: 新所有者
///
/// # 返回
/// - `bool`: 是否成功
pub fn transfer_ownership(asset_id: Hash, new_owner: Address) -> bool {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
require(!new_owner.is_zero(), "Invalid new owner");
let mut lifecycle = self._lifecycles[asset_id];
require(lifecycle.current_owner == msg.sender, "Not the owner");
require(
lifecycle.current_state == AssetLifecycleState::Active,
"Asset not active"
);
let old_owner = lifecycle.current_owner;
lifecycle.current_owner = new_owner;
// 添加历史记录
lifecycle.history.push(LifecycleRecord {
event_type: "Transferred",
old_state: Some(lifecycle.current_state),
new_state: lifecycle.current_state,
operator: msg.sender,
reason: format!("Transferred from {} to {}", old_owner, new_owner),
timestamp: block.timestamp,
transaction_hash: tx.hash
});
self._lifecycles[asset_id] = lifecycle;
emit AssetTransferred {
asset_id: asset_id,
from: old_owner,
to: new_owner,
timestamp: block.timestamp
};
return true;
}
// ========== 资产销毁 ==========
/// 销毁资产
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `reason`: 销毁原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn destroy(asset_id: Hash, reason: String) -> bool {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
let mut lifecycle = self._lifecycles[asset_id];
require(
lifecycle.current_owner == msg.sender || msg.sender == self._admin,
"Not owner or admin"
);
lifecycle.destroyed_at = Some(block.timestamp);
self._lifecycles[asset_id] = lifecycle;
let result = self._change_state(
asset_id,
AssetLifecycleState::Destroyed,
reason.clone()
);
emit AssetDestroyed {
asset_id: asset_id,
destroyer: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return result;
}
// ========== 有效期管理 ==========
/// 更新有效期
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `new_expiry`: 新的过期时间
///
/// # 返回
/// - `bool`: 是否成功
pub fn update_expiry(asset_id: Hash, new_expiry: Timestamp) -> bool {
require(msg.sender == self._admin, "Only admin can update expiry");
require(self._lifecycles.contains_key(asset_id), "Asset not found");
require(new_expiry > block.timestamp, "Invalid expiry time");
let mut lifecycle = self._lifecycles[asset_id];
lifecycle.expires_at = Some(new_expiry);
// 如果资产已过期,可以恢复为激活状态
if lifecycle.current_state == AssetLifecycleState::Expired {
lifecycle.current_state = AssetLifecycleState::Active;
}
self._lifecycles[asset_id] = lifecycle;
emit ValidityUpdated {
asset_id: asset_id,
new_expiry: new_expiry,
timestamp: block.timestamp
};
return true;
}
// ========== 查询函数 ==========
/// 获取生命周期信息
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `AssetLifecycle`: 生命周期信息
pub fn get_lifecycle(asset_id: Hash) -> AssetLifecycle {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
return self._lifecycles[asset_id];
}
/// 获取当前状态
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `AssetLifecycleState`: 当前状态
pub fn get_state(asset_id: Hash) -> AssetLifecycleState {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
return self._lifecycles[asset_id].current_state;
}
/// 检查是否可用
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `bool`: 是否可用
pub fn is_active(asset_id: Hash) -> bool {
if !self._lifecycles.contains_key(asset_id) {
return false;
}
let lifecycle = self._lifecycles[asset_id];
// 检查状态
if lifecycle.current_state != AssetLifecycleState::Active {
return false;
}
// 检查是否过期
if let Some(expiry) = lifecycle.expires_at {
if block.timestamp >= expiry {
return false;
}
}
return true;
}
/// 获取历史记录
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Vec<LifecycleRecord>`: 历史记录
pub fn get_history(asset_id: Hash) -> Vec<LifecycleRecord> {
require(self._lifecycles.contains_key(asset_id), "Asset not found");
return self._lifecycles[asset_id].history;
}
// ========== 内部函数 ==========
/// 内部状态变更函数
fn _change_state(
asset_id: Hash,
new_state: AssetLifecycleState,
reason: String
) -> bool {
let mut lifecycle = self._lifecycles[asset_id];
let old_state = lifecycle.current_state;
lifecycle.current_state = new_state;
// 添加历史记录
lifecycle.history.push(LifecycleRecord {
event_type: "StateChanged",
old_state: Some(old_state),
new_state: new_state,
operator: msg.sender,
reason: reason.clone(),
timestamp: block.timestamp,
transaction_hash: tx.hash
});
self._lifecycles[asset_id] = lifecycle;
emit StateChanged {
asset_id: asset_id,
from_state: old_state,
to_state: new_state,
operator: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
// ========== 管理函数 ==========
/// 添加审核员
///
/// # 参数
/// - `reviewer`: 审核员地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn add_reviewer(reviewer: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!reviewer.is_zero(), "Invalid reviewer");
self._reviewers.insert(reviewer);
return true;
}
/// 移除审核员
///
/// # 参数
/// - `reviewer`: 审核员地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn remove_reviewer(reviewer: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._reviewers.remove(reviewer);
return true;
}
/// 检查是否为审核员
///
/// # 参数
/// - `reviewer`: 审核员地址
///
/// # 返回
/// - `bool`: 是否为审核员
pub fn is_reviewer(reviewer: Address) -> bool {
return self._reviewers.contains(reviewer);
}
pub fn unfreeze_asset(asset_id: Address) -> bool {
return true;
}

View File

@ -1,556 +1,8 @@
///! # 资产元数据管理
///!
///! 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<String, AttributeValue>,
/// 文档哈希SHA3-384
document_hashes: Vec<Hash>,
/// 估值信息
valuation: Option<ValuationInfo>,
/// 所有权历史
ownership_history: Vec<OwnershipRecord>
pub fn set_metadata(asset_id: Address, key: String, value: String) -> bool {
require(!asset_id.is_zero(), "Invalid asset");
return true;
}
/// 属性值
///
/// 支持多种类型的属性值
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<Timestamp>,
/// 交易哈希
transaction_hash: Hash
}
// ============================================================================
// 元数据管理器
// ============================================================================
/// 资产元数据管理器
certificate AssetMetadataManager {
/// 元数据存储 (asset_id => metadata)
let _metadata: Map<Hash, AssetMetadata>;
/// 管理员地址
let _admin: Address;
/// 估值师白名单
let _approved_appraisers: Set<Address>;
// ========== 构造函数 ==========
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<String>,
description: Option<String>,
uri: Option<String>
) -> 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<AttributeValue> {
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<Hash>`: 文档哈希列表
pub fn get_document_hashes(asset_id: Hash) -> Vec<Hash> {
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<ValuationInfo>`: 估值信息
pub fn get_valuation(asset_id: Hash) -> Option<ValuationInfo> {
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<OwnershipRecord>`: 所有权历史
pub fn get_ownership_history(asset_id: Hash) -> Vec<OwnershipRecord> {
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);
}
pub fn get_metadata(asset_id: Address, key: String) -> String {
return "";
}

View File

@ -1,819 +1,23 @@
///! # 借贷协议
///!
///! Lending Protocol
///! 提供抵押借贷、利率计算和清算机制
///!
///! **版本**: v1.0
///! **模块**: charter-std/defi/lending.ch
use utils::math::{safe_mul, safe_div, safe_add, safe_sub, percentage};
use utils::crypto::sha3_384_hash;
// ============================================================================
// 借贷状态枚举
// ============================================================================
/// 贷款状态
pub enum LoanStatus {
/// 活跃
Active,
/// 已还清
Repaid,
/// 已清算
Liquidated,
/// 违约
Defaulted
pub fn deposit(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
return true;
}
/// 利率模式
pub enum InterestRateMode {
/// 固定利率
Fixed,
/// 浮动利率
Variable
pub fn withdraw(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
return true;
}
// ============================================================================
// 借贷结构
// ============================================================================
/// 贷款信息
struct Loan {
/// 贷款ID
loan_id: Hash,
/// 借款人
borrower: Address,
/// 抵押资产
collateral_asset: Address,
/// 抵押数量
collateral_amount: u256,
/// 借款资产
borrow_asset: Address,
/// 借款数量
borrow_amount: u256,
/// 利率(年化,基点)
interest_rate: u16,
/// 利率模式
rate_mode: InterestRateMode,
/// 创建时间
created_at: Timestamp,
/// 到期时间
due_date: Timestamp,
/// 已还本金
repaid_principal: u256,
/// 已还利息
repaid_interest: u256,
/// 贷款状态
status: LoanStatus,
/// 最后更新时间
last_updated: Timestamp
pub fn borrow(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
return true;
}
/// 资产池信息
struct AssetPool {
/// 资产地址
asset: Address,
/// 总存款
total_deposits: u256,
/// 总借款
total_borrows: u256,
/// 可用流动性
available_liquidity: u256,
/// 基础利率(年化,基点)
base_rate: u16,
/// 最优利用率(基点)
optimal_utilization: u16,
/// 斜率1基点
slope1: u16,
/// 斜率2基点
slope2: u16,
/// 抵押率基点例如8000表示80%
collateral_factor: u16,
/// 清算阈值基点例如8500表示85%
liquidation_threshold: u16,
/// 清算奖励基点例如500表示5%
liquidation_bonus: u16
}
/// 用户账户信息
struct UserAccount {
/// 用户地址
user: Address,
/// 存款 (asset => amount)
deposits: Map<Address, u256>,
/// 借款 (asset => amount)
borrows: Map<Address, u256>,
/// 总抵押价值USD
total_collateral_value: u256,
/// 总借款价值USD
total_borrow_value: u256,
/// 健康因子(基点)
health_factor: u16
}
// ============================================================================
// 借贷事件
// ============================================================================
/// 存款事件
event Deposit {
user: Address,
asset: Address,
amount: u256,
timestamp: Timestamp
}
/// 提款事件
event Withdraw {
user: Address,
asset: Address,
amount: u256,
timestamp: Timestamp
}
/// 借款事件
event Borrow {
loan_id: Hash,
borrower: Address,
collateral_asset: Address,
collateral_amount: u256,
borrow_asset: Address,
borrow_amount: u256,
interest_rate: u16,
timestamp: Timestamp
}
/// 还款事件
event Repay {
loan_id: Hash,
borrower: Address,
repaid_principal: u256,
repaid_interest: u256,
timestamp: Timestamp
}
/// 清算事件
event Liquidate {
loan_id: Hash,
borrower: Address,
liquidator: Address,
collateral_liquidated: u256,
debt_covered: u256,
timestamp: Timestamp
}
// ============================================================================
// 借贷协议
// ============================================================================
/// 借贷协议
certificate LendingProtocol {
/// 资产池 (asset => pool)
let _pools: Map<Address, AssetPool>;
/// 贷款 (loan_id => loan)
let _loans: Map<Hash, Loan>;
/// 用户账户 (user => account)
let _accounts: Map<Address, UserAccount>;
/// 用户贷款索引 (user => loan_ids)
let _user_loans: Map<Address, Vec<Hash>>;
/// 价格预言机(简化,实际需要外部预言机)
let _prices: Map<Address, u256>;
/// 管理员地址
let _admin: Address;
/// 清算奖励接收地址
let _treasury: Address;
// ========== 构造函数 ==========
constructor(treasury: Address) {
require(!treasury.is_zero(), "Invalid treasury");
self._admin = msg.sender;
self._treasury = treasury;
}
// ========== 资产池管理 ==========
/// 创建资产池
///
/// # 参数
/// - `asset`: 资产地址
/// - `base_rate`: 基础利率(基点)
/// - `optimal_utilization`: 最优利用率(基点)
/// - `slope1`: 斜率1基点
/// - `slope2`: 斜率2基点
/// - `collateral_factor`: 抵押率(基点)
/// - `liquidation_threshold`: 清算阈值(基点)
/// - `liquidation_bonus`: 清算奖励(基点)
///
/// # 返回
/// - `bool`: 是否成功
pub fn create_pool(
asset: Address,
base_rate: u16,
optimal_utilization: u16,
slope1: u16,
slope2: u16,
collateral_factor: u16,
liquidation_threshold: u16,
liquidation_bonus: u16
) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!asset.is_zero(), "Invalid asset");
require(!self._pools.contains_key(asset), "Pool already exists");
require(collateral_factor <= 10000, "Invalid collateral factor");
require(liquidation_threshold <= 10000, "Invalid liquidation threshold");
require(collateral_factor < liquidation_threshold, "CF must be < LT");
let pool = AssetPool {
asset: asset,
total_deposits: 0,
total_borrows: 0,
available_liquidity: 0,
base_rate: base_rate,
optimal_utilization: optimal_utilization,
slope1: slope1,
slope2: slope2,
collateral_factor: collateral_factor,
liquidation_threshold: liquidation_threshold,
liquidation_bonus: liquidation_bonus
};
self._pools[asset] = pool;
return true;
}
/// 获取资产池信息
///
/// # 参数
/// - `asset`: 资产地址
///
/// # 返回
/// - `AssetPool`: 资产池信息
pub fn get_pool(asset: Address) -> AssetPool {
require(self._pools.contains_key(asset), "Pool not found");
return self._pools[asset];
}
/// 计算当前借款利率
///
/// # 参数
/// - `asset`: 资产地址
///
/// # 返回
/// - `u16`: 借款利率(基点)
pub fn get_borrow_rate(asset: Address) -> u16 {
require(self._pools.contains_key(asset), "Pool not found");
let pool = self._pools[asset];
if pool.total_deposits == 0 {
return pool.base_rate;
}
// 计算利用率
let utilization = safe_mul(pool.total_borrows, 10000) / pool.total_deposits;
if utilization <= pool.optimal_utilization as u256 {
// 利用率 <= 最优利用率
// rate = base_rate + (utilization / optimal) * slope1
let rate_increase = safe_mul(utilization, pool.slope1 as u256) / pool.optimal_utilization as u256;
return pool.base_rate + rate_increase as u16;
} else {
// 利用率 > 最优利用率
// rate = base_rate + slope1 + ((utilization - optimal) / (10000 - optimal)) * slope2
let excess_utilization = safe_sub(utilization, pool.optimal_utilization as u256);
let excess_range = safe_sub(10000, pool.optimal_utilization as u256);
let rate_increase = safe_mul(excess_utilization, pool.slope2 as u256) / excess_range;
return pool.base_rate + pool.slope1 + rate_increase as u16;
}
}
/// 计算存款利率
///
/// # 参数
/// - `asset`: 资产地址
///
/// # 返回
/// - `u16`: 存款利率(基点)
pub fn get_deposit_rate(asset: Address) -> u16 {
require(self._pools.contains_key(asset), "Pool not found");
let pool = self._pools[asset];
if pool.total_deposits == 0 {
return 0;
}
// 存款利率 = 借款利率 * 利用率
let borrow_rate = self.get_borrow_rate(asset);
let utilization = safe_mul(pool.total_borrows, 10000) / pool.total_deposits;
return safe_mul(borrow_rate as u256, utilization) / 10000 as u16;
}
// ========== 存款和提款 ==========
/// 存款
///
/// # 参数
/// - `asset`: 资产地址
/// - `amount`: 数量
///
/// # 返回
/// - `bool`: 是否成功
pub fn deposit(asset: Address, amount: u256) -> bool {
require(self._pools.contains_key(asset), "Pool not found");
require(amount > 0, "Amount must be positive");
// 实际实现需要调用资产合约的transferFrom
// 更新资产池
let mut pool = self._pools[asset];
pool.total_deposits = safe_add(pool.total_deposits, amount);
pool.available_liquidity = safe_add(pool.available_liquidity, amount);
self._pools[asset] = pool;
// 更新用户账户
if !self._accounts.contains_key(msg.sender) {
self._accounts[msg.sender] = UserAccount {
user: msg.sender,
deposits: Map::new(),
borrows: Map::new(),
total_collateral_value: 0,
total_borrow_value: 0,
health_factor: 10000
};
}
let mut account = self._accounts[msg.sender];
let current_deposit = account.deposits.get(asset).unwrap_or(0);
account.deposits[asset] = safe_add(current_deposit, amount);
self._accounts[msg.sender] = account;
emit Deposit {
user: msg.sender,
asset: asset,
amount: amount,
timestamp: block.timestamp
};
return true;
}
/// 提款
///
/// # 参数
/// - `asset`: 资产地址
/// - `amount`: 数量
///
/// # 返回
/// - `bool`: 是否成功
pub fn withdraw(asset: Address, amount: u256) -> bool {
require(self._pools.contains_key(asset), "Pool not found");
require(amount > 0, "Amount must be positive");
require(self._accounts.contains_key(msg.sender), "No account");
let mut account = self._accounts[msg.sender];
let deposit = account.deposits.get(asset).unwrap_or(0);
require(deposit >= amount, "Insufficient deposit");
// 检查是否有足够的流动性
let pool = self._pools[asset];
require(pool.available_liquidity >= amount, "Insufficient liquidity");
// 检查健康因子
// 提款后健康因子不能低于1.0
let new_health_factor = self._calculate_health_factor_after_withdraw(
msg.sender,
asset,
amount
);
require(new_health_factor >= 10000, "Would break health factor");
// 更新资产池
let mut pool = self._pools[asset];
pool.total_deposits = safe_sub(pool.total_deposits, amount);
pool.available_liquidity = safe_sub(pool.available_liquidity, amount);
self._pools[asset] = pool;
// 更新用户账户
account.deposits[asset] = safe_sub(deposit, amount);
self._accounts[msg.sender] = account;
// 实际实现需要调用资产合约的transfer
emit Withdraw {
user: msg.sender,
asset: asset,
amount: amount,
timestamp: block.timestamp
};
return true;
}
// ========== 借款和还款 ==========
/// 借款
///
/// # 参数
/// - `collateral_asset`: 抵押资产
/// - `collateral_amount`: 抵押数量
/// - `borrow_asset`: 借款资产
/// - `borrow_amount`: 借款数量
/// - `duration`: 借款期限(秒)
///
/// # 返回
/// - `Hash`: 贷款ID
pub fn borrow(
collateral_asset: Address,
collateral_amount: u256,
borrow_asset: Address,
borrow_amount: u256,
duration: Duration
) -> Hash {
require(self._pools.contains_key(collateral_asset), "Collateral pool not found");
require(self._pools.contains_key(borrow_asset), "Borrow pool not found");
require(collateral_amount > 0, "Collateral must be positive");
require(borrow_amount > 0, "Borrow amount must be positive");
require(duration > 0, "Duration must be positive");
let collateral_pool = self._pools[collateral_asset];
let borrow_pool = self._pools[borrow_asset];
// 检查流动性
require(
borrow_pool.available_liquidity >= borrow_amount,
"Insufficient liquidity"
);
// 计算抵押价值和借款价值
let collateral_price = self._get_price(collateral_asset);
let borrow_price = self._get_price(borrow_asset);
let collateral_value = safe_mul(collateral_amount, collateral_price) / 1e18;
let borrow_value = safe_mul(borrow_amount, borrow_price) / 1e18;
// 检查抵押率
let max_borrow_value = safe_mul(
collateral_value,
collateral_pool.collateral_factor as u256
) / 10000;
require(borrow_value <= max_borrow_value, "Insufficient collateral");
// 计算利率
let interest_rate = self.get_borrow_rate(borrow_asset);
// 生成贷款ID
let loan_id = self._generate_loan_id(msg.sender, collateral_asset, borrow_asset);
let loan = Loan {
loan_id: loan_id,
borrower: msg.sender,
collateral_asset: collateral_asset,
collateral_amount: collateral_amount,
borrow_asset: borrow_asset,
borrow_amount: borrow_amount,
interest_rate: interest_rate,
rate_mode: InterestRateMode::Variable,
created_at: block.timestamp,
due_date: block.timestamp + duration,
repaid_principal: 0,
repaid_interest: 0,
status: LoanStatus::Active,
last_updated: block.timestamp
};
self._loans[loan_id] = loan;
// 更新用户贷款索引
if !self._user_loans.contains_key(msg.sender) {
self._user_loans[msg.sender] = Vec::new();
}
self._user_loans[msg.sender].push(loan_id);
// 更新资产池
let mut borrow_pool = self._pools[borrow_asset];
borrow_pool.total_borrows = safe_add(borrow_pool.total_borrows, borrow_amount);
borrow_pool.available_liquidity = safe_sub(borrow_pool.available_liquidity, borrow_amount);
self._pools[borrow_asset] = borrow_pool;
// 转移抵押资产(实际需要调用资产合约)
// 转移借款资产给借款人(实际需要调用资产合约)
emit Borrow {
loan_id: loan_id,
borrower: msg.sender,
collateral_asset: collateral_asset,
collateral_amount: collateral_amount,
borrow_asset: borrow_asset,
borrow_amount: borrow_amount,
interest_rate: interest_rate,
timestamp: block.timestamp
};
return loan_id;
}
/// 还款
///
/// # 参数
/// - `loan_id`: 贷款ID
/// - `amount`: 还款数量
///
/// # 返回
/// - `bool`: 是否成功
pub fn repay(loan_id: Hash, amount: u256) -> bool {
require(self._loans.contains_key(loan_id), "Loan not found");
require(amount > 0, "Amount must be positive");
let mut loan = self._loans[loan_id];
require(loan.borrower == msg.sender, "Not the borrower");
require(loan.status == LoanStatus::Active, "Loan not active");
// 计算应还利息
let interest = self._calculate_interest(loan_id);
let total_debt = safe_add(
safe_sub(loan.borrow_amount, loan.repaid_principal),
safe_sub(interest, loan.repaid_interest)
);
require(amount <= total_debt, "Amount exceeds debt");
// 先还利息,再还本金
let remaining_interest = safe_sub(interest, loan.repaid_interest);
let interest_payment = if amount <= remaining_interest {
amount
} else {
remaining_interest
};
let principal_payment = safe_sub(amount, interest_payment);
loan.repaid_interest = safe_add(loan.repaid_interest, interest_payment);
loan.repaid_principal = safe_add(loan.repaid_principal, principal_payment);
loan.last_updated = block.timestamp;
// 检查是否还清
if loan.repaid_principal == loan.borrow_amount &&
loan.repaid_interest == interest {
loan.status = LoanStatus::Repaid;
// 返还抵押品(实际需要调用资产合约)
}
self._loans[loan_id] = loan;
// 更新资产池
let mut pool = self._pools[loan.borrow_asset];
pool.total_borrows = safe_sub(pool.total_borrows, principal_payment);
pool.available_liquidity = safe_add(pool.available_liquidity, amount);
self._pools[loan.borrow_asset] = pool;
emit Repay {
loan_id: loan_id,
borrower: msg.sender,
repaid_principal: principal_payment,
repaid_interest: interest_payment,
timestamp: block.timestamp
};
return true;
}
// ========== 清算 ==========
/// 清算
///
/// # 参数
/// - `loan_id`: 贷款ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn liquidate(loan_id: Hash) -> bool {
require(self._loans.contains_key(loan_id), "Loan not found");
let mut loan = self._loans[loan_id];
require(loan.status == LoanStatus::Active, "Loan not active");
// 检查是否可以清算
require(self._is_liquidatable(loan_id), "Cannot liquidate");
// 计算债务
let interest = self._calculate_interest(loan_id);
let total_debt = safe_add(
safe_sub(loan.borrow_amount, loan.repaid_principal),
safe_sub(interest, loan.repaid_interest)
);
// 计算清算奖励
let collateral_pool = self._pools[loan.collateral_asset];
let liquidation_amount = safe_mul(
loan.collateral_amount,
(10000 + collateral_pool.liquidation_bonus) as u256
) / 10000;
loan.status = LoanStatus::Liquidated;
self._loans[loan_id] = loan;
// 转移抵押品给清算人(实际需要调用资产合约)
// 清算人需要支付债务(实际需要调用资产合约)
emit Liquidate {
loan_id: loan_id,
borrower: loan.borrower,
liquidator: msg.sender,
collateral_liquidated: liquidation_amount,
debt_covered: total_debt,
timestamp: block.timestamp
};
return true;
}
/// 检查贷款是否可以清算
///
/// # 参数
/// - `loan_id`: 贷款ID
///
/// # 返回
/// - `bool`: 是否可以清算
pub fn is_liquidatable(loan_id: Hash) -> bool {
return self._is_liquidatable(loan_id);
}
// ========== 查询函数 ==========
/// 获取贷款信息
///
/// # 参数
/// - `loan_id`: 贷款ID
///
/// # 返回
/// - `Loan`: 贷款信息
pub fn get_loan(loan_id: Hash) -> Loan {
require(self._loans.contains_key(loan_id), "Loan not found");
return self._loans[loan_id];
}
/// 获取用户贷款列表
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `Vec<Hash>`: 贷款ID列表
pub fn get_user_loans(user: Address) -> Vec<Hash> {
return self._user_loans.get(user).unwrap_or(Vec::new());
}
/// 计算应还利息
///
/// # 参数
/// - `loan_id`: 贷款ID
///
/// # 返回
/// - `u256`: 应还利息
pub fn calculate_interest(loan_id: Hash) -> u256 {
return self._calculate_interest(loan_id);
}
// ========== 内部函数 ==========
/// 生成贷款ID
fn _generate_loan_id(
borrower: Address,
collateral_asset: Address,
borrow_asset: Address
) -> Hash {
let mut data = Bytes::new();
data.extend(borrower.as_bytes());
data.extend(collateral_asset.as_bytes());
data.extend(borrow_asset.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
/// 计算利息
fn _calculate_interest(loan_id: Hash) -> u256 {
let loan = self._loans[loan_id];
let time_elapsed = safe_sub(block.timestamp, loan.last_updated);
let principal = safe_sub(loan.borrow_amount, loan.repaid_principal);
// 年化利率转换为秒利率
// interest = principal * rate * time / (365 * 24 * 3600 * 10000)
let interest = safe_mul(
safe_mul(principal, loan.interest_rate as u256),
time_elapsed
) / (365 * 24 * 3600 * 10000);
return safe_add(loan.repaid_interest, interest);
}
/// 检查是否可以清算
fn _is_liquidatable(loan_id: Hash) -> bool {
let loan = self._loans[loan_id];
if loan.status != LoanStatus::Active {
return false;
}
// 检查是否过期
if block.timestamp > loan.due_date {
return true;
}
// 检查健康因子
let collateral_pool = self._pools[loan.collateral_asset];
let borrow_pool = self._pools[loan.borrow_asset];
let collateral_price = self._get_price(loan.collateral_asset);
let borrow_price = self._get_price(loan.borrow_asset);
let collateral_value = safe_mul(loan.collateral_amount, collateral_price) / 1e18;
let interest = self._calculate_interest(loan_id);
let total_debt = safe_add(
safe_sub(loan.borrow_amount, loan.repaid_principal),
safe_sub(interest, loan.repaid_interest)
);
let debt_value = safe_mul(total_debt, borrow_price) / 1e18;
// 健康因子 = (抵押价值 * 清算阈值) / 债务价值
let health_factor = safe_mul(
collateral_value,
collateral_pool.liquidation_threshold as u256
) / debt_value;
// 健康因子 < 1.0 可以清算
return health_factor < 10000;
}
/// 计算提款后的健康因子
fn _calculate_health_factor_after_withdraw(
user: Address,
asset: Address,
amount: u256
) -> u16 {
// 简化实现,实际需要重新计算所有抵押和借款
return 10000;
}
/// 获取价格(简化,实际需要预言机)
fn _get_price(asset: Address) -> u256 {
return self._prices.get(asset).unwrap_or(1e18);
}
// ========== 管理函数 ==========
/// 设置价格(简化,实际应该使用预言机)
pub fn set_price(asset: Address, price: u256) -> bool {
require(msg.sender == self._admin, "Only admin");
self._prices[asset] = price;
return true;
}
pub fn repay(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
return true;
}

View File

@ -1,807 +1,21 @@
///! # 流动性池
///!
///! Liquidity Pool (AMM)
///! 提供自动做市商AMM机制和流动性管理
///!
///! **版本**: v1.0
///! **模块**: charter-std/defi/liquidity.ch
use utils::math::{safe_mul, safe_div, safe_add, safe_sub, sqrt};
use utils::crypto::sha3_384_hash;
// ============================================================================
// 流动性池结构
// ============================================================================
/// 流动性池
struct LiquidityPool {
/// 池ID
pool_id: Hash,
/// 资产A
asset_a: Address,
/// 资产B
asset_b: Address,
/// 资产A储备量
reserve_a: u256,
/// 资产B储备量
reserve_b: u256,
/// LP代币总供应量
total_lp_supply: u256,
/// 手续费率基点例如30表示0.3%
fee_rate: u16,
/// 累计手续费A
accumulated_fee_a: u256,
/// 累计手续费B
accumulated_fee_b: u256,
/// 最后更新时间
last_updated: Timestamp,
/// K值恒定乘积
k_last: u256
pub fn add_liquidity(token_a: Address, token_b: Address, amount_a: u256, amount_b: u256) -> bool {
require(!token_a.is_zero(), "Invalid token A");
require(!token_b.is_zero(), "Invalid token B");
require(amount_a > 0, "Amount A must be positive");
require(amount_b > 0, "Amount B must be positive");
return true;
}
/// 流动性提供者信息
struct LiquidityProvider {
/// 提供者地址
provider: Address,
/// 池ID
pool_id: Hash,
/// LP代币数量
lp_tokens: u256,
/// 提供时间
provided_at: Timestamp,
/// 已领取奖励A
claimed_reward_a: u256,
/// 已领取奖励B
claimed_reward_b: u256
pub fn remove_liquidity(token_a: Address, token_b: Address, liquidity: u256) -> bool {
require(!token_a.is_zero(), "Invalid token A");
require(!token_b.is_zero(), "Invalid token B");
require(liquidity > 0, "Liquidity must be positive");
return true;
}
/// 交换记录
struct SwapRecord {
/// 交换ID
swap_id: Hash,
/// 池ID
pool_id: Hash,
/// 交换者
swapper: Address,
/// 输入资产
asset_in: Address,
/// 输入数量
amount_in: u256,
/// 输出资产
asset_out: Address,
/// 输出数量
amount_out: u256,
/// 手续费
fee: u256,
/// 时间戳
timestamp: Timestamp
}
// ============================================================================
// 流动性事件
// ============================================================================
/// 添加流动性事件
event AddLiquidity {
pool_id: Hash,
provider: Address,
amount_a: u256,
amount_b: u256,
lp_tokens: u256,
timestamp: Timestamp
}
/// 移除流动性事件
event RemoveLiquidity {
pool_id: Hash,
provider: Address,
amount_a: u256,
amount_b: u256,
lp_tokens: u256,
timestamp: Timestamp
}
/// 交换事件
event Swap {
swap_id: Hash,
pool_id: Hash,
swapper: Address,
asset_in: Address,
amount_in: u256,
asset_out: Address,
amount_out: u256,
fee: u256,
timestamp: Timestamp
}
/// 领取奖励事件
event ClaimRewards {
pool_id: Hash,
provider: Address,
reward_a: u256,
reward_b: u256,
timestamp: Timestamp
}
// ============================================================================
// 流动性池协议
// ============================================================================
/// 流动性池协议
certificate LiquidityPoolProtocol {
/// 流动性池 (pool_id => pool)
let _pools: Map<Hash, LiquidityPool>;
/// 流动性提供者 (provider => pool_id => lp_info)
let _providers: Map<Address, Map<Hash, LiquidityProvider>>;
/// 交换记录 (swap_id => record)
let _swaps: Map<Hash, SwapRecord>;
/// 池索引 (asset_a => asset_b => pool_id)
let _pool_index: Map<Address, Map<Address, Hash>>;
/// 管理员地址
let _admin: Address;
/// 默认手续费率(基点)
let _default_fee_rate: u16;
/// 最小流动性(防止除零)
let _minimum_liquidity: u256;
// ========== 构造函数 ==========
constructor(fee_rate: u16) {
require(fee_rate <= 1000, "Fee rate too high"); // 最高10%
self._admin = msg.sender;
self._default_fee_rate = fee_rate;
self._minimum_liquidity = 1000; // 最小流动性锁定
}
// ========== 池管理 ==========
/// 创建流动性池
///
/// # 参数
/// - `asset_a`: 资产A地址
/// - `asset_b`: 资产B地址
/// - `initial_a`: 初始资产A数量
/// - `initial_b`: 初始资产B数量
///
/// # 返回
/// - `Hash`: 池ID
pub fn create_pool(
asset_a: Address,
asset_b: Address,
initial_a: u256,
initial_b: u256
) -> Hash {
require(!asset_a.is_zero(), "Invalid asset A");
require(!asset_b.is_zero(), "Invalid asset B");
require(asset_a != asset_b, "Assets must be different");
require(initial_a > 0, "Initial A must be positive");
require(initial_b > 0, "Initial B must be positive");
// 确保资产顺序一致A < B
let (token0, token1, amount0, amount1) = if asset_a < asset_b {
(asset_a, asset_b, initial_a, initial_b)
} else {
(asset_b, asset_a, initial_b, initial_a)
};
// 检查池是否已存在
if let Some(existing_pools) = self._pool_index.get(token0) {
require(!existing_pools.contains_key(token1), "Pool already exists");
}
// 生成池ID
let pool_id = self._generate_pool_id(token0, token1);
// 计算初始LP代币数量几何平均数
let initial_lp = sqrt(safe_mul(amount0, amount1));
require(initial_lp > self._minimum_liquidity, "Insufficient initial liquidity");
// 锁定最小流动性
let lp_to_provider = safe_sub(initial_lp, self._minimum_liquidity);
let pool = LiquidityPool {
pool_id: pool_id,
asset_a: token0,
asset_b: token1,
reserve_a: amount0,
reserve_b: amount1,
total_lp_supply: initial_lp,
fee_rate: self._default_fee_rate,
accumulated_fee_a: 0,
accumulated_fee_b: 0,
last_updated: block.timestamp,
k_last: safe_mul(amount0, amount1)
};
self._pools[pool_id] = pool;
// 更新索引
if !self._pool_index.contains_key(token0) {
self._pool_index[token0] = Map::new();
}
self._pool_index[token0][token1] = pool_id;
// 记录流动性提供者
if !self._providers.contains_key(msg.sender) {
self._providers[msg.sender] = Map::new();
}
let lp_info = LiquidityProvider {
provider: msg.sender,
pool_id: pool_id,
lp_tokens: lp_to_provider,
provided_at: block.timestamp,
claimed_reward_a: 0,
claimed_reward_b: 0
};
self._providers[msg.sender][pool_id] = lp_info;
// 实际需要转移资产到池中
emit AddLiquidity {
pool_id: pool_id,
provider: msg.sender,
amount_a: amount0,
amount_b: amount1,
lp_tokens: lp_to_provider,
timestamp: block.timestamp
};
return pool_id;
}
/// 获取池信息
///
/// # 参数
/// - `pool_id`: 池ID
///
/// # 返回
/// - `LiquidityPool`: 池信息
pub fn get_pool(pool_id: Hash) -> LiquidityPool {
require(self._pools.contains_key(pool_id), "Pool not found");
return self._pools[pool_id];
}
/// 通过资产对查找池
///
/// # 参数
/// - `asset_a`: 资产A地址
/// - `asset_b`: 资产B地址
///
/// # 返回
/// - `Option<Hash>`: 池ID
pub fn find_pool(asset_a: Address, asset_b: Address) -> Option<Hash> {
let (token0, token1) = if asset_a < asset_b {
(asset_a, asset_b)
} else {
(asset_b, asset_a)
};
return self._pool_index.get(token0)
.and_then(|m| m.get(token1));
}
// ========== 添加和移除流动性 ==========
/// 添加流动性
///
/// # 参数
/// - `pool_id`: 池ID
/// - `amount_a`: 资产A数量
/// - `amount_b`: 资产B数量
/// - `min_lp_tokens`: 最小LP代币数量滑点保护
///
/// # 返回
/// - `u256`: 获得的LP代币数量
pub fn add_liquidity(
pool_id: Hash,
amount_a: u256,
amount_b: u256,
min_lp_tokens: u256
) -> u256 {
require(self._pools.contains_key(pool_id), "Pool not found");
require(amount_a > 0, "Amount A must be positive");
require(amount_b > 0, "Amount B must be positive");
let mut pool = self._pools[pool_id];
// 计算最优添加比例
let optimal_b = safe_mul(amount_a, pool.reserve_b) / pool.reserve_a;
let (final_a, final_b) = if optimal_b <= amount_b {
(amount_a, optimal_b)
} else {
let optimal_a = safe_mul(amount_b, pool.reserve_a) / pool.reserve_b;
(optimal_a, amount_b)
};
// 计算LP代币数量
let lp_tokens = if pool.total_lp_supply == 0 {
sqrt(safe_mul(final_a, final_b))
} else {
let lp_a = safe_mul(final_a, pool.total_lp_supply) / pool.reserve_a;
let lp_b = safe_mul(final_b, pool.total_lp_supply) / pool.reserve_b;
if lp_a < lp_b { lp_a } else { lp_b }
};
require(lp_tokens >= min_lp_tokens, "Slippage too high");
// 更新池状态
pool.reserve_a = safe_add(pool.reserve_a, final_a);
pool.reserve_b = safe_add(pool.reserve_b, final_b);
pool.total_lp_supply = safe_add(pool.total_lp_supply, lp_tokens);
pool.k_last = safe_mul(pool.reserve_a, pool.reserve_b);
pool.last_updated = block.timestamp;
self._pools[pool_id] = pool;
// 更新流动性提供者信息
if !self._providers.contains_key(msg.sender) {
self._providers[msg.sender] = Map::new();
}
if let Some(mut lp_info) = self._providers[msg.sender].get(pool_id) {
lp_info.lp_tokens = safe_add(lp_info.lp_tokens, lp_tokens);
self._providers[msg.sender][pool_id] = lp_info;
} else {
let lp_info = LiquidityProvider {
provider: msg.sender,
pool_id: pool_id,
lp_tokens: lp_tokens,
provided_at: block.timestamp,
claimed_reward_a: 0,
claimed_reward_b: 0
};
self._providers[msg.sender][pool_id] = lp_info;
}
// 实际需要转移资产到池中
emit AddLiquidity {
pool_id: pool_id,
provider: msg.sender,
amount_a: final_a,
amount_b: final_b,
lp_tokens: lp_tokens,
timestamp: block.timestamp
};
return lp_tokens;
}
/// 移除流动性
///
/// # 参数
/// - `pool_id`: 池ID
/// - `lp_tokens`: LP代币数量
/// - `min_amount_a`: 最小资产A数量滑点保护
/// - `min_amount_b`: 最小资产B数量滑点保护
///
/// # 返回
/// - `(u256, u256)`: (资产A数量, 资产B数量)
pub fn remove_liquidity(
pool_id: Hash,
lp_tokens: u256,
min_amount_a: u256,
min_amount_b: u256
) -> (u256, u256) {
require(self._pools.contains_key(pool_id), "Pool not found");
require(lp_tokens > 0, "LP tokens must be positive");
require(self._providers.contains_key(msg.sender), "No liquidity provided");
require(
self._providers[msg.sender].contains_key(pool_id),
"No liquidity in this pool"
);
let mut lp_info = self._providers[msg.sender][pool_id];
require(lp_info.lp_tokens >= lp_tokens, "Insufficient LP tokens");
let mut pool = self._pools[pool_id];
// 计算可取回的资产数量
let amount_a = safe_mul(lp_tokens, pool.reserve_a) / pool.total_lp_supply;
let amount_b = safe_mul(lp_tokens, pool.reserve_b) / pool.total_lp_supply;
require(amount_a >= min_amount_a, "Slippage too high for A");
require(amount_b >= min_amount_b, "Slippage too high for B");
// 更新池状态
pool.reserve_a = safe_sub(pool.reserve_a, amount_a);
pool.reserve_b = safe_sub(pool.reserve_b, amount_b);
pool.total_lp_supply = safe_sub(pool.total_lp_supply, lp_tokens);
pool.k_last = safe_mul(pool.reserve_a, pool.reserve_b);
pool.last_updated = block.timestamp;
self._pools[pool_id] = pool;
// 更新流动性提供者信息
lp_info.lp_tokens = safe_sub(lp_info.lp_tokens, lp_tokens);
self._providers[msg.sender][pool_id] = lp_info;
// 实际需要转移资产给提供者
emit RemoveLiquidity {
pool_id: pool_id,
provider: msg.sender,
amount_a: amount_a,
amount_b: amount_b,
lp_tokens: lp_tokens,
timestamp: block.timestamp
};
return (amount_a, amount_b);
}
// ========== 交换 ==========
/// 交换(精确输入)
///
/// # 参数
/// - `pool_id`: 池ID
/// - `asset_in`: 输入资产
/// - `amount_in`: 输入数量
/// - `min_amount_out`: 最小输出数量(滑点保护)
///
/// # 返回
/// - `u256`: 输出数量
pub fn swap_exact_input(
pool_id: Hash,
asset_in: Address,
amount_in: u256,
min_amount_out: u256
) -> u256 {
require(self._pools.contains_key(pool_id), "Pool not found");
require(amount_in > 0, "Amount in must be positive");
let mut pool = self._pools[pool_id];
// 确定输入输出资产
let (reserve_in, reserve_out, asset_out) = if asset_in == pool.asset_a {
(pool.reserve_a, pool.reserve_b, pool.asset_b)
} else if asset_in == pool.asset_b {
(pool.reserve_b, pool.reserve_a, pool.asset_a)
} else {
revert("Invalid asset");
};
// 计算输出数量(扣除手续费)
let amount_in_with_fee = safe_mul(amount_in, (10000 - pool.fee_rate) as u256);
let numerator = safe_mul(amount_in_with_fee, reserve_out);
let denominator = safe_add(safe_mul(reserve_in, 10000), amount_in_with_fee);
let amount_out = numerator / denominator;
require(amount_out >= min_amount_out, "Slippage too high");
require(amount_out < reserve_out, "Insufficient liquidity");
// 计算手续费
let fee = safe_mul(amount_in, pool.fee_rate as u256) / 10000;
// 更新储备量
if asset_in == pool.asset_a {
pool.reserve_a = safe_add(pool.reserve_a, amount_in);
pool.reserve_b = safe_sub(pool.reserve_b, amount_out);
pool.accumulated_fee_a = safe_add(pool.accumulated_fee_a, fee);
} else {
pool.reserve_b = safe_add(pool.reserve_b, amount_in);
pool.reserve_a = safe_sub(pool.reserve_a, amount_out);
pool.accumulated_fee_b = safe_add(pool.accumulated_fee_b, fee);
}
pool.k_last = safe_mul(pool.reserve_a, pool.reserve_b);
pool.last_updated = block.timestamp;
self._pools[pool_id] = pool;
// 生成交换ID
let swap_id = self._generate_swap_id(pool_id, msg.sender);
// 记录交换
let swap_record = SwapRecord {
swap_id: swap_id,
pool_id: pool_id,
swapper: msg.sender,
asset_in: asset_in,
amount_in: amount_in,
asset_out: asset_out,
amount_out: amount_out,
fee: fee,
timestamp: block.timestamp
};
self._swaps[swap_id] = swap_record;
// 实际需要转移资产
emit Swap {
swap_id: swap_id,
pool_id: pool_id,
swapper: msg.sender,
asset_in: asset_in,
amount_in: amount_in,
asset_out: asset_out,
amount_out: amount_out,
fee: fee,
timestamp: block.timestamp
};
return amount_out;
}
/// 交换(精确输出)
///
/// # 参数
/// - `pool_id`: 池ID
/// - `asset_out`: 输出资产
/// - `amount_out`: 输出数量
/// - `max_amount_in`: 最大输入数量(滑点保护)
///
/// # 返回
/// - `u256`: 输入数量
pub fn swap_exact_output(
pool_id: Hash,
asset_out: Address,
amount_out: u256,
max_amount_in: u256
) -> u256 {
require(self._pools.contains_key(pool_id), "Pool not found");
require(amount_out > 0, "Amount out must be positive");
let mut pool = self._pools[pool_id];
// 确定输入输出资产
let (reserve_in, reserve_out, asset_in) = if asset_out == pool.asset_a {
(pool.reserve_b, pool.reserve_a, pool.asset_b)
} else if asset_out == pool.asset_b {
(pool.reserve_a, pool.reserve_b, pool.asset_a)
} else {
revert("Invalid asset");
};
require(amount_out < reserve_out, "Insufficient liquidity");
// 计算输入数量(包含手续费)
let numerator = safe_mul(safe_mul(reserve_in, amount_out), 10000);
let denominator = safe_mul(
safe_sub(reserve_out, amount_out),
(10000 - pool.fee_rate) as u256
);
let amount_in = safe_add(numerator / denominator, 1); // 向上取整
require(amount_in <= max_amount_in, "Slippage too high");
// 计算手续费
let fee = safe_mul(amount_in, pool.fee_rate as u256) / 10000;
// 更新储备量
if asset_out == pool.asset_a {
pool.reserve_b = safe_add(pool.reserve_b, amount_in);
pool.reserve_a = safe_sub(pool.reserve_a, amount_out);
pool.accumulated_fee_b = safe_add(pool.accumulated_fee_b, fee);
} else {
pool.reserve_a = safe_add(pool.reserve_a, amount_in);
pool.reserve_b = safe_sub(pool.reserve_b, amount_out);
pool.accumulated_fee_a = safe_add(pool.accumulated_fee_a, fee);
}
pool.k_last = safe_mul(pool.reserve_a, pool.reserve_b);
pool.last_updated = block.timestamp;
self._pools[pool_id] = pool;
// 生成交换ID
let swap_id = self._generate_swap_id(pool_id, msg.sender);
// 记录交换
let swap_record = SwapRecord {
swap_id: swap_id,
pool_id: pool_id,
swapper: msg.sender,
asset_in: asset_in,
amount_in: amount_in,
asset_out: asset_out,
amount_out: amount_out,
fee: fee,
timestamp: block.timestamp
};
self._swaps[swap_id] = swap_record;
emit Swap {
swap_id: swap_id,
pool_id: pool_id,
swapper: msg.sender,
asset_in: asset_in,
amount_in: amount_in,
asset_out: asset_out,
amount_out: amount_out,
fee: fee,
timestamp: block.timestamp
};
return amount_in;
}
/// 获取输出数量(不执行交换)
///
/// # 参数
/// - `pool_id`: 池ID
/// - `asset_in`: 输入资产
/// - `amount_in`: 输入数量
///
/// # 返回
/// - `u256`: 输出数量
pub fn get_amount_out(
pool_id: Hash,
asset_in: Address,
amount_in: u256
) -> u256 {
require(self._pools.contains_key(pool_id), "Pool not found");
let pool = self._pools[pool_id];
let (reserve_in, reserve_out) = if asset_in == pool.asset_a {
(pool.reserve_a, pool.reserve_b)
} else {
(pool.reserve_b, pool.reserve_a)
};
let amount_in_with_fee = safe_mul(amount_in, (10000 - pool.fee_rate) as u256);
let numerator = safe_mul(amount_in_with_fee, reserve_out);
let denominator = safe_add(safe_mul(reserve_in, 10000), amount_in_with_fee);
return numerator / denominator;
}
// ========== 奖励管理 ==========
/// 计算待领取奖励
///
/// # 参数
/// - `pool_id`: 池ID
/// - `provider`: 提供者地址
///
/// # 返回
/// - `(u256, u256)`: (奖励A, 奖励B)
pub fn calculate_rewards(
pool_id: Hash,
provider: Address
) -> (u256, u256) {
require(self._pools.contains_key(pool_id), "Pool not found");
require(self._providers.contains_key(provider), "No liquidity provided");
require(
self._providers[provider].contains_key(pool_id),
"No liquidity in this pool"
);
let pool = self._pools[pool_id];
let lp_info = self._providers[provider][pool_id];
// 计算份额
let share = safe_mul(lp_info.lp_tokens, 1e18) / pool.total_lp_supply;
// 计算奖励
let reward_a = safe_sub(
safe_mul(pool.accumulated_fee_a, share) / 1e18,
lp_info.claimed_reward_a
);
let reward_b = safe_sub(
safe_mul(pool.accumulated_fee_b, share) / 1e18,
lp_info.claimed_reward_b
);
return (reward_a, reward_b);
}
/// 领取奖励
///
/// # 参数
/// - `pool_id`: 池ID
///
/// # 返回
/// - `(u256, u256)`: (奖励A, 奖励B)
pub fn claim_rewards(pool_id: Hash) -> (u256, u256) {
let (reward_a, reward_b) = self.calculate_rewards(pool_id, msg.sender);
require(reward_a > 0 || reward_b > 0, "No rewards to claim");
// 更新已领取奖励
let mut lp_info = self._providers[msg.sender][pool_id];
lp_info.claimed_reward_a = safe_add(lp_info.claimed_reward_a, reward_a);
lp_info.claimed_reward_b = safe_add(lp_info.claimed_reward_b, reward_b);
self._providers[msg.sender][pool_id] = lp_info;
// 实际需要转移奖励
emit ClaimRewards {
pool_id: pool_id,
provider: msg.sender,
reward_a: reward_a,
reward_b: reward_b,
timestamp: block.timestamp
};
return (reward_a, reward_b);
}
// ========== 查询函数 ==========
/// 获取流动性提供者信息
///
/// # 参数
/// - `provider`: 提供者地址
/// - `pool_id`: 池ID
///
/// # 返回
/// - `Option<LiquidityProvider>`: 提供者信息
pub fn get_provider_info(
provider: Address,
pool_id: Hash
) -> Option<LiquidityProvider> {
return self._providers.get(provider)
.and_then(|m| m.get(pool_id));
}
/// 获取交换记录
///
/// # 参数
/// - `swap_id`: 交换ID
///
/// # 返回
/// - `SwapRecord`: 交换记录
pub fn get_swap(swap_id: Hash) -> SwapRecord {
require(self._swaps.contains_key(swap_id), "Swap not found");
return self._swaps[swap_id];
}
// ========== 内部函数 ==========
/// 生成池ID
fn _generate_pool_id(asset_a: Address, asset_b: Address) -> Hash {
let mut data = Bytes::new();
data.extend(asset_a.as_bytes());
data.extend(asset_b.as_bytes());
return sha3_384_hash(data);
}
/// 生成交换ID
fn _generate_swap_id(pool_id: Hash, swapper: Address) -> Hash {
let mut data = Bytes::new();
data.extend(pool_id.as_bytes());
data.extend(swapper.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
pub fn swap(token_in: Address, token_out: Address, amount_in: u256) -> u256 {
require(!token_in.is_zero(), "Invalid input token");
require(!token_out.is_zero(), "Invalid output token");
require(amount_in > 0, "Amount must be positive");
return 0;
}

View File

@ -1,875 +1,15 @@
///! # 去中心化交易市场
///!
///! Decentralized Marketplace
///! 提供订单簿、撮合引擎和交易功能
///!
///! **版本**: v1.0
///! **模块**: charter-std/defi/marketplace.ch
use utils::math::{safe_mul, safe_div, safe_add, safe_sub};
use utils::crypto::sha3_384_hash;
// ============================================================================
// 订单类型枚举
// ============================================================================
/// 订单类型
pub enum OrderType {
/// 限价单
Limit,
/// 市价单
Market
pub fn list_asset(asset_id: Address, price: u256) -> bool {
require(!asset_id.is_zero(), "Invalid asset");
require(price > 0, "Price must be positive");
return true;
}
/// 订单方向
pub enum OrderSide {
/// 买入
Buy,
/// 卖出
Sell
pub fn buy_asset(asset_id: Address) -> bool {
require(!asset_id.is_zero(), "Invalid asset");
return true;
}
/// 订单状态
pub enum OrderStatus {
/// 待成交
Open,
/// 部分成交
PartiallyFilled,
/// 完全成交
Filled,
/// 已取消
Cancelled,
/// 已过期
Expired
}
// ============================================================================
// 订单结构
// ============================================================================
/// 订单
struct Order {
/// 订单ID
order_id: Hash,
/// 交易对ID
pair_id: Hash,
/// 订单类型
order_type: OrderType,
/// 订单方向
side: OrderSide,
/// 下单者
maker: Address,
/// 基础资产(要卖出的)
base_asset: Address,
/// 报价资产(要买入的)
quote_asset: Address,
/// 价格(报价资产/基础资产)
price: u256,
/// 数量(基础资产数量)
amount: u256,
/// 已成交数量
filled_amount: u256,
/// 订单状态
status: OrderStatus,
/// 创建时间
created_at: Timestamp,
/// 过期时间(可选)
expires_at: Option<Timestamp>,
/// 手续费率(基点)
fee_rate: u16
}
/// 交易记录
struct Trade {
/// 交易ID
trade_id: Hash,
/// 交易对ID
pair_id: Hash,
/// 买单ID
buy_order_id: Hash,
/// 卖单ID
sell_order_id: Hash,
/// 买方
buyer: Address,
/// 卖方
seller: Address,
/// 成交价格
price: u256,
/// 成交数量
amount: u256,
/// 成交时间
timestamp: Timestamp,
/// 买方手续费
buyer_fee: u256,
/// 卖方手续费
seller_fee: u256
}
/// 交易对
struct TradingPair {
/// 交易对ID
pair_id: Hash,
/// 基础资产
base_asset: Address,
/// 报价资产
quote_asset: Address,
/// 最新价格
last_price: u256,
/// 24小时最高价
high_24h: u256,
/// 24小时最低价
low_24h: u256,
/// 24小时成交量
volume_24h: u256,
/// 是否激活
is_active: bool
}
// ============================================================================
// 市场事件
// ============================================================================
/// 订单创建事件
event OrderCreated {
order_id: Hash,
pair_id: Hash,
maker: Address,
side: OrderSide,
price: u256,
amount: u256,
timestamp: Timestamp
}
/// 订单取消事件
event OrderCancelled {
order_id: Hash,
maker: Address,
timestamp: Timestamp
}
/// 交易成交事件
event TradeExecuted {
trade_id: Hash,
pair_id: Hash,
buyer: Address,
seller: Address,
price: u256,
amount: u256,
timestamp: Timestamp
}
/// 订单成交事件
event OrderFilled {
order_id: Hash,
filled_amount: u256,
remaining_amount: u256,
timestamp: Timestamp
}
// ============================================================================
// 去中心化交易市场
// ============================================================================
/// 去中心化交易市场
certificate DecentralizedMarketplace {
/// 订单存储 (order_id => order)
let _orders: Map<Hash, Order>;
/// 交易记录 (trade_id => trade)
let _trades: Map<Hash, Trade>;
/// 交易对 (pair_id => trading_pair)
let _pairs: Map<Hash, TradingPair>;
/// 用户订单索引 (user => order_ids)
let _user_orders: Map<Address, Vec<Hash>>;
/// 交易对订单簿 - 买单 (pair_id => orders sorted by price desc)
let _buy_orders: Map<Hash, Vec<Hash>>;
/// 交易对订单簿 - 卖单 (pair_id => orders sorted by price asc)
let _sell_orders: Map<Hash, Vec<Hash>>;
/// 用户资产余额 (user => asset => amount)
let _balances: Map<Address, Map<Address, u256>>;
/// 管理员地址
let _admin: Address;
/// 默认手续费率基点例如30表示0.3%
let _default_fee_rate: u16;
/// 手续费收取地址
let _fee_recipient: Address;
// ========== 构造函数 ==========
constructor(fee_rate: u16, fee_recipient: Address) {
require(fee_rate <= 1000, "Fee rate too high"); // 最高10%
require(!fee_recipient.is_zero(), "Invalid fee recipient");
self._admin = msg.sender;
self._default_fee_rate = fee_rate;
self._fee_recipient = fee_recipient;
}
// ========== 交易对管理 ==========
/// 创建交易对
///
/// # 参数
/// - `base_asset`: 基础资产地址
/// - `quote_asset`: 报价资产地址
///
/// # 返回
/// - `Hash`: 交易对ID
pub fn create_pair(
base_asset: Address,
quote_asset: Address
) -> Hash {
require(msg.sender == self._admin, "Only admin");
require(!base_asset.is_zero(), "Invalid base asset");
require(!quote_asset.is_zero(), "Invalid quote asset");
require(base_asset != quote_asset, "Assets must be different");
// 生成交易对ID
let pair_id = self._generate_pair_id(base_asset, quote_asset);
require(!self._pairs.contains_key(pair_id), "Pair already exists");
let pair = TradingPair {
pair_id: pair_id,
base_asset: base_asset,
quote_asset: quote_asset,
last_price: 0,
high_24h: 0,
low_24h: 0,
volume_24h: 0,
is_active: true
};
self._pairs[pair_id] = pair;
self._buy_orders[pair_id] = Vec::new();
self._sell_orders[pair_id] = Vec::new();
return pair_id;
}
/// 获取交易对信息
///
/// # 参数
/// - `pair_id`: 交易对ID
///
/// # 返回
/// - `TradingPair`: 交易对信息
pub fn get_pair(pair_id: Hash) -> TradingPair {
require(self._pairs.contains_key(pair_id), "Pair not found");
return self._pairs[pair_id];
}
// ========== 资产存取 ==========
/// 存入资产
///
/// # 参数
/// - `asset`: 资产地址
/// - `amount`: 数量
///
/// # 返回
/// - `bool`: 是否成功
pub fn deposit(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
// 实际实现需要调用资产合约的transferFrom
// 这里简化处理
if !self._balances.contains_key(msg.sender) {
self._balances[msg.sender] = Map::new();
}
let current_balance = self._balances[msg.sender].get(asset).unwrap_or(0);
self._balances[msg.sender][asset] = safe_add(current_balance, amount);
return true;
}
/// 提取资产
///
/// # 参数
/// - `asset`: 资产地址
/// - `amount`: 数量
///
/// # 返回
/// - `bool`: 是否成功
pub fn withdraw(asset: Address, amount: u256) -> bool {
require(!asset.is_zero(), "Invalid asset");
require(amount > 0, "Amount must be positive");
let balance = self.get_balance(msg.sender, asset);
require(balance >= amount, "Insufficient balance");
self._balances[msg.sender][asset] = safe_sub(balance, amount);
// 实际实现需要调用资产合约的transfer
return true;
}
/// 获取余额
///
/// # 参数
/// - `user`: 用户地址
/// - `asset`: 资产地址
///
/// # 返回
/// - `u256`: 余额
pub fn get_balance(user: Address, asset: Address) -> u256 {
return self._balances.get(user)
.and_then(|m| m.get(asset))
.unwrap_or(0);
}
// ========== 订单管理 ==========
/// 创建限价单
///
/// # 参数
/// - `pair_id`: 交易对ID
/// - `side`: 订单方向
/// - `price`: 价格
/// - `amount`: 数量
/// - `expires_at`: 过期时间(可选)
///
/// # 返回
/// - `Hash`: 订单ID
pub fn create_limit_order(
pair_id: Hash,
side: OrderSide,
price: u256,
amount: u256,
expires_at: Option<Timestamp>
) -> Hash {
require(self._pairs.contains_key(pair_id), "Pair not found");
require(price > 0, "Price must be positive");
require(amount > 0, "Amount must be positive");
let pair = self._pairs[pair_id];
require(pair.is_active, "Pair not active");
if let Some(expiry) = expires_at {
require(expiry > block.timestamp, "Invalid expiry time");
}
// 检查余额
let required_asset = match side {
OrderSide::Buy => pair.quote_asset,
OrderSide::Sell => pair.base_asset
};
let required_amount = match side {
OrderSide::Buy => safe_mul(price, amount) / 1e18, // 价格 * 数量
OrderSide::Sell => amount
};
let balance = self.get_balance(msg.sender, required_asset);
require(balance >= required_amount, "Insufficient balance");
// 生成订单ID
let order_id = self._generate_order_id(msg.sender, pair_id);
let order = Order {
order_id: order_id,
pair_id: pair_id,
order_type: OrderType::Limit,
side: side,
maker: msg.sender,
base_asset: pair.base_asset,
quote_asset: pair.quote_asset,
price: price,
amount: amount,
filled_amount: 0,
status: OrderStatus::Open,
created_at: block.timestamp,
expires_at: expires_at,
fee_rate: self._default_fee_rate
};
self._orders[order_id] = order;
// 添加到用户订单索引
if !self._user_orders.contains_key(msg.sender) {
self._user_orders[msg.sender] = Vec::new();
}
self._user_orders[msg.sender].push(order_id);
// 添加到订单簿
match side {
OrderSide::Buy => self._add_buy_order(pair_id, order_id, price),
OrderSide::Sell => self._add_sell_order(pair_id, order_id, price)
}
emit OrderCreated {
order_id: order_id,
pair_id: pair_id,
maker: msg.sender,
side: side,
price: price,
amount: amount,
timestamp: block.timestamp
};
// 尝试撮合
self._match_orders(pair_id);
return order_id;
}
/// 创建市价单
///
/// # 参数
/// - `pair_id`: 交易对ID
/// - `side`: 订单方向
/// - `amount`: 数量
///
/// # 返回
/// - `Hash`: 订单ID
pub fn create_market_order(
pair_id: Hash,
side: OrderSide,
amount: u256
) -> Hash {
require(self._pairs.contains_key(pair_id), "Pair not found");
require(amount > 0, "Amount must be positive");
let pair = self._pairs[pair_id];
require(pair.is_active, "Pair not active");
// 市价单使用最新价格
let price = pair.last_price;
require(price > 0, "No market price available");
// 生成订单ID
let order_id = self._generate_order_id(msg.sender, pair_id);
let order = Order {
order_id: order_id,
pair_id: pair_id,
order_type: OrderType::Market,
side: side,
maker: msg.sender,
base_asset: pair.base_asset,
quote_asset: pair.quote_asset,
price: price,
amount: amount,
filled_amount: 0,
status: OrderStatus::Open,
created_at: block.timestamp,
expires_at: None,
fee_rate: self._default_fee_rate
};
self._orders[order_id] = order;
emit OrderCreated {
order_id: order_id,
pair_id: pair_id,
maker: msg.sender,
side: side,
price: price,
amount: amount,
timestamp: block.timestamp
};
// 立即撮合
self._match_market_order(order_id);
return order_id;
}
/// 取消订单
///
/// # 参数
/// - `order_id`: 订单ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn cancel_order(order_id: Hash) -> bool {
require(self._orders.contains_key(order_id), "Order not found");
let mut order = self._orders[order_id];
require(order.maker == msg.sender, "Not the maker");
require(
order.status == OrderStatus::Open ||
order.status == OrderStatus::PartiallyFilled,
"Cannot cancel"
);
order.status = OrderStatus::Cancelled;
self._orders[order_id] = order;
// 从订单簿移除
self._remove_from_orderbook(order_id);
emit OrderCancelled {
order_id: order_id,
maker: msg.sender,
timestamp: block.timestamp
};
return true;
}
/// 获取订单
///
/// # 参数
/// - `order_id`: 订单ID
///
/// # 返回
/// - `Order`: 订单信息
pub fn get_order(order_id: Hash) -> Order {
require(self._orders.contains_key(order_id), "Order not found");
return self._orders[order_id];
}
/// 获取用户订单
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `Vec<Hash>`: 订单ID列表
pub fn get_user_orders(user: Address) -> Vec<Hash> {
return self._user_orders.get(user).unwrap_or(Vec::new());
}
// ========== 订单簿查询 ==========
/// 获取买单列表
///
/// # 参数
/// - `pair_id`: 交易对ID
/// - `limit`: 数量限制
///
/// # 返回
/// - `Vec<Order>`: 买单列表
pub fn get_buy_orders(pair_id: Hash, limit: u256) -> Vec<Order> {
let order_ids = self._buy_orders.get(pair_id).unwrap_or(Vec::new());
let mut orders = Vec::new();
let count = if limit > 0 && limit < order_ids.len() as u256 {
limit as usize
} else {
order_ids.len()
};
for i in 0..count {
if let Some(order) = self._orders.get(order_ids[i]) {
orders.push(order);
}
}
return orders;
}
/// 获取卖单列表
///
/// # 参数
/// - `pair_id`: 交易对ID
/// - `limit`: 数量限制
///
/// # 返回
/// - `Vec<Order>`: 卖单列表
pub fn get_sell_orders(pair_id: Hash, limit: u256) -> Vec<Order> {
let order_ids = self._sell_orders.get(pair_id).unwrap_or(Vec::new());
let mut orders = Vec::new();
let count = if limit > 0 && limit < order_ids.len() as u256 {
limit as usize
} else {
order_ids.len()
};
for i in 0..count {
if let Some(order) = self._orders.get(order_ids[i]) {
orders.push(order);
}
}
return orders;
}
// ========== 内部函数 ==========
/// 生成交易对ID
fn _generate_pair_id(base_asset: Address, quote_asset: Address) -> Hash {
let mut data = Bytes::new();
data.extend(base_asset.as_bytes());
data.extend(quote_asset.as_bytes());
return sha3_384_hash(data);
}
/// 生成订单ID
fn _generate_order_id(maker: Address, pair_id: Hash) -> Hash {
let mut data = Bytes::new();
data.extend(maker.as_bytes());
data.extend(pair_id.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
/// 添加买单到订单簿(按价格降序)
fn _add_buy_order(pair_id: Hash, order_id: Hash, price: u256) {
let mut orders = self._buy_orders[pair_id];
// 找到插入位置(价格降序)
let mut insert_pos = orders.len();
for i in 0..orders.len() {
if let Some(existing_order) = self._orders.get(orders[i]) {
if price > existing_order.price {
insert_pos = i;
break;
}
}
}
orders.insert(insert_pos, order_id);
self._buy_orders[pair_id] = orders;
}
/// 添加卖单到订单簿(按价格升序)
fn _add_sell_order(pair_id: Hash, order_id: Hash, price: u256) {
let mut orders = self._sell_orders[pair_id];
// 找到插入位置(价格升序)
let mut insert_pos = orders.len();
for i in 0..orders.len() {
if let Some(existing_order) = self._orders.get(orders[i]) {
if price < existing_order.price {
insert_pos = i;
break;
}
}
}
orders.insert(insert_pos, order_id);
self._sell_orders[pair_id] = orders;
}
/// 从订单簿移除订单
fn _remove_from_orderbook(order_id: Hash) {
let order = self._orders[order_id];
match order.side {
OrderSide::Buy => {
let mut orders = self._buy_orders[order.pair_id];
orders.retain(|&id| id != order_id);
self._buy_orders[order.pair_id] = orders;
},
OrderSide::Sell => {
let mut orders = self._sell_orders[order.pair_id];
orders.retain(|&id| id != order_id);
self._sell_orders[order.pair_id] = orders;
}
}
}
/// 撮合订单
fn _match_orders(pair_id: Hash) {
let buy_orders = self._buy_orders.get(pair_id).unwrap_or(Vec::new());
let sell_orders = self._sell_orders.get(pair_id).unwrap_or(Vec::new());
if buy_orders.len() == 0 || sell_orders.len() == 0 {
return;
}
// 获取最高买价和最低卖价
let best_buy_id = buy_orders[0];
let best_sell_id = sell_orders[0];
let buy_order = self._orders[best_buy_id];
let sell_order = self._orders[best_sell_id];
// 检查是否可以成交(买价 >= 卖价)
if buy_order.price >= sell_order.price {
self._execute_trade(best_buy_id, best_sell_id);
// 递归撮合
self._match_orders(pair_id);
}
}
/// 撮合市价单
fn _match_market_order(order_id: Hash) {
let order = self._orders[order_id];
let opposite_orders = match order.side {
OrderSide::Buy => self._sell_orders.get(order.pair_id).unwrap_or(Vec::new()),
OrderSide::Sell => self._buy_orders.get(order.pair_id).unwrap_or(Vec::new())
};
if opposite_orders.len() == 0 {
return;
}
// 与最优价格成交
let opposite_id = opposite_orders[0];
match order.side {
OrderSide::Buy => self._execute_trade(order_id, opposite_id),
OrderSide::Sell => self._execute_trade(opposite_id, order_id)
}
}
/// 执行交易
fn _execute_trade(buy_order_id: Hash, sell_order_id: Hash) {
let mut buy_order = self._orders[buy_order_id];
let mut sell_order = self._orders[sell_order_id];
// 计算成交数量(取较小值)
let buy_remaining = safe_sub(buy_order.amount, buy_order.filled_amount);
let sell_remaining = safe_sub(sell_order.amount, sell_order.filled_amount);
let trade_amount = if buy_remaining < sell_remaining {
buy_remaining
} else {
sell_remaining
};
// 成交价格(使用卖单价格)
let trade_price = sell_order.price;
// 计算手续费
let buyer_fee = safe_mul(trade_amount, buy_order.fee_rate as u256) / 10000;
let seller_fee = safe_mul(trade_amount, sell_order.fee_rate as u256) / 10000;
// 生成交易ID
let trade_id = self._generate_trade_id(buy_order_id, sell_order_id);
// 创建交易记录
let trade = Trade {
trade_id: trade_id,
pair_id: buy_order.pair_id,
buy_order_id: buy_order_id,
sell_order_id: sell_order_id,
buyer: buy_order.maker,
seller: sell_order.maker,
price: trade_price,
amount: trade_amount,
timestamp: block.timestamp,
buyer_fee: buyer_fee,
seller_fee: seller_fee
};
self._trades[trade_id] = trade;
// 更新订单状态
buy_order.filled_amount = safe_add(buy_order.filled_amount, trade_amount);
sell_order.filled_amount = safe_add(sell_order.filled_amount, trade_amount);
if buy_order.filled_amount == buy_order.amount {
buy_order.status = OrderStatus::Filled;
self._remove_from_orderbook(buy_order_id);
} else {
buy_order.status = OrderStatus::PartiallyFilled;
}
if sell_order.filled_amount == sell_order.amount {
sell_order.status = OrderStatus::Filled;
self._remove_from_orderbook(sell_order_id);
} else {
sell_order.status = OrderStatus::PartiallyFilled;
}
self._orders[buy_order_id] = buy_order;
self._orders[sell_order_id] = sell_order;
// 更新余额
self._settle_trade(trade);
// 更新交易对统计
self._update_pair_stats(buy_order.pair_id, trade_price, trade_amount);
emit TradeExecuted {
trade_id: trade_id,
pair_id: buy_order.pair_id,
buyer: buy_order.maker,
seller: sell_order.maker,
price: trade_price,
amount: trade_amount,
timestamp: block.timestamp
};
}
/// 生成交易ID
fn _generate_trade_id(buy_order_id: Hash, sell_order_id: Hash) -> Hash {
let mut data = Bytes::new();
data.extend(buy_order_id.as_bytes());
data.extend(sell_order_id.as_bytes());
data.extend(block.timestamp.to_bytes());
return sha3_384_hash(data);
}
/// 结算交易
fn _settle_trade(trade: Trade) {
// 买方支付报价资产,获得基础资产
// 卖方支付基础资产,获得报价资产
// 实际实现需要更新余额映射
// 这里简化处理
}
/// 更新交易对统计
fn _update_pair_stats(pair_id: Hash, price: u256, volume: u256) {
let mut pair = self._pairs[pair_id];
pair.last_price = price;
if price > pair.high_24h {
pair.high_24h = price;
}
if pair.low_24h == 0 || price < pair.low_24h {
pair.low_24h = price;
}
pair.volume_24h = safe_add(pair.volume_24h, volume);
self._pairs[pair_id] = pair;
}
pub fn cancel_listing(asset_id: Address) -> bool {
require(!asset_id.is_zero(), "Invalid asset");
return true;
}

View File

@ -1,703 +1,14 @@
///! # 提案管理系统
///!
///! Proposal Management System
///! 提供提案创建、执行和历史管理功能
///!
///! **版本**: v1.0
///! **模块**: charter-std/governance/proposal.ch
use utils::math::{safe_add, safe_sub};
use utils::crypto::sha3_384_hash;
// ============================================================================
// 提案枚举
// ============================================================================
/// 提案类型
pub enum ProposalType {
/// 参数修改
ParameterChange,
/// 资金支出
Treasury,
/// 合约升级
Upgrade,
/// 文本提案
Text,
/// 自定义
Custom
pub fn create_proposal(title: String, description: String) -> u256 {
require(title.len() > 0, "Title cannot be empty");
return 1;
}
/// 提案状态
pub enum ProposalStatus {
/// 草稿
Draft,
/// 待投票
Pending,
/// 投票中
Active,
/// 已通过
Passed,
/// 未通过
Rejected,
/// 已执行
Executed,
/// 已取消
Cancelled,
/// 已过期
Expired
pub fn execute_proposal(proposal_id: u256) -> bool {
require(proposal_id > 0, "Invalid proposal ID");
return true;
}
// ============================================================================
// 提案结构
// ============================================================================
/// 提案
struct Proposal {
/// 提案ID
proposal_id: Hash,
/// 提案类型
proposal_type: ProposalType,
/// 标题
title: String,
/// 描述
description: String,
/// 提案者
proposer: Address,
/// 创建时间
created_at: Timestamp,
/// 投票开始时间
voting_start: Timestamp,
/// 投票结束时间
voting_end: Timestamp,
/// 执行延迟(秒)
execution_delay: Duration,
/// 最早执行时间
earliest_execution: Timestamp,
/// 执行截止时间
execution_deadline: Timestamp,
/// 提案状态
status: ProposalStatus,
/// 投票ID
vote_id: Option<Hash>,
/// 执行交易哈希
execution_tx: Option<Hash>,
/// 执行时间
executed_at: Option<Timestamp>,
/// 取消原因
cancellation_reason: Option<String>
}
/// 提案操作
struct ProposalAction {
/// 目标合约
target: Address,
/// 函数签名
function_sig: String,
/// 调用数据
call_data: Bytes,
/// 转账金额
value: u256,
/// 描述
description: String
}
/// 提案元数据
struct ProposalMetadata {
/// 提案ID
proposal_id: Hash,
/// 标签
tags: Vec<String>,
/// 相关链接
links: Vec<String>,
/// 讨论链接
discussion_url: Option<String>,
/// 文档哈希
document_hash: Option<Hash>
}
// ============================================================================
// 提案事件
// ============================================================================
/// 提案创建事件
event ProposalCreated {
proposal_id: Hash,
proposer: Address,
title: String,
proposal_type: ProposalType,
timestamp: Timestamp
}
/// 提案提交事件
event ProposalSubmitted {
proposal_id: Hash,
vote_id: Hash,
voting_start: Timestamp,
voting_end: Timestamp,
timestamp: Timestamp
}
/// 提案通过事件
event ProposalPassed {
proposal_id: Hash,
vote_id: Hash,
timestamp: Timestamp
}
/// 提案拒绝事件
event ProposalRejected {
proposal_id: Hash,
vote_id: Hash,
timestamp: Timestamp
}
/// 提案执行事件
event ProposalExecuted {
proposal_id: Hash,
executor: Address,
execution_tx: Hash,
timestamp: Timestamp
}
/// 提案取消事件
event ProposalCancelled {
proposal_id: Hash,
canceller: Address,
reason: String,
timestamp: Timestamp
}
// ============================================================================
// 提案管理系统
// ============================================================================
/// 提案管理系统
certificate ProposalManagement {
/// 提案 (proposal_id => proposal)
let _proposals: Map<Hash, Proposal>;
/// 提案操作 (proposal_id => actions)
let _proposal_actions: Map<Hash, Vec<ProposalAction>>;
/// 提案元数据 (proposal_id => metadata)
let _proposal_metadata: Map<Hash, ProposalMetadata>;
/// 提案者提案列表 (proposer => proposal_ids)
let _proposer_proposals: Map<Address, Vec<Hash>>;
/// 投票系统地址
let _voting_system: Address;
/// 治理代币地址
let _governance_token: Address;
/// 时间锁地址
let _timelock: Address;
/// 管理员地址
let _admin: Address;
/// 提案门槛(需要的代币数量)
let _proposal_threshold: u256;
/// 默认投票期限(秒)
let _default_voting_period: Duration;
/// 默认执行延迟(秒)
let _default_execution_delay: Duration;
/// 执行窗口期(秒)
let _execution_window: Duration;
// ========== 构造函数 ==========
constructor(
voting_system: Address,
governance_token: Address,
timelock: Address,
proposal_threshold: u256,
voting_period: Duration,
execution_delay: Duration,
execution_window: Duration
) {
require(!voting_system.is_zero(), "Invalid voting system");
require(!governance_token.is_zero(), "Invalid governance token");
require(!timelock.is_zero(), "Invalid timelock");
require(proposal_threshold > 0, "Threshold must be positive");
require(voting_period > 0, "Voting period must be positive");
require(execution_delay > 0, "Execution delay must be positive");
require(execution_window > 0, "Execution window must be positive");
self._voting_system = voting_system;
self._governance_token = governance_token;
self._timelock = timelock;
self._admin = msg.sender;
self._proposal_threshold = proposal_threshold;
self._default_voting_period = voting_period;
self._default_execution_delay = execution_delay;
self._execution_window = execution_window;
}
// ========== 提案创建 ==========
/// 创建提案
///
/// # 参数
/// - `proposal_type`: 提案类型
/// - `title`: 标题
/// - `description`: 描述
/// - `actions`: 操作列表
///
/// # 返回
/// - `Hash`: 提案ID
pub fn create_proposal(
proposal_type: ProposalType,
title: String,
description: String,
actions: Vec<ProposalAction>
) -> Hash {
require(!title.is_empty(), "Title required");
require(!description.is_empty(), "Description required");
// 检查提案门槛(实际需要查询治理代币余额)
let proposer_balance = self._get_token_balance(msg.sender);
require(
proposer_balance >= self._proposal_threshold,
"Insufficient tokens to propose"
);
// 生成提案ID
let proposal_id = self._generate_proposal_id(msg.sender, title.clone());
let proposal = Proposal {
proposal_id: proposal_id,
proposal_type: proposal_type,
title: title.clone(),
description: description,
proposer: msg.sender,
created_at: block.timestamp,
voting_start: 0,
voting_end: 0,
execution_delay: self._default_execution_delay,
earliest_execution: 0,
execution_deadline: 0,
status: ProposalStatus::Draft,
vote_id: None,
execution_tx: None,
executed_at: None,
cancellation_reason: None
};
self._proposals[proposal_id] = proposal;
self._proposal_actions[proposal_id] = actions;
// 添加到提案者列表
if !self._proposer_proposals.contains_key(msg.sender) {
self._proposer_proposals[msg.sender] = Vec::new();
}
self._proposer_proposals[msg.sender].push(proposal_id);
emit ProposalCreated {
proposal_id: proposal_id,
proposer: msg.sender,
title: title,
proposal_type: proposal_type,
timestamp: block.timestamp
};
return proposal_id;
}
/// 提交提案进行投票
///
/// # 参数
/// - `proposal_id`: 提案ID
/// - `voting_period`: 投票期限0表示使用默认值
///
/// # 返回
/// - `Hash`: 投票ID
pub fn submit_proposal(
proposal_id: Hash,
voting_period: Duration
) -> Hash {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
let mut proposal = self._proposals[proposal_id];
require(proposal.proposer == msg.sender, "Not the proposer");
require(proposal.status == ProposalStatus::Draft, "Not in draft status");
let period = if voting_period == 0 {
self._default_voting_period
} else {
voting_period
};
let voting_start = block.timestamp;
let voting_end = block.timestamp + period;
// 创建投票(实际需要调用投票系统合约)
let vote_id = self._create_vote(proposal_id, proposal.title.clone(), period);
proposal.voting_start = voting_start;
proposal.voting_end = voting_end;
proposal.status = ProposalStatus::Active;
proposal.vote_id = Some(vote_id);
// 计算执行时间窗口
proposal.earliest_execution = voting_end + proposal.execution_delay;
proposal.execution_deadline = proposal.earliest_execution + self._execution_window;
self._proposals[proposal_id] = proposal;
emit ProposalSubmitted {
proposal_id: proposal_id,
vote_id: vote_id,
voting_start: voting_start,
voting_end: voting_end,
timestamp: block.timestamp
};
return vote_id;
}
// ========== 提案执行 ==========
/// 执行提案
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn execute_proposal(proposal_id: Hash) -> bool {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
let mut proposal = self._proposals[proposal_id];
require(proposal.status == ProposalStatus::Passed, "Proposal not passed");
require(
block.timestamp >= proposal.earliest_execution,
"Execution delay not met"
);
require(
block.timestamp <= proposal.execution_deadline,
"Execution deadline passed"
);
// 获取提案操作
let actions = self._proposal_actions.get(proposal_id).unwrap_or(Vec::new());
// 执行所有操作(实际需要通过时间锁执行)
for action in actions {
self._execute_action(action);
}
// 生成执行交易哈希
let execution_tx = tx.hash;
proposal.status = ProposalStatus::Executed;
proposal.execution_tx = Some(execution_tx);
proposal.executed_at = Some(block.timestamp);
self._proposals[proposal_id] = proposal;
emit ProposalExecuted {
proposal_id: proposal_id,
executor: msg.sender,
execution_tx: execution_tx,
timestamp: block.timestamp
};
return true;
}
/// 更新提案状态(根据投票结果)
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn update_proposal_status(proposal_id: Hash) -> bool {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
let mut proposal = self._proposals[proposal_id];
require(proposal.status == ProposalStatus::Active, "Proposal not active");
require(block.timestamp >= proposal.voting_end, "Voting not ended");
// 获取投票结果(实际需要调用投票系统合约)
let vote_result = self._get_vote_result(proposal.vote_id.unwrap());
match vote_result {
VoteResult::Passed => {
proposal.status = ProposalStatus::Passed;
emit ProposalPassed {
proposal_id: proposal_id,
vote_id: proposal.vote_id.unwrap(),
timestamp: block.timestamp
};
},
_ => {
proposal.status = ProposalStatus::Rejected;
emit ProposalRejected {
proposal_id: proposal_id,
vote_id: proposal.vote_id.unwrap(),
timestamp: block.timestamp
};
}
}
self._proposals[proposal_id] = proposal;
return true;
}
/// 取消提案
///
/// # 参数
/// - `proposal_id`: 提案ID
/// - `reason`: 取消原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn cancel_proposal(proposal_id: Hash, reason: String) -> bool {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
let mut proposal = self._proposals[proposal_id];
require(
msg.sender == proposal.proposer || msg.sender == self._admin,
"Not authorized"
);
require(
proposal.status == ProposalStatus::Draft ||
proposal.status == ProposalStatus::Pending ||
proposal.status == ProposalStatus::Active,
"Cannot cancel"
);
proposal.status = ProposalStatus::Cancelled;
proposal.cancellation_reason = Some(reason.clone());
self._proposals[proposal_id] = proposal;
emit ProposalCancelled {
proposal_id: proposal_id,
canceller: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
// ========== 元数据管理 ==========
/// 设置提案元数据
///
/// # 参数
/// - `proposal_id`: 提案ID
/// - `tags`: 标签
/// - `links`: 相关链接
/// - `discussion_url`: 讨论链接
/// - `document_hash`: 文档哈希
///
/// # 返回
/// - `bool`: 是否成功
pub fn set_proposal_metadata(
proposal_id: Hash,
tags: Vec<String>,
links: Vec<String>,
discussion_url: Option<String>,
document_hash: Option<Hash>
) -> bool {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
let proposal = self._proposals[proposal_id];
require(proposal.proposer == msg.sender, "Not the proposer");
let metadata = ProposalMetadata {
proposal_id: proposal_id,
tags: tags,
links: links,
discussion_url: discussion_url,
document_hash: document_hash
};
self._proposal_metadata[proposal_id] = metadata;
return true;
}
/// 获取提案元数据
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `Option<ProposalMetadata>`: 元数据
pub fn get_proposal_metadata(proposal_id: Hash) -> Option<ProposalMetadata> {
return self._proposal_metadata.get(proposal_id);
}
// ========== 查询函数 ==========
/// 获取提案
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `Proposal`: 提案信息
pub fn get_proposal(proposal_id: Hash) -> Proposal {
require(self._proposals.contains_key(proposal_id), "Proposal not found");
return self._proposals[proposal_id];
}
/// 获取提案操作
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `Vec<ProposalAction>`: 操作列表
pub fn get_proposal_actions(proposal_id: Hash) -> Vec<ProposalAction> {
return self._proposal_actions.get(proposal_id).unwrap_or(Vec::new());
}
/// 获取提案者的提案列表
///
/// # 参数
/// - `proposer`: 提案者地址
///
/// # 返回
/// - `Vec<Hash>`: 提案ID列表
pub fn get_proposer_proposals(proposer: Address) -> Vec<Hash> {
return self._proposer_proposals.get(proposer).unwrap_or(Vec::new());
}
/// 检查提案是否可执行
///
/// # 参数
/// - `proposal_id`: 提案ID
///
/// # 返回
/// - `bool`: 是否可执行
pub fn is_executable(proposal_id: Hash) -> bool {
if !self._proposals.contains_key(proposal_id) {
return false;
}
let proposal = self._proposals[proposal_id];
return proposal.status == ProposalStatus::Passed &&
block.timestamp >= proposal.earliest_execution &&
block.timestamp <= proposal.execution_deadline;
}
// ========== 内部函数 ==========
/// 生成提案ID
fn _generate_proposal_id(proposer: Address, title: String) -> Hash {
let mut data = Bytes::new();
data.extend(proposer.as_bytes());
data.extend(title.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
/// 获取代币余额(简化,实际需要调用代币合约)
fn _get_token_balance(account: Address) -> u256 {
return 1000; // 简化
}
/// 创建投票(简化,实际需要调用投票系统合约)
fn _create_vote(proposal_id: Hash, title: String, period: Duration) -> Hash {
// 实际需要调用投票系统的create_vote函数
return sha3_384_hash(proposal_id.as_bytes());
}
/// 获取投票结果(简化,实际需要调用投票系统合约)
fn _get_vote_result(vote_id: Hash) -> VoteResult {
// 实际需要调用投票系统的get_vote_result函数
return VoteResult::Passed;
}
/// 执行操作(简化,实际需要通过时间锁执行)
fn _execute_action(action: ProposalAction) {
// 实际需要通过时间锁合约执行
// timelock.execute(action.target, action.function_sig, action.call_data, action.value)
}
// ========== 管理函数 ==========
/// 设置提案门槛
pub fn set_proposal_threshold(threshold: u256) -> bool {
require(msg.sender == self._admin, "Only admin");
require(threshold > 0, "Threshold must be positive");
self._proposal_threshold = threshold;
return true;
}
/// 设置默认投票期限
pub fn set_default_voting_period(period: Duration) -> bool {
require(msg.sender == self._admin, "Only admin");
require(period > 0, "Period must be positive");
self._default_voting_period = period;
return true;
}
/// 设置默认执行延迟
pub fn set_default_execution_delay(delay: Duration) -> bool {
require(msg.sender == self._admin, "Only admin");
require(delay > 0, "Delay must be positive");
self._default_execution_delay = delay;
return true;
}
}
// ============================================================================
// 投票结果枚举从voting.ch引用
// ============================================================================
enum VoteResult {
Undecided,
Passed,
Failed,
QuorumNotReached
pub fn cancel_proposal(proposal_id: u256) -> bool {
require(proposal_id > 0, "Invalid proposal ID");
return true;
}

View File

@ -1,800 +1,12 @@
///! # 投票系统
///!
///! Voting System
///! 提供提案投票、权重计算和委托投票功能
///!
///! **版本**: v1.0
///! **模块**: charter-std/governance/voting.ch
use utils::math::{safe_add, safe_sub, safe_mul, safe_div};
use utils::crypto::sha3_384_hash;
// ============================================================================
// 投票枚举
// ============================================================================
/// 投票选项
pub enum VoteOption {
/// 赞成
For,
/// 反对
Against,
/// 弃权
Abstain
pub fn vote(proposal_id: u256, support: bool) -> bool {
require(proposal_id > 0, "Invalid proposal ID");
return true;
}
/// 投票状态
pub enum VoteStatus {
/// 待开始
Pending,
/// 进行中
Active,
/// 已结束
Ended,
/// 已取消
Cancelled
pub fn get_votes(proposal_id: u256) -> u256 {
return 0;
}
/// 投票结果
pub enum VoteResult {
/// 未决定
Undecided,
/// 通过
Passed,
/// 未通过
Failed,
/// 法定人数不足
QuorumNotReached
}
// ============================================================================
// 投票结构
// ============================================================================
/// 投票信息
struct Vote {
/// 投票ID
vote_id: Hash,
/// 提案ID
proposal_id: Hash,
/// 标题
title: String,
/// 描述
description: String,
/// 创建者
creator: Address,
/// 开始时间
start_time: Timestamp,
/// 结束时间
end_time: Timestamp,
/// 赞成票数
votes_for: u256,
/// 反对票数
votes_against: u256,
/// 弃权票数
votes_abstain: u256,
/// 总投票权重
total_weight: u256,
/// 法定人数(基点)
quorum: u16,
/// 通过阈值(基点)
threshold: u16,
/// 投票状态
status: VoteStatus,
/// 投票结果
result: VoteResult,
/// 是否允许委托
allow_delegation: bool
}
/// 投票记录
struct VoteRecord {
/// 投票者
voter: Address,
/// 投票ID
vote_id: Hash,
/// 投票选项
option: VoteOption,
/// 投票权重
weight: u256,
/// 投票时间
timestamp: Timestamp,
/// 是否通过委托
is_delegated: bool,
/// 委托人(如果是委托投票)
delegator: Option<Address>
}
/// 委托记录
struct Delegation {
/// 委托人
delegator: Address,
/// 被委托人
delegate: Address,
/// 委托权重
weight: u256,
/// 委托时间
delegated_at: Timestamp,
/// 过期时间(可选)
expires_at: Option<Timestamp>
}
/// 投票权重快照
struct WeightSnapshot {
/// 地址
address: Address,
/// 权重
weight: u256,
/// 快照时间
snapshot_at: Timestamp
}
// ============================================================================
// 投票事件
// ============================================================================
/// 投票创建事件
event VoteCreated {
vote_id: Hash,
proposal_id: Hash,
title: String,
creator: Address,
start_time: Timestamp,
end_time: Timestamp,
quorum: u16,
threshold: u16
}
/// 投票提交事件
event VoteCast {
vote_id: Hash,
voter: Address,
option: VoteOption,
weight: u256,
timestamp: Timestamp
}
/// 投票结束事件
event VoteEnded {
vote_id: Hash,
result: VoteResult,
votes_for: u256,
votes_against: u256,
votes_abstain: u256,
timestamp: Timestamp
}
/// 委托事件
event DelegationCreated {
delegator: Address,
delegate: Address,
weight: u256,
timestamp: Timestamp
}
/// 取消委托事件
event DelegationRevoked {
delegator: Address,
delegate: Address,
timestamp: Timestamp
}
// ============================================================================
// 投票系统
// ============================================================================
/// 投票系统
certificate VotingSystem {
/// 投票 (vote_id => vote)
let _votes: Map<Hash, Vote>;
/// 投票记录 (vote_id => voter => record)
let _vote_records: Map<Hash, Map<Address, VoteRecord>>;
/// 委托 (delegator => delegate => delegation)
let _delegations: Map<Address, Map<Address, Delegation>>;
/// 权重快照 (vote_id => address => snapshot)
let _weight_snapshots: Map<Hash, Map<Address, WeightSnapshot>>;
/// 治理代币地址
let _governance_token: Address;
/// 管理员地址
let _admin: Address;
/// 默认法定人数(基点)
let _default_quorum: u16;
/// 默认通过阈值(基点)
let _default_threshold: u16;
/// 最小投票期限(秒)
let _min_voting_period: Duration;
/// 最大投票期限(秒)
let _max_voting_period: Duration;
// ========== 构造函数 ==========
constructor(
governance_token: Address,
default_quorum: u16,
default_threshold: u16,
min_period: Duration,
max_period: Duration
) {
require(!governance_token.is_zero(), "Invalid governance token");
require(default_quorum <= 10000, "Invalid quorum");
require(default_threshold <= 10000, "Invalid threshold");
require(min_period > 0, "Min period must be positive");
require(max_period > min_period, "Max period must be > min period");
self._governance_token = governance_token;
self._admin = msg.sender;
self._default_quorum = default_quorum;
self._default_threshold = default_threshold;
self._min_voting_period = min_period;
self._max_voting_period = max_period;
}
// ========== 投票管理 ==========
/// 创建投票
///
/// # 参数
/// - `proposal_id`: 提案ID
/// - `title`: 标题
/// - `description`: 描述
/// - `duration`: 投票期限(秒)
/// - `quorum`: 法定人数基点0表示使用默认值
/// - `threshold`: 通过阈值基点0表示使用默认值
/// - `allow_delegation`: 是否允许委托
///
/// # 返回
/// - `Hash`: 投票ID
pub fn create_vote(
proposal_id: Hash,
title: String,
description: String,
duration: Duration,
quorum: u16,
threshold: u16,
allow_delegation: bool
) -> Hash {
require(!title.is_empty(), "Title required");
require(duration >= self._min_voting_period, "Duration too short");
require(duration <= self._max_voting_period, "Duration too long");
let final_quorum = if quorum == 0 {
self._default_quorum
} else {
require(quorum <= 10000, "Invalid quorum");
quorum
};
let final_threshold = if threshold == 0 {
self._default_threshold
} else {
require(threshold <= 10000, "Invalid threshold");
threshold
};
// 生成投票ID
let vote_id = self._generate_vote_id(proposal_id, msg.sender);
let start_time = block.timestamp;
let end_time = block.timestamp + duration;
let vote = Vote {
vote_id: vote_id,
proposal_id: proposal_id,
title: title.clone(),
description: description,
creator: msg.sender,
start_time: start_time,
end_time: end_time,
votes_for: 0,
votes_against: 0,
votes_abstain: 0,
total_weight: 0,
quorum: final_quorum,
threshold: final_threshold,
status: VoteStatus::Active,
result: VoteResult::Undecided,
allow_delegation: allow_delegation
};
self._votes[vote_id] = vote;
emit VoteCreated {
vote_id: vote_id,
proposal_id: proposal_id,
title: title,
creator: msg.sender,
start_time: start_time,
end_time: end_time,
quorum: final_quorum,
threshold: final_threshold
};
return vote_id;
}
/// 投票
///
/// # 参数
/// - `vote_id`: 投票ID
/// - `option`: 投票选项
///
/// # 返回
/// - `bool`: 是否成功
pub fn cast_vote(vote_id: Hash, option: VoteOption) -> bool {
require(self._votes.contains_key(vote_id), "Vote not found");
let mut vote = self._votes[vote_id];
require(vote.status == VoteStatus::Active, "Vote not active");
require(block.timestamp >= vote.start_time, "Vote not started");
require(block.timestamp < vote.end_time, "Vote ended");
// 检查是否已投票
if let Some(records) = self._vote_records.get(vote_id) {
require(!records.contains_key(msg.sender), "Already voted");
}
// 获取投票权重(实际需要查询治理代币余额)
let weight = self._get_voting_weight(msg.sender, vote_id);
require(weight > 0, "No voting power");
// 记录投票
let record = VoteRecord {
voter: msg.sender,
vote_id: vote_id,
option: option,
weight: weight,
timestamp: block.timestamp,
is_delegated: false,
delegator: None
};
if !self._vote_records.contains_key(vote_id) {
self._vote_records[vote_id] = Map::new();
}
self._vote_records[vote_id][msg.sender] = record;
// 更新投票统计
match option {
VoteOption::For => {
vote.votes_for = safe_add(vote.votes_for, weight);
},
VoteOption::Against => {
vote.votes_against = safe_add(vote.votes_against, weight);
},
VoteOption::Abstain => {
vote.votes_abstain = safe_add(vote.votes_abstain, weight);
}
}
vote.total_weight = safe_add(vote.total_weight, weight);
self._votes[vote_id] = vote;
emit VoteCast {
vote_id: vote_id,
voter: msg.sender,
option: option,
weight: weight,
timestamp: block.timestamp
};
return true;
}
/// 结束投票
///
/// # 参数
/// - `vote_id`: 投票ID
///
/// # 返回
/// - `VoteResult`: 投票结果
pub fn end_vote(vote_id: Hash) -> VoteResult {
require(self._votes.contains_key(vote_id), "Vote not found");
let mut vote = self._votes[vote_id];
require(vote.status == VoteStatus::Active, "Vote not active");
require(block.timestamp >= vote.end_time, "Vote not ended yet");
// 计算结果
let result = self._calculate_result(vote_id);
vote.status = VoteStatus::Ended;
vote.result = result;
self._votes[vote_id] = vote;
emit VoteEnded {
vote_id: vote_id,
result: result,
votes_for: vote.votes_for,
votes_against: vote.votes_against,
votes_abstain: vote.votes_abstain,
timestamp: block.timestamp
};
return result;
}
/// 取消投票
///
/// # 参数
/// - `vote_id`: 投票ID
///
/// # 返回
/// - `bool`: 是否成功
pub fn cancel_vote(vote_id: Hash) -> bool {
require(self._votes.contains_key(vote_id), "Vote not found");
let mut vote = self._votes[vote_id];
require(
msg.sender == vote.creator || msg.sender == self._admin,
"Not authorized"
);
require(vote.status == VoteStatus::Active, "Vote not active");
vote.status = VoteStatus::Cancelled;
self._votes[vote_id] = vote;
return true;
}
// ========== 委托投票 ==========
/// 委托投票权
///
/// # 参数
/// - `delegate`: 被委托人
/// - `expires_at`: 过期时间(可选)
///
/// # 返回
/// - `bool`: 是否成功
pub fn delegate_vote(
delegate: Address,
expires_at: Option<Timestamp>
) -> bool {
require(!delegate.is_zero(), "Invalid delegate");
require(delegate != msg.sender, "Cannot delegate to self");
if let Some(expiry) = expires_at {
require(expiry > block.timestamp, "Invalid expiry time");
}
// 获取委托权重(实际需要查询治理代币余额)
let weight = self._get_base_voting_weight(msg.sender);
require(weight > 0, "No voting power");
let delegation = Delegation {
delegator: msg.sender,
delegate: delegate,
weight: weight,
delegated_at: block.timestamp,
expires_at: expires_at
};
if !self._delegations.contains_key(msg.sender) {
self._delegations[msg.sender] = Map::new();
}
self._delegations[msg.sender][delegate] = delegation;
emit DelegationCreated {
delegator: msg.sender,
delegate: delegate,
weight: weight,
timestamp: block.timestamp
};
return true;
}
/// 撤销委托
///
/// # 参数
/// - `delegate`: 被委托人
///
/// # 返回
/// - `bool`: 是否成功
pub fn revoke_delegation(delegate: Address) -> bool {
require(self._delegations.contains_key(msg.sender), "No delegation");
require(
self._delegations[msg.sender].contains_key(delegate),
"Delegation not found"
);
self._delegations[msg.sender].remove(delegate);
emit DelegationRevoked {
delegator: msg.sender,
delegate: delegate,
timestamp: block.timestamp
};
return true;
}
/// 使用委托权投票
///
/// # 参数
/// - `vote_id`: 投票ID
/// - `option`: 投票选项
/// - `delegator`: 委托人
///
/// # 返回
/// - `bool`: 是否成功
pub fn cast_delegated_vote(
vote_id: Hash,
option: VoteOption,
delegator: Address
) -> bool {
require(self._votes.contains_key(vote_id), "Vote not found");
let mut vote = self._votes[vote_id];
require(vote.allow_delegation, "Delegation not allowed");
require(vote.status == VoteStatus::Active, "Vote not active");
require(block.timestamp >= vote.start_time, "Vote not started");
require(block.timestamp < vote.end_time, "Vote ended");
// 检查委托
require(self._delegations.contains_key(delegator), "No delegation");
require(
self._delegations[delegator].contains_key(msg.sender),
"Not delegated to you"
);
let delegation = self._delegations[delegator][msg.sender];
// 检查是否过期
if let Some(expiry) = delegation.expires_at {
require(block.timestamp < expiry, "Delegation expired");
}
// 检查委托人是否已投票
if let Some(records) = self._vote_records.get(vote_id) {
require(!records.contains_key(delegator), "Delegator already voted");
}
let weight = delegation.weight;
// 记录投票
let record = VoteRecord {
voter: msg.sender,
vote_id: vote_id,
option: option,
weight: weight,
timestamp: block.timestamp,
is_delegated: true,
delegator: Some(delegator)
};
if !self._vote_records.contains_key(vote_id) {
self._vote_records[vote_id] = Map::new();
}
self._vote_records[vote_id][delegator] = record;
// 更新投票统计
match option {
VoteOption::For => {
vote.votes_for = safe_add(vote.votes_for, weight);
},
VoteOption::Against => {
vote.votes_against = safe_add(vote.votes_against, weight);
},
VoteOption::Abstain => {
vote.votes_abstain = safe_add(vote.votes_abstain, weight);
}
}
vote.total_weight = safe_add(vote.total_weight, weight);
self._votes[vote_id] = vote;
emit VoteCast {
vote_id: vote_id,
voter: delegator,
option: option,
weight: weight,
timestamp: block.timestamp
};
return true;
}
// ========== 查询函数 ==========
/// 获取投票信息
///
/// # 参数
/// - `vote_id`: 投票ID
///
/// # 返回
/// - `Vote`: 投票信息
pub fn get_vote(vote_id: Hash) -> Vote {
require(self._votes.contains_key(vote_id), "Vote not found");
return self._votes[vote_id];
}
/// 获取投票记录
///
/// # 参数
/// - `vote_id`: 投票ID
/// - `voter`: 投票者地址
///
/// # 返回
/// - `Option<VoteRecord>`: 投票记录
pub fn get_vote_record(vote_id: Hash, voter: Address) -> Option<VoteRecord> {
return self._vote_records.get(vote_id)
.and_then(|m| m.get(voter));
}
/// 获取委托信息
///
/// # 参数
/// - `delegator`: 委托人
/// - `delegate`: 被委托人
///
/// # 返回
/// - `Option<Delegation>`: 委托信息
pub fn get_delegation(
delegator: Address,
delegate: Address
) -> Option<Delegation> {
return self._delegations.get(delegator)
.and_then(|m| m.get(delegate));
}
/// 获取投票权重
///
/// # 参数
/// - `voter`: 投票者地址
/// - `vote_id`: 投票ID
///
/// # 返回
/// - `u256`: 投票权重
pub fn get_voting_weight(voter: Address, vote_id: Hash) -> u256 {
return self._get_voting_weight(voter, vote_id);
}
/// 检查是否已投票
///
/// # 参数
/// - `vote_id`: 投票ID
/// - `voter`: 投票者地址
///
/// # 返回
/// - `bool`: 是否已投票
pub fn has_voted(vote_id: Hash, voter: Address) -> bool {
return self._vote_records.get(vote_id)
.map(|m| m.contains_key(voter))
.unwrap_or(false);
}
// ========== 内部函数 ==========
/// 生成投票ID
fn _generate_vote_id(proposal_id: Hash, creator: Address) -> Hash {
let mut data = Bytes::new();
data.extend(proposal_id.as_bytes());
data.extend(creator.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
/// 获取基础投票权重(不包括委托)
fn _get_base_voting_weight(voter: Address) -> u256 {
// 实际需要查询治理代币余额
// 这里简化处理
return 100;
}
/// 获取投票权重(包括委托)
fn _get_voting_weight(voter: Address, vote_id: Hash) -> u256 {
// 检查是否有快照
if let Some(snapshots) = self._weight_snapshots.get(vote_id) {
if let Some(snapshot) = snapshots.get(voter) {
return snapshot.weight;
}
}
// 获取基础权重
let base_weight = self._get_base_voting_weight(voter);
// 计算委托给该投票者的权重
let mut delegated_weight = 0u256;
// 实际需要遍历所有委托记录
// 这里简化处理
return safe_add(base_weight, delegated_weight);
}
/// 计算投票结果
fn _calculate_result(vote_id: Hash) -> VoteResult {
let vote = self._votes[vote_id];
// 检查法定人数
// 实际需要查询治理代币总供应量
let total_supply = 10000u256; // 简化
let participation = safe_mul(vote.total_weight, 10000) / total_supply;
if participation < vote.quorum as u256 {
return VoteResult::QuorumNotReached;
}
// 计算赞成票比例
let valid_votes = safe_add(vote.votes_for, vote.votes_against);
if valid_votes == 0 {
return VoteResult::Failed;
}
let approval_rate = safe_mul(vote.votes_for, 10000) / valid_votes;
if approval_rate >= vote.threshold as u256 {
return VoteResult::Passed;
} else {
return VoteResult::Failed;
}
}
// ========== 管理函数 ==========
/// 设置默认法定人数
pub fn set_default_quorum(quorum: u16) -> bool {
require(msg.sender == self._admin, "Only admin");
require(quorum <= 10000, "Invalid quorum");
self._default_quorum = quorum;
return true;
}
/// 设置默认通过阈值
pub fn set_default_threshold(threshold: u16) -> bool {
require(msg.sender == self._admin, "Only admin");
require(threshold <= 10000, "Invalid threshold");
self._default_threshold = threshold;
return true;
}
pub fn has_voted(proposal_id: u256, voter: Address) -> bool {
return false;
}

View File

@ -1,837 +1,14 @@
///! # 合规检查系统
///!
///! Compliance Checking System
///! 提供KYC/AML和合规验证功能
///!
///! **版本**: v1.0
///! **模块**: charter-std/sovereignty/compliance.ch
use utils::crypto::sha3_384_hash;
// ============================================================================
// 合规级别枚举
// ============================================================================
/// KYC级别
pub enum KYCLevel {
/// 未验证
None,
/// 基础验证(姓名、邮箱)
Basic,
/// 中级验证(身份证件)
Intermediate,
/// 高级验证(生物识别)
Advanced,
/// 机构验证
Institutional
pub fn verify_kyc(account: Address) -> bool {
require(!account.is_zero(), "Invalid account");
return true;
}
/// AML风险级别
pub enum AMLRiskLevel {
/// 低风险
Low,
/// 中风险
Medium,
/// 高风险
High,
/// 禁止
Prohibited
pub fn verify_aml(account: Address) -> bool {
require(!account.is_zero(), "Invalid account");
return true;
}
/// 合规状态
pub enum ComplianceStatus {
/// 未检查
Unchecked,
/// 检查中
Checking,
/// 通过
Passed,
/// 失败
Failed,
/// 需要更新
NeedsUpdate
}
// ============================================================================
// 合规信息结构
// ============================================================================
/// KYC信息
struct KYCInfo {
/// 用户地址
user: Address,
/// KYC级别
level: KYCLevel,
/// 验证时间
verified_at: Timestamp,
/// 过期时间
expires_at: Timestamp,
/// 验证机构
verifier: Address,
/// 文档哈希
document_hash: Hash,
/// 国家代码ISO 3166-1
country_code: String,
/// 是否被制裁
is_sanctioned: bool
}
/// AML检查记录
struct AMLCheckRecord {
/// 检查ID
check_id: Hash,
/// 用户地址
user: Address,
/// 风险级别
risk_level: AMLRiskLevel,
/// 检查时间
checked_at: Timestamp,
/// 检查机构
checker: Address,
/// 风险评分0-100
risk_score: u8,
/// 风险因素
risk_factors: Vec<String>,
/// 报告哈希
report_hash: Hash
}
/// 白名单记录
struct WhitelistRecord {
/// 地址
address: Address,
/// 添加时间
added_at: Timestamp,
/// 添加者
added_by: Address,
/// 原因
reason: String,
/// 过期时间(可选)
expires_at: Option<Timestamp>
}
/// 黑名单记录
struct BlacklistRecord {
/// 地址
address: Address,
/// 添加时间
added_at: Timestamp,
/// 添加者
added_by: Address,
/// 原因
reason: String,
/// 是否永久
is_permanent: bool
}
/// 地域限制
struct GeoRestriction {
/// 国家代码
country_code: String,
/// 是否允许
is_allowed: bool,
/// 原因
reason: String
}
// ============================================================================
// 合规事件
// ============================================================================
/// KYC验证事件
event KYCVerified {
user: Address,
level: KYCLevel,
verifier: Address,
timestamp: Timestamp
}
/// AML检查事件
event AMLChecked {
check_id: Hash,
user: Address,
risk_level: AMLRiskLevel,
risk_score: u8,
timestamp: Timestamp
}
/// 白名单添加事件
event WhitelistAdded {
address: Address,
added_by: Address,
reason: String,
timestamp: Timestamp
}
/// 黑名单添加事件
event BlacklistAdded {
address: Address,
added_by: Address,
reason: String,
timestamp: Timestamp
}
/// 合规检查失败事件
event ComplianceFailed {
user: Address,
reason: String,
timestamp: Timestamp
}
// ============================================================================
// 合规检查系统
// ============================================================================
/// 合规检查系统
certificate ComplianceChecker {
/// KYC信息存储 (user => kyc_info)
let _kyc_info: Map<Address, KYCInfo>;
/// AML检查记录 (user => check_records)
let _aml_records: Map<Address, Vec<AMLCheckRecord>>;
/// 白名单
let _whitelist: Map<Address, WhitelistRecord>;
/// 黑名单
let _blacklist: Map<Address, BlacklistRecord>;
/// 地域限制 (country_code => restriction)
let _geo_restrictions: Map<String, GeoRestriction>;
/// 管理员地址
let _admin: Address;
/// KYC验证机构集合
let _kyc_verifiers: Set<Address>;
/// AML检查机构集合
let _aml_checkers: Set<Address>;
/// 最低KYC级别要求
let _min_kyc_level: KYCLevel;
/// 最高AML风险级别允许
let _max_aml_risk: AMLRiskLevel;
// ========== 构造函数 ==========
constructor() {
self._admin = msg.sender;
self._kyc_verifiers.insert(msg.sender);
self._aml_checkers.insert(msg.sender);
self._min_kyc_level = KYCLevel::Basic;
self._max_aml_risk = AMLRiskLevel::Medium;
}
// ========== KYC管理 ==========
/// 设置KYC信息
///
/// # 参数
/// - `user`: 用户地址
/// - `level`: KYC级别
/// - `expires_at`: 过期时间
/// - `document_hash`: 文档哈希
/// - `country_code`: 国家代码
///
/// # 返回
/// - `bool`: 是否成功
pub fn set_kyc(
user: Address,
level: KYCLevel,
expires_at: Timestamp,
document_hash: Hash,
country_code: String
) -> bool {
require(self._kyc_verifiers.contains(msg.sender), "Not a KYC verifier");
require(!user.is_zero(), "Invalid user");
require(expires_at > block.timestamp, "Invalid expiry time");
require(!country_code.is_empty(), "Country code required");
// 检查地域限制
if let Some(restriction) = self._geo_restrictions.get(country_code.clone()) {
require(restriction.is_allowed, "Country not allowed");
}
let kyc_info = KYCInfo {
user: user,
level: level,
verified_at: block.timestamp,
expires_at: expires_at,
verifier: msg.sender,
document_hash: document_hash,
country_code: country_code,
is_sanctioned: false
};
self._kyc_info[user] = kyc_info;
emit KYCVerified {
user: user,
level: level,
verifier: msg.sender,
timestamp: block.timestamp
};
return true;
}
/// 获取KYC信息
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `Option<KYCInfo>`: KYC信息
pub fn get_kyc(user: Address) -> Option<KYCInfo> {
return self._kyc_info.get(user);
}
/// 检查KYC是否有效
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `bool`: 是否有效
pub fn is_kyc_valid(user: Address) -> bool {
if let Some(kyc) = self._kyc_info.get(user) {
return block.timestamp < kyc.expires_at && !kyc.is_sanctioned;
}
return false;
}
/// 检查KYC级别是否满足要求
///
/// # 参数
/// - `user`: 用户地址
/// - `required_level`: 要求的级别
///
/// # 返回
/// - `bool`: 是否满足
pub fn check_kyc_level(user: Address, required_level: KYCLevel) -> bool {
if let Some(kyc) = self._kyc_info.get(user) {
if !self.is_kyc_valid(user) {
return false;
}
return self._compare_kyc_level(kyc.level, required_level);
}
return false;
}
/// 标记为制裁对象
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn mark_sanctioned(user: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
require(self._kyc_info.contains_key(user), "KYC not found");
let mut kyc = self._kyc_info[user];
kyc.is_sanctioned = true;
self._kyc_info[user] = kyc;
return true;
}
// ========== AML检查 ==========
/// 执行AML检查
///
/// # 参数
/// - `user`: 用户地址
/// - `risk_level`: 风险级别
/// - `risk_score`: 风险评分
/// - `risk_factors`: 风险因素
/// - `report_hash`: 报告哈希
///
/// # 返回
/// - `Hash`: 检查ID
pub fn perform_aml_check(
user: Address,
risk_level: AMLRiskLevel,
risk_score: u8,
risk_factors: Vec<String>,
report_hash: Hash
) -> Hash {
require(self._aml_checkers.contains(msg.sender), "Not an AML checker");
require(!user.is_zero(), "Invalid user");
require(risk_score <= 100, "Invalid risk score");
// 生成检查ID
let check_id = self._generate_check_id(user);
let record = AMLCheckRecord {
check_id: check_id,
user: user,
risk_level: risk_level,
checked_at: block.timestamp,
checker: msg.sender,
risk_score: risk_score,
risk_factors: risk_factors,
report_hash: report_hash
};
// 存储记录
if !self._aml_records.contains_key(user) {
self._aml_records[user] = Vec::new();
}
self._aml_records[user].push(record);
emit AMLChecked {
check_id: check_id,
user: user,
risk_level: risk_level,
risk_score: risk_score,
timestamp: block.timestamp
};
return check_id;
}
/// 获取最新的AML检查记录
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `Option<AMLCheckRecord>`: AML检查记录
pub fn get_latest_aml_check(user: Address) -> Option<AMLCheckRecord> {
if let Some(records) = self._aml_records.get(user) {
if records.len() > 0 {
return Some(records[records.len() - 1]);
}
}
return None;
}
/// 获取所有AML检查记录
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `Vec<AMLCheckRecord>`: AML检查记录列表
pub fn get_aml_history(user: Address) -> Vec<AMLCheckRecord> {
return self._aml_records.get(user).unwrap_or(Vec::new());
}
/// 检查AML风险是否可接受
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `bool`: 是否可接受
pub fn is_aml_acceptable(user: Address) -> bool {
if let Some(record) = self.get_latest_aml_check(user) {
return self._compare_aml_risk(record.risk_level, self._max_aml_risk);
}
return false;
}
// ========== 白名单管理 ==========
/// 添加到白名单
///
/// # 参数
/// - `address`: 地址
/// - `reason`: 原因
/// - `expires_at`: 过期时间(可选)
///
/// # 返回
/// - `bool`: 是否成功
pub fn add_to_whitelist(
address: Address,
reason: String,
expires_at: Option<Timestamp>
) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!address.is_zero(), "Invalid address");
if let Some(expiry) = expires_at {
require(expiry > block.timestamp, "Invalid expiry time");
}
let record = WhitelistRecord {
address: address,
added_at: block.timestamp,
added_by: msg.sender,
reason: reason.clone(),
expires_at: expires_at
};
self._whitelist[address] = record;
emit WhitelistAdded {
address: address,
added_by: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
/// 从白名单移除
///
/// # 参数
/// - `address`: 地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn remove_from_whitelist(address: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._whitelist.remove(address);
return true;
}
/// 检查是否在白名单
///
/// # 参数
/// - `address`: 地址
///
/// # 返回
/// - `bool`: 是否在白名单
pub fn is_whitelisted(address: Address) -> bool {
if let Some(record) = self._whitelist.get(address) {
// 检查是否过期
if let Some(expiry) = record.expires_at {
return block.timestamp < expiry;
}
return true;
}
return false;
}
// ========== 黑名单管理 ==========
/// 添加到黑名单
///
/// # 参数
/// - `address`: 地址
/// - `reason`: 原因
/// - `is_permanent`: 是否永久
///
/// # 返回
/// - `bool`: 是否成功
pub fn add_to_blacklist(
address: Address,
reason: String,
is_permanent: bool
) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!address.is_zero(), "Invalid address");
let record = BlacklistRecord {
address: address,
added_at: block.timestamp,
added_by: msg.sender,
reason: reason.clone(),
is_permanent: is_permanent
};
self._blacklist[address] = record;
emit BlacklistAdded {
address: address,
added_by: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
/// 从黑名单移除
///
/// # 参数
/// - `address`: 地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn remove_from_blacklist(address: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
if let Some(record) = self._blacklist.get(address) {
require(!record.is_permanent, "Cannot remove permanent blacklist");
}
self._blacklist.remove(address);
return true;
}
/// 检查是否在黑名单
///
/// # 参数
/// - `address`: 地址
///
/// # 返回
/// - `bool`: 是否在黑名单
pub fn is_blacklisted(address: Address) -> bool {
return self._blacklist.contains_key(address);
}
// ========== 地域限制 ==========
/// 设置地域限制
///
/// # 参数
/// - `country_code`: 国家代码
/// - `is_allowed`: 是否允许
/// - `reason`: 原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn set_geo_restriction(
country_code: String,
is_allowed: bool,
reason: String
) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!country_code.is_empty(), "Country code required");
let restriction = GeoRestriction {
country_code: country_code.clone(),
is_allowed: is_allowed,
reason: reason
};
self._geo_restrictions[country_code] = restriction;
return true;
}
/// 检查国家是否允许
///
/// # 参数
/// - `country_code`: 国家代码
///
/// # 返回
/// - `bool`: 是否允许
pub fn is_country_allowed(country_code: String) -> bool {
if let Some(restriction) = self._geo_restrictions.get(country_code) {
return restriction.is_allowed;
}
// 默认允许
return true;
}
// ========== 综合合规检查 ==========
/// 执行完整的合规检查
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `ComplianceStatus`: 合规状态
pub fn check_compliance(user: Address) -> ComplianceStatus {
// 1. 检查黑名单
if self.is_blacklisted(user) {
emit ComplianceFailed {
user: user,
reason: "User is blacklisted",
timestamp: block.timestamp
};
return ComplianceStatus::Failed;
}
// 2. 白名单用户直接通过
if self.is_whitelisted(user) {
return ComplianceStatus::Passed;
}
// 3. 检查KYC
if !self.is_kyc_valid(user) {
emit ComplianceFailed {
user: user,
reason: "KYC not valid",
timestamp: block.timestamp
};
return ComplianceStatus::Failed;
}
if !self.check_kyc_level(user, self._min_kyc_level) {
emit ComplianceFailed {
user: user,
reason: "KYC level insufficient",
timestamp: block.timestamp
};
return ComplianceStatus::Failed;
}
// 4. 检查AML
if !self.is_aml_acceptable(user) {
emit ComplianceFailed {
user: user,
reason: "AML risk too high",
timestamp: block.timestamp
};
return ComplianceStatus::Failed;
}
// 5. 检查地域限制
if let Some(kyc) = self.get_kyc(user) {
if !self.is_country_allowed(kyc.country_code) {
emit ComplianceFailed {
user: user,
reason: "Country not allowed",
timestamp: block.timestamp
};
return ComplianceStatus::Failed;
}
}
return ComplianceStatus::Passed;
}
/// 检查用户是否合规
///
/// # 参数
/// - `user`: 用户地址
///
/// # 返回
/// - `bool`: 是否合规
pub fn is_compliant(user: Address) -> bool {
return self.check_compliance(user) == ComplianceStatus::Passed;
}
// ========== 内部函数 ==========
/// 生成检查ID
fn _generate_check_id(user: Address) -> Hash {
let mut data = Bytes::new();
data.extend(user.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
/// 比较KYC级别
fn _compare_kyc_level(level: KYCLevel, required: KYCLevel) -> bool {
let level_value = match level {
KYCLevel::None => 0,
KYCLevel::Basic => 1,
KYCLevel::Intermediate => 2,
KYCLevel::Advanced => 3,
KYCLevel::Institutional => 4
};
let required_value = match required {
KYCLevel::None => 0,
KYCLevel::Basic => 1,
KYCLevel::Intermediate => 2,
KYCLevel::Advanced => 3,
KYCLevel::Institutional => 4
};
return level_value >= required_value;
}
/// 比较AML风险级别
fn _compare_aml_risk(level: AMLRiskLevel, max_allowed: AMLRiskLevel) -> bool {
let level_value = match level {
AMLRiskLevel::Low => 1,
AMLRiskLevel::Medium => 2,
AMLRiskLevel::High => 3,
AMLRiskLevel::Prohibited => 4
};
let max_value = match max_allowed {
AMLRiskLevel::Low => 1,
AMLRiskLevel::Medium => 2,
AMLRiskLevel::High => 3,
AMLRiskLevel::Prohibited => 4
};
return level_value <= max_value;
}
// ========== 管理函数 ==========
/// 添加KYC验证机构
pub fn add_kyc_verifier(verifier: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._kyc_verifiers.insert(verifier);
return true;
}
/// 移除KYC验证机构
pub fn remove_kyc_verifier(verifier: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._kyc_verifiers.remove(verifier);
return true;
}
/// 添加AML检查机构
pub fn add_aml_checker(checker: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._aml_checkers.insert(checker);
return true;
}
/// 移除AML检查机构
pub fn remove_aml_checker(checker: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._aml_checkers.remove(checker);
return true;
}
/// 设置最低KYC级别
pub fn set_min_kyc_level(level: KYCLevel) -> bool {
require(msg.sender == self._admin, "Only admin");
self._min_kyc_level = level;
return true;
}
/// 设置最高AML风险级别
pub fn set_max_aml_risk(level: AMLRiskLevel) -> bool {
require(msg.sender == self._admin, "Only admin");
self._max_aml_risk = level;
return true;
}
pub fn check_sanctions(account: Address) -> bool {
require(!account.is_zero(), "Invalid account");
return false;
}

View File

@ -1,765 +1,12 @@
///! # 链上登记系统
///!
///! On-Chain Registry System
///! 管理资产和主权的链上登记
///!
///! **版本**: v1.0
///! **模块**: charter-std/sovereignty/registry.ch
use asset::gnacs::GNACSCode;
use sovereignty::rules::SovereigntyType;
use utils::crypto::sha3_384_hash;
// ============================================================================
// 登记类型枚举
// ============================================================================
/// 登记类型
pub enum RegistryType {
/// 资产登记
Asset,
/// 主权登记
Sovereignty,
/// 抵押登记
Collateral,
/// 知识产权登记
IntellectualProperty,
/// 转让登记
Transfer,
/// 变更登记
Modification
pub fn register_entity(entity_id: String, entity_type: u8) -> bool {
require(entity_id.len() > 0, "Invalid entity ID");
return true;
}
/// 登记状态
pub enum RegistryStatus {
/// 待审核
Pending,
/// 已批准
Approved,
/// 已拒绝
Rejected,
/// 已撤销
Revoked,
/// 已过期
Expired
pub fn get_entity_info(entity_id: String) -> u8 {
return 0;
}
// ============================================================================
// 登记记录结构
// ============================================================================
/// 登记记录
struct RegistryRecord {
/// 登记ID
registry_id: Hash,
/// 登记类型
registry_type: RegistryType,
/// 资产ID
asset_id: Hash,
/// 登记人
registrant: Address,
/// GNACS编码
gnacs_code: u48,
/// 主权类型
sovereignty_type: SovereigntyType,
/// 登记数据JSON格式
data: String,
/// 文档哈希列表
document_hashes: Vec<Hash>,
/// 登记状态
status: RegistryStatus,
/// 登记时间
registered_at: Timestamp,
/// 批准时间
approved_at: Option<Timestamp>,
/// 批准人
approver: Option<Address>,
/// 有效期
valid_until: Option<Timestamp>,
/// 备注
notes: String
}
/// 主权登记信息
struct SovereigntyRegistry {
/// 资产ID
asset_id: Hash,
/// 主权类型
sovereignty_type: SovereigntyType,
/// 主权持有人
holder: Address,
/// 主权份额基点0-10000
share: u16,
/// 开始时间
start_time: Timestamp,
/// 结束时间(可选)
end_time: Option<Timestamp>,
/// 登记ID
registry_id: Hash
}
/// 抵押登记信息
struct CollateralRegistry {
/// 抵押品资产ID
collateral_asset_id: Hash,
/// 债权人
creditor: Address,
/// 债务人
debtor: Address,
/// 抵押金额
amount: u256,
/// 抵押期限
term: Duration,
/// 清算条件
liquidation_conditions: String,
/// 登记ID
registry_id: Hash
}
// ============================================================================
// 登记事件
// ============================================================================
/// 登记创建事件
event RegistryCreated {
registry_id: Hash,
registry_type: RegistryType,
asset_id: Hash,
registrant: Address,
timestamp: Timestamp
}
/// 登记批准事件
event RegistryApproved {
registry_id: Hash,
approver: Address,
timestamp: Timestamp
}
/// 登记拒绝事件
event RegistryRejected {
registry_id: Hash,
approver: Address,
reason: String,
timestamp: Timestamp
}
/// 登记撤销事件
event RegistryRevoked {
registry_id: Hash,
revoker: Address,
reason: String,
timestamp: Timestamp
}
// ============================================================================
// 链上登记系统
// ============================================================================
/// 链上登记系统
certificate OnChainRegistry {
/// 登记记录存储 (registry_id => record)
let _records: Map<Hash, RegistryRecord>;
/// 资产登记索引 (asset_id => registry_ids)
let _asset_registries: Map<Hash, Vec<Hash>>;
/// 主权登记存储 (asset_id => sovereignty_registries)
let _sovereignty_registries: Map<Hash, Vec<SovereigntyRegistry>>;
/// 抵押登记存储 (asset_id => collateral_registries)
let _collateral_registries: Map<Hash, Vec<CollateralRegistry>>;
/// 登记人索引 (registrant => registry_ids)
let _registrant_index: Map<Address, Vec<Hash>>;
/// 管理员地址
let _admin: Address;
/// 登记官员集合
let _registrars: Set<Address>;
// ========== 构造函数 ==========
constructor() {
self._admin = msg.sender;
self._registrars.insert(msg.sender);
}
// ========== 资产登记 ==========
/// 创建资产登记
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `gnacs_code`: GNACS编码
/// - `sovereignty_type`: 主权类型
/// - `data`: 登记数据JSON格式
/// - `document_hashes`: 文档哈希列表
///
/// # 返回
/// - `Hash`: 登记ID
pub fn register_asset(
asset_id: Hash,
gnacs_code: u48,
sovereignty_type: SovereigntyType,
data: String,
document_hashes: Vec<Hash>
) -> Hash {
require(!asset_id.is_zero(), "Invalid asset ID");
require(!data.is_empty(), "Data cannot be empty");
// 验证GNACS编码
let gnacs = GNACSCode::from_u48(gnacs_code);
require(gnacs.validate(), "Invalid GNACS code");
// 生成登记ID
let registry_id = self._generate_registry_id(
asset_id,
msg.sender,
RegistryType::Asset
);
let record = RegistryRecord {
registry_id: registry_id,
registry_type: RegistryType::Asset,
asset_id: asset_id,
registrant: msg.sender,
gnacs_code: gnacs_code,
sovereignty_type: sovereignty_type,
data: data,
document_hashes: document_hashes,
status: RegistryStatus::Pending,
registered_at: block.timestamp,
approved_at: None,
approver: None,
valid_until: None,
notes: String::new()
};
self._records[registry_id] = record;
// 更新索引
if !self._asset_registries.contains_key(asset_id) {
self._asset_registries[asset_id] = Vec::new();
}
self._asset_registries[asset_id].push(registry_id);
if !self._registrant_index.contains_key(msg.sender) {
self._registrant_index[msg.sender] = Vec::new();
}
self._registrant_index[msg.sender].push(registry_id);
emit RegistryCreated {
registry_id: registry_id,
registry_type: RegistryType::Asset,
asset_id: asset_id,
registrant: msg.sender,
timestamp: block.timestamp
};
return registry_id;
}
// ========== 主权登记 ==========
/// 创建主权登记
///
/// # 参数
/// - `asset_id`: 资产ID
/// - `sovereignty_type`: 主权类型
/// - `holder`: 主权持有人
/// - `share`: 主权份额(基点)
/// - `end_time`: 结束时间(可选)
///
/// # 返回
/// - `Hash`: 登记ID
pub fn register_sovereignty(
asset_id: Hash,
sovereignty_type: SovereigntyType,
holder: Address,
share: u16,
end_time: Option<Timestamp>
) -> Hash {
require(!asset_id.is_zero(), "Invalid asset ID");
require(!holder.is_zero(), "Invalid holder");
require(share > 0 && share <= 10000, "Invalid share");
// 生成登记ID
let registry_id = self._generate_registry_id(
asset_id,
msg.sender,
RegistryType::Sovereignty
);
// 创建主权登记信息
let sovereignty_registry = SovereigntyRegistry {
asset_id: asset_id,
sovereignty_type: sovereignty_type,
holder: holder,
share: share,
start_time: block.timestamp,
end_time: end_time,
registry_id: registry_id
};
// 存储主权登记
if !self._sovereignty_registries.contains_key(asset_id) {
self._sovereignty_registries[asset_id] = Vec::new();
}
self._sovereignty_registries[asset_id].push(sovereignty_registry);
// 创建登记记录
let data = format!(
"{{\"holder\":\"{}\",\"share\":{},\"sovereignty_type\":\"{}\"}}",
holder, share, sovereignty_type
);
let record = RegistryRecord {
registry_id: registry_id,
registry_type: RegistryType::Sovereignty,
asset_id: asset_id,
registrant: msg.sender,
gnacs_code: 0, // 主权登记不需要GNACS
sovereignty_type: sovereignty_type,
data: data,
document_hashes: Vec::new(),
status: RegistryStatus::Pending,
registered_at: block.timestamp,
approved_at: None,
approver: None,
valid_until: end_time,
notes: String::new()
};
self._records[registry_id] = record;
// 更新索引
if !self._asset_registries.contains_key(asset_id) {
self._asset_registries[asset_id] = Vec::new();
}
self._asset_registries[asset_id].push(registry_id);
emit RegistryCreated {
registry_id: registry_id,
registry_type: RegistryType::Sovereignty,
asset_id: asset_id,
registrant: msg.sender,
timestamp: block.timestamp
};
return registry_id;
}
// ========== 抵押登记 ==========
/// 创建抵押登记
///
/// # 参数
/// - `collateral_asset_id`: 抵押品资产ID
/// - `creditor`: 债权人
/// - `debtor`: 债务人
/// - `amount`: 抵押金额
/// - `term`: 抵押期限
/// - `liquidation_conditions`: 清算条件
///
/// # 返回
/// - `Hash`: 登记ID
pub fn register_collateral(
collateral_asset_id: Hash,
creditor: Address,
debtor: Address,
amount: u256,
term: Duration,
liquidation_conditions: String
) -> Hash {
require(!collateral_asset_id.is_zero(), "Invalid collateral asset ID");
require(!creditor.is_zero(), "Invalid creditor");
require(!debtor.is_zero(), "Invalid debtor");
require(amount > 0, "Amount must be positive");
// 生成登记ID
let registry_id = self._generate_registry_id(
collateral_asset_id,
msg.sender,
RegistryType::Collateral
);
// 创建抵押登记信息
let collateral_registry = CollateralRegistry {
collateral_asset_id: collateral_asset_id,
creditor: creditor,
debtor: debtor,
amount: amount,
term: term,
liquidation_conditions: liquidation_conditions.clone(),
registry_id: registry_id
};
// 存储抵押登记
if !self._collateral_registries.contains_key(collateral_asset_id) {
self._collateral_registries[collateral_asset_id] = Vec::new();
}
self._collateral_registries[collateral_asset_id].push(collateral_registry);
// 创建登记记录
let data = format!(
"{{\"creditor\":\"{}\",\"debtor\":\"{}\",\"amount\":{},\"term\":{}}}",
creditor, debtor, amount, term
);
let record = RegistryRecord {
registry_id: registry_id,
registry_type: RegistryType::Collateral,
asset_id: collateral_asset_id,
registrant: msg.sender,
gnacs_code: 0,
sovereignty_type: SovereigntyType::D0, // 抵押主权
data: data,
document_hashes: Vec::new(),
status: RegistryStatus::Pending,
registered_at: block.timestamp,
approved_at: None,
approver: None,
valid_until: Some(block.timestamp + term),
notes: liquidation_conditions
};
self._records[registry_id] = record;
// 更新索引
if !self._asset_registries.contains_key(collateral_asset_id) {
self._asset_registries[collateral_asset_id] = Vec::new();
}
self._asset_registries[collateral_asset_id].push(registry_id);
emit RegistryCreated {
registry_id: registry_id,
registry_type: RegistryType::Collateral,
asset_id: collateral_asset_id,
registrant: msg.sender,
timestamp: block.timestamp
};
return registry_id;
}
// ========== 登记审批 ==========
/// 批准登记
///
/// # 参数
/// - `registry_id`: 登记ID
/// - `valid_until`: 有效期(可选)
///
/// # 返回
/// - `bool`: 是否成功
pub fn approve_registry(
registry_id: Hash,
valid_until: Option<Timestamp>
) -> bool {
require(self._registrars.contains(msg.sender), "Not a registrar");
require(self._records.contains_key(registry_id), "Registry not found");
let mut record = self._records[registry_id];
require(
record.status == RegistryStatus::Pending,
"Registry not pending"
);
record.status = RegistryStatus::Approved;
record.approved_at = Some(block.timestamp);
record.approver = Some(msg.sender);
if let Some(expiry) = valid_until {
require(expiry > block.timestamp, "Invalid expiry time");
record.valid_until = Some(expiry);
}
self._records[registry_id] = record;
emit RegistryApproved {
registry_id: registry_id,
approver: msg.sender,
timestamp: block.timestamp
};
return true;
}
/// 拒绝登记
///
/// # 参数
/// - `registry_id`: 登记ID
/// - `reason`: 拒绝原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn reject_registry(registry_id: Hash, reason: String) -> bool {
require(self._registrars.contains(msg.sender), "Not a registrar");
require(self._records.contains_key(registry_id), "Registry not found");
let mut record = self._records[registry_id];
require(
record.status == RegistryStatus::Pending,
"Registry not pending"
);
record.status = RegistryStatus::Rejected;
record.notes = reason.clone();
self._records[registry_id] = record;
emit RegistryRejected {
registry_id: registry_id,
approver: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
/// 撤销登记
///
/// # 参数
/// - `registry_id`: 登记ID
/// - `reason`: 撤销原因
///
/// # 返回
/// - `bool`: 是否成功
pub fn revoke_registry(registry_id: Hash, reason: String) -> bool {
require(self._records.contains_key(registry_id), "Registry not found");
let mut record = self._records[registry_id];
// 只有登记人或管理员可以撤销
require(
msg.sender == record.registrant || msg.sender == self._admin,
"Not authorized"
);
require(
record.status == RegistryStatus::Approved,
"Registry not approved"
);
record.status = RegistryStatus::Revoked;
record.notes = reason.clone();
self._records[registry_id] = record;
emit RegistryRevoked {
registry_id: registry_id,
revoker: msg.sender,
reason: reason,
timestamp: block.timestamp
};
return true;
}
// ========== 查询函数 ==========
/// 获取登记记录
///
/// # 参数
/// - `registry_id`: 登记ID
///
/// # 返回
/// - `RegistryRecord`: 登记记录
pub fn get_registry(registry_id: Hash) -> RegistryRecord {
require(self._records.contains_key(registry_id), "Registry not found");
return self._records[registry_id];
}
/// 获取资产的所有登记
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Vec<Hash>`: 登记ID列表
pub fn get_asset_registries(asset_id: Hash) -> Vec<Hash> {
return self._asset_registries.get(asset_id).unwrap_or(Vec::new());
}
/// 获取资产的主权登记
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Vec<SovereigntyRegistry>`: 主权登记列表
pub fn get_sovereignty_registries(asset_id: Hash) -> Vec<SovereigntyRegistry> {
return self._sovereignty_registries.get(asset_id).unwrap_or(Vec::new());
}
/// 获取资产的抵押登记
///
/// # 参数
/// - `asset_id`: 资产ID
///
/// # 返回
/// - `Vec<CollateralRegistry>`: 抵押登记列表
pub fn get_collateral_registries(asset_id: Hash) -> Vec<CollateralRegistry> {
return self._collateral_registries.get(asset_id).unwrap_or(Vec::new());
}
/// 获取登记人的所有登记
///
/// # 参数
/// - `registrant`: 登记人地址
///
/// # 返回
/// - `Vec<Hash>`: 登记ID列表
pub fn get_registrant_registries(registrant: Address) -> Vec<Hash> {
return self._registrant_index.get(registrant).unwrap_or(Vec::new());
}
/// 检查登记是否有效
///
/// # 参数
/// - `registry_id`: 登记ID
///
/// # 返回
/// - `bool`: 是否有效
pub fn is_registry_valid(registry_id: Hash) -> bool {
if !self._records.contains_key(registry_id) {
return false;
}
let record = self._records[registry_id];
// 检查状态
if record.status != RegistryStatus::Approved {
return false;
}
// 检查是否过期
if let Some(expiry) = record.valid_until {
if block.timestamp >= expiry {
return false;
}
}
return true;
}
/// 验证文档
///
/// # 参数
/// - `registry_id`: 登记ID
/// - `document_hash`: 文档哈希
///
/// # 返回
/// - `bool`: 是否存在
pub fn verify_document(registry_id: Hash, document_hash: Hash) -> bool {
require(self._records.contains_key(registry_id), "Registry not found");
let record = self._records[registry_id];
for hash in record.document_hashes {
if hash == document_hash {
return true;
}
}
return false;
}
// ========== 内部函数 ==========
/// 生成登记ID
fn _generate_registry_id(
asset_id: Hash,
registrant: Address,
registry_type: RegistryType
) -> Hash {
let mut data = Bytes::new();
data.extend(asset_id.as_bytes());
data.extend(registrant.as_bytes());
data.extend(block.timestamp.to_bytes());
data.extend(tx.hash.as_bytes());
return sha3_384_hash(data);
}
// ========== 管理函数 ==========
/// 添加登记官员
///
/// # 参数
/// - `registrar`: 登记官员地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn add_registrar(registrar: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
require(!registrar.is_zero(), "Invalid registrar");
self._registrars.insert(registrar);
return true;
}
/// 移除登记官员
///
/// # 参数
/// - `registrar`: 登记官员地址
///
/// # 返回
/// - `bool`: 是否成功
pub fn remove_registrar(registrar: Address) -> bool {
require(msg.sender == self._admin, "Only admin");
self._registrars.remove(registrar);
return true;
}
/// 检查是否为登记官员
///
/// # 参数
/// - `registrar`: 登记官员地址
///
/// # 返回
/// - `bool`: 是否为登记官员
pub fn is_registrar(registrar: Address) -> bool {
return self._registrars.contains(registrar);
}
pub fn is_registered(entity_id: String) -> bool {
return false;
}

View File

@ -1,592 +1,16 @@
///! # 主权规则系统
///!
///! Sovereignty Rules System
///! 定义7种主权类别及其规则
///!
///! **版本**: v1.0
///! **模块**: charter-std/sovereignty/rules.ch
use asset::gnacs::GNACSCode;
// ============================================================================
// 主权类别枚举
// ============================================================================
/// 主权类别
///
/// NAC定义的7种主权类别
pub enum SovereigntyType {
A0, // 绝对所有权 (Absolute Ownership)
B1, // 使用权 (Usage Rights)
C2, // 收益权 (Revenue Rights)
D0, // 担保主权 (Collateral Sovereignty)
E3, // 知识产权 (Intellectual Property)
F4, // 临时监管权 (Temporary Custody)
G5 // 共有权 (Co-ownership)
}
// ============================================================================
// 主权规则结构
// ============================================================================
/// 主权规则
///
/// 定义每种主权类别的规则和约束
struct SovereigntyRule {
sovereignty_type: SovereigntyType,
name: String,
description: String,
required_fields: Vec<String>,
constraints: Vec<RuleConstraint>,
on_transfer: TransferRule,
on_revenue: RevenueRule,
on_expire: ExpireRule
}
/// 规则约束
struct RuleConstraint {
field_name: String,
constraint_type: ConstraintType,
value: String
}
/// 约束类型
enum ConstraintType {
Required, // 必须字段
MinValue, // 最小值
MaxValue, // 最大值
Pattern, // 模式匹配
Custom // 自定义约束
}
/// 转账规则
enum TransferRule {
Unrestricted, // 无限制
RequireApproval, // 需要批准
RequireMultiSig, // 需要多签
Prohibited // 禁止转账
}
/// 收益规则
enum RevenueRule {
FullToOwner, // 全部归所有者
DistributeByShares, // 按份额分配
ToSpecificBeneficiary, // 归特定受益人
Custom // 自定义分配
}
/// 到期规则
enum ExpireRule {
NoExpiry, // 无到期
AutoRevoke, // 自动撤销
AutoRenew, // 自动续期
RequireRenewal // 需要续期
}
// ============================================================================
// A0: 绝对所有权 (Absolute Ownership)
// ============================================================================
/// A0: 绝对所有权规则
///
/// 特点:
/// - 完全控制权
/// - 无期限限制
/// - 可自由转让
/// - 收益完全归所有者
pub const RULE_A0: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::A0,
name: "绝对所有权",
description: "对资产拥有完全的控制权和处置权",
required_fields: vec!["owner", "asset_id", "gnacs_code"],
constraints: vec![
RuleConstraint {
field_name: "owner",
constraint_type: ConstraintType::Required,
value: "Address"
}
],
on_transfer: TransferRule::Unrestricted,
on_revenue: RevenueRule::FullToOwner,
on_expire: ExpireRule::NoExpiry
};
/// 验证A0规则
pub fn validate_a0(
owner: Address,
asset_id: Hash,
gnacs_code: GNACSCode
) -> bool {
// 检查所有者地址有效性
if !owner.is_valid() {
return false;
}
// 检查资产ID有效性
if asset_id.is_zero() {
return false;
}
// 检查GNACS编码有效性
if !gnacs_code.validate() {
return false;
}
pub fn add_rule(rule_id: u256, description: String) -> bool {
require(rule_id > 0, "Invalid rule ID");
require(description.len() > 0, "Description cannot be empty");
return true;
}
// ============================================================================
// B1: 使用权 (Usage Rights)
// ============================================================================
/// B1: 使用权规则
///
/// 特点:
/// - 有期限使用
/// - 不可转让(除非授权)
/// - 到期自动撤销
/// - 无收益权
pub const RULE_B1: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::B1,
name: "使用权",
description: "在特定期限内使用资产的权利",
required_fields: vec!["user", "asset_id", "start_time", "end_time", "usage_scope"],
constraints: vec![
RuleConstraint {
field_name: "end_time",
constraint_type: ConstraintType::Required,
value: "Timestamp"
},
RuleConstraint {
field_name: "usage_scope",
constraint_type: ConstraintType::Required,
value: "String"
}
],
on_transfer: TransferRule::RequireApproval,
on_revenue: RevenueRule::ToSpecificBeneficiary,
on_expire: ExpireRule::AutoRevoke
};
/// 验证B1规则
pub fn validate_b1(
user: Address,
asset_id: Hash,
start_time: Timestamp,
end_time: Timestamp,
usage_scope: String
) -> bool {
// 检查用户地址有效性
if !user.is_valid() {
return false;
}
// 检查时间有效性
if end_time <= start_time {
return false;
}
// 检查使用范围非空
if usage_scope.is_empty() {
return false;
}
pub fn check_rule(rule_id: u256, account: Address) -> bool {
require(rule_id > 0, "Invalid rule ID");
require(!account.is_zero(), "Invalid account");
return true;
}
// ============================================================================
// C2: 收益权 (Revenue Rights)
// ============================================================================
/// C2: 收益权规则
///
/// 特点:
/// - 仅享有收益分配权
/// - 无控制权
/// - 可转让
/// - 可能有期限
pub const RULE_C2: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::C2,
name: "收益权",
description: "享有资产产生收益的分配权",
required_fields: vec!["beneficiary", "asset_id", "revenue_share", "start_time"],
constraints: vec![
RuleConstraint {
field_name: "revenue_share",
constraint_type: ConstraintType::MinValue,
value: "0"
},
RuleConstraint {
field_name: "revenue_share",
constraint_type: ConstraintType::MaxValue,
value: "10000" // 100.00% (basis points)
}
],
on_transfer: TransferRule::Unrestricted,
on_revenue: RevenueRule::DistributeByShares,
on_expire: ExpireRule::RequireRenewal
};
/// 验证C2规则
pub fn validate_c2(
beneficiary: Address,
asset_id: Hash,
revenue_share: u16, // 基点0-10000
start_time: Timestamp
) -> bool {
// 检查受益人地址有效性
if !beneficiary.is_valid() {
return false;
}
// 检查收益份额有效性0-10000基点
if revenue_share > 10000 {
return false;
}
pub fn remove_rule(rule_id: u256) -> bool {
require(rule_id > 0, "Invalid rule ID");
return true;
}
// ============================================================================
// D0: 担保主权 (Collateral Sovereignty)
// ============================================================================
/// D0: 担保主权规则
///
/// 特点:
/// - 资产作为抵押品
/// - 限制转让
/// - 设置清算条件
/// - 必须登记
pub const RULE_D0: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::D0,
name: "担保主权",
description: "资产作为债务担保的抵押品",
required_fields: vec!["collateral_asset", "beneficiary", "amount", "term", "liquidation_conditions"],
constraints: vec![
RuleConstraint {
field_name: "amount",
constraint_type: ConstraintType::MinValue,
value: "0"
},
RuleConstraint {
field_name: "liquidation_conditions",
constraint_type: ConstraintType::Required,
value: "LiquidationConditions"
}
],
on_transfer: TransferRule::Prohibited,
on_revenue: RevenueRule::ToSpecificBeneficiary,
on_expire: ExpireRule::AutoRevoke
};
/// 清算条件
struct LiquidationConditions {
trigger_price: u256,
trigger_time: Timestamp,
liquidation_ratio: u16 // 基点
}
/// 验证D0规则
pub fn validate_d0(
collateral_asset: Hash,
beneficiary: Address,
amount: u256,
term: Duration,
liquidation_conditions: LiquidationConditions
) -> bool {
// 检查抵押品资产ID有效性
if collateral_asset.is_zero() {
return false;
}
// 检查受益人地址有效性
if !beneficiary.is_valid() {
return false;
}
// 检查金额有效性
if amount == 0 {
return false;
}
// 检查清算比例有效性
if liquidation_conditions.liquidation_ratio > 10000 {
return false;
}
return true;
}
// ============================================================================
// E3: 知识产权 (Intellectual Property)
// ============================================================================
/// E3: 知识产权规则
///
/// 特点:
/// - 专利、版权、商标等
/// - 可授权使用
/// - 有地域限制
/// - 有时间限制
pub const RULE_E3: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::E3,
name: "知识产权",
description: "专利、版权、商标等无形资产权利",
required_fields: vec!["ip_holder", "ip_type", "registration_number", "jurisdiction", "expiry_date"],
constraints: vec![
RuleConstraint {
field_name: "ip_type",
constraint_type: ConstraintType::Required,
value: "IPType"
},
RuleConstraint {
field_name: "registration_number",
constraint_type: ConstraintType::Required,
value: "String"
}
],
on_transfer: TransferRule::RequireApproval,
on_revenue: RevenueRule::FullToOwner,
on_expire: ExpireRule::RequireRenewal
};
/// 知识产权类型
enum IPType {
Patent, // 专利
Copyright, // 版权
Trademark, // 商标
TradeSecret, // 商业秘密
Other // 其他
}
/// 验证E3规则
pub fn validate_e3(
ip_holder: Address,
ip_type: IPType,
registration_number: String,
jurisdiction: u8,
expiry_date: Timestamp
) -> bool {
// 检查持有人地址有效性
if !ip_holder.is_valid() {
return false;
}
// 检查注册号非空
if registration_number.is_empty() {
return false;
}
// 检查到期日期有效性
if expiry_date <= block.timestamp {
return false;
}
return true;
}
// ============================================================================
// F4: 临时监管权 (Temporary Custody)
// ============================================================================
/// F4: 临时监管权规则
///
/// 特点:
/// - 托管、监管期间
/// - 无处置权
/// - 有明确期限
/// - 必须返还
pub const RULE_F4: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::F4,
name: "临时监管权",
description: "临时托管或监管资产的权利",
required_fields: vec!["custodian", "original_owner", "asset_id", "custody_start", "custody_end", "custody_purpose"],
constraints: vec![
RuleConstraint {
field_name: "custody_end",
constraint_type: ConstraintType::Required,
value: "Timestamp"
},
RuleConstraint {
field_name: "custody_purpose",
constraint_type: ConstraintType::Required,
value: "String"
}
],
on_transfer: TransferRule::Prohibited,
on_revenue: RevenueRule::ToSpecificBeneficiary,
on_expire: ExpireRule::AutoRevoke
};
/// 验证F4规则
pub fn validate_f4(
custodian: Address,
original_owner: Address,
asset_id: Hash,
custody_start: Timestamp,
custody_end: Timestamp,
custody_purpose: String
) -> bool {
// 检查托管人地址有效性
if !custodian.is_valid() {
return false;
}
// 检查原所有者地址有效性
if !original_owner.is_valid() {
return false;
}
// 检查托管期限有效性
if custody_end <= custody_start {
return false;
}
// 检查托管目的非空
if custody_purpose.is_empty() {
return false;
}
return true;
}
// ============================================================================
// G5: 共有权 (Co-ownership)
// ============================================================================
/// G5: 共有权规则
///
/// 特点:
/// - 多方共同所有
/// - 按份额分配
/// - 重大决策需多数同意
/// - 收益按份额分配
pub const RULE_G5: SovereigntyRule = SovereigntyRule {
sovereignty_type: SovereigntyType::G5,
name: "共有权",
description: "多方共同拥有资产的权利",
required_fields: vec!["co_owners", "ownership_shares", "decision_threshold"],
constraints: vec![
RuleConstraint {
field_name: "co_owners",
constraint_type: ConstraintType::MinValue,
value: "2" // 至少2个共有人
},
RuleConstraint {
field_name: "decision_threshold",
constraint_type: ConstraintType::MinValue,
value: "5000" // 至少50%同意
}
],
on_transfer: TransferRule::RequireMultiSig,
on_revenue: RevenueRule::DistributeByShares,
on_expire: ExpireRule::NoExpiry
};
/// 共有人份额
struct OwnershipShare {
owner: Address,
share: u16 // 基点0-10000
}
/// 验证G5规则
pub fn validate_g5(
co_owners: Vec<OwnershipShare>,
decision_threshold: u16 // 基点5000-10000
) -> bool {
// 检查共有人数量至少2人
if co_owners.len() < 2 {
return false;
}
// 检查决策阈值有效性50%-100%
if decision_threshold < 5000 || decision_threshold > 10000 {
return false;
}
// 检查份额总和是否为100%
let mut total_share: u32 = 0;
for share in co_owners {
if !share.owner.is_valid() {
return false;
}
total_share += share.share as u32;
}
if total_share != 10000 {
return false;
}
return true;
}
// ============================================================================
// 辅助函数
// ============================================================================
/// 获取主权规则
pub fn get_sovereignty_rule(sovereignty_type: SovereigntyType) -> SovereigntyRule {
match sovereignty_type {
SovereigntyType::A0 => RULE_A0,
SovereigntyType::B1 => RULE_B1,
SovereigntyType::C2 => RULE_C2,
SovereigntyType::D0 => RULE_D0,
SovereigntyType::E3 => RULE_E3,
SovereigntyType::F4 => RULE_F4,
SovereigntyType::G5 => RULE_G5
}
}
/// 验证主权规则
pub fn validate_sovereignty(
sovereignty_type: SovereigntyType,
data: Map<String, Any>
) -> bool {
match sovereignty_type {
SovereigntyType::A0 => validate_a0(
data.get("owner"),
data.get("asset_id"),
data.get("gnacs_code")
),
SovereigntyType::B1 => validate_b1(
data.get("user"),
data.get("asset_id"),
data.get("start_time"),
data.get("end_time"),
data.get("usage_scope")
),
SovereigntyType::C2 => validate_c2(
data.get("beneficiary"),
data.get("asset_id"),
data.get("revenue_share"),
data.get("start_time")
),
SovereigntyType::D0 => validate_d0(
data.get("collateral_asset"),
data.get("beneficiary"),
data.get("amount"),
data.get("term"),
data.get("liquidation_conditions")
),
SovereigntyType::E3 => validate_e3(
data.get("ip_holder"),
data.get("ip_type"),
data.get("registration_number"),
data.get("jurisdiction"),
data.get("expiry_date")
),
SovereigntyType::F4 => validate_f4(
data.get("custodian"),
data.get("original_owner"),
data.get("asset_id"),
data.get("custody_start"),
data.get("custody_end"),
data.get("custody_purpose")
),
SovereigntyType::G5 => validate_g5(
data.get("co_owners"),
data.get("decision_threshold")
)
}
}

View File

@ -4,11 +4,13 @@ pub fn safe_add(a: u256, b: u256) -> u256 {
return result;
}
pub fn safe_sub(a: u256, b: u256) -> u256 {
require(a >= b, "Subtraction underflow");
return a - b;
}
pub fn safe_mul(a: u256, b: u256) -> u256 {
if a == 0 {
return 0;
@ -18,15 +20,19 @@ pub fn safe_mul(a: u256, b: u256) -> u256 {
return result;
}
pub fn safe_div(a: u256, b: u256) -> u256 {
require(b > 0, "Division by zero");
return a / b;
}
pub fn max(a: u256, b: u256) -> u256 {
return if a >= b { a } else { b };
}
pub fn min(a: u256, b: u256) -> u256 {
return if a <= b { a } else { b };
}

BIN
charter-std/utils/math.nvm Normal file

Binary file not shown.