558 lines
14 KiB
Plaintext
558 lines
14 KiB
Plaintext
///! # 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;
|
||
}
|
||
|
||
// ============================================================================
|
||
// ACC-20事件定义
|
||
// ============================================================================
|
||
|
||
/// 转账事件
|
||
event Transfer {
|
||
from: Address,
|
||
to: Address,
|
||
amount: u256,
|
||
timestamp: Timestamp
|
||
}
|
||
|
||
/// 授权事件
|
||
event Approval {
|
||
owner: Address,
|
||
spender: Address,
|
||
amount: u256,
|
||
timestamp: Timestamp
|
||
}
|
||
|
||
/// 铸造事件
|
||
event Mint {
|
||
to: Address,
|
||
amount: u256,
|
||
timestamp: Timestamp
|
||
}
|
||
|
||
/// 销毁事件
|
||
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;
|
||
}
|
||
}
|