12 KiB
12 KiB
ACC-20C: 兼容层协议使用指南
概述
ACC-20C是NAC与以太坊生态之间的战略性桥梁,而非妥协。它提供双向包装机制,让NAC原生的ACC-20资产能够在以太坊生态(OpenSea等)中流通,同时保留NAC的合规特性。
核心理念
NAC是核心,ACC-20C是流动性入口
为什么需要ACC-20C?
-
现实情况
- 以太坊生态拥有数百万用户和成熟基础设施
- NAC是新生态,需要冷启动
- 完全隔离会导致流动性不足
-
战略价值
- 短期(1-2年): 让ACC-20资产在OpenSea等市场流通
- 中期(2-3年): 逐步引导用户使用NAC原生工具
- 长期(3年+): ACC-20C变成可选而非必需
-
合规不妥协
- 即使包装成ERC-721,仍保留KYC/AML检查
- 合规状态在NAC链上验证
- 冻结机制跨链同步
架构
┌─────────────────────────────────────────────────────────┐
│ NAC原生生态(核心) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ ACC-20 Enhanced + GNACS + 主权管理 + 合规引擎 │ │
│ └──────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ ACC-20C兼容层(战略桥梁) │ │
│ │ - 包装器合约 │ │
│ │ - 状态同步引擎 │ │
│ │ - 元数据生成器 │ │
│ │ - 权限代理系统 │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
↕
┌─────────────────────────────────────────────────────────┐
│ 以太坊生态(流动性来源) │
│ ERC-721标准 + OpenSea + MetaMask + DeFi协议 │
└─────────────────────────────────────────────────────────┘
核心组件
1. 包装器合约(Wrapper)
- 锁定ACC-20资产
- 铸造ERC-721 NFT
- 管理包装/解包装流程
2. 状态同步引擎(SyncEngine)
- 监听两条链的事件
- 同步状态变更
- 处理跨链消息
3. 元数据生成器(MetadataGenerator)
- 生成ERC-721元数据
- 包含GNACS信息
- 符合OpenSea标准
4. 权限代理系统(PermissionProxy)
- 跨链权限验证
- 合规检查代理
- 主权规则验证
使用流程
包装(Wrap)
1. 用户在NAC链上调用wrap()
2. 锁定ACC-20资产
3. 生成包装记录
4. 同步引擎监听事件
5. 在以太坊链铸造ERC-721
6. 用户可在OpenSea交易
解包装(Unwrap)
1. 用户在以太坊链销毁ERC-721
2. 同步引擎监听事件
3. 在NAC链验证合规性
4. 解锁ACC-20资产
5. 转回用户账户
快速开始
1. 添加依赖
[dependencies]
nac-sdk = "0.1.0"
nac-udm = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
2. 创建客户端
use nac_sdk::client::NacLensClient;
use nac_sdk::protocols::ACC20C;
let client = NacLensClient::new("https://rpc.newassetchain.io");
let acc20c = ACC20C::new(client);
3. 包装ACC-20为ERC-721
use nac_udm::primitives::Address;
use nac_udm::l1_protocol::acc20c::EthAddress;
// 准备地址
let wrapper_address = Address::from_hex("0x1234...")?;
let nac_owner = Address::from_hex("0x2234...")?;
let eth_recipient = EthAddress([0u8; 20]); // 以太坊地址
// 包装
let amount = 5_000_000_000_000_000_000u128; // 5 ACC-20
let token_id = acc20c.wrap(
&wrapper_address,
&nac_owner,
ð_recipient,
amount,
).await?;
println!("ERC-721 Token ID: {}", token_id.low);
4. 解包装ERC-721为ACC-20
let nac_recipient = Address::from_hex("0x3234...")?;
let unwrapped_amount = acc20c.unwrap(
&wrapper_address,
token_id,
ð_recipient,
&nac_recipient,
).await?;
println!("Unwrapped amount: {}", unwrapped_amount);
API参考
包装/解包装操作
wrap
包装ACC-20为ERC-721
pub async fn wrap(
&self,
wrapper_address: &Address,
owner: &Address,
eth_recipient: &EthAddress,
amount: u128,
) -> Result<u256>
参数:
wrapper_address- 包装器合约地址owner- NAC链上的所有者地址eth_recipient- 以太坊链上的接收者地址amount- 包装数量
返回:ERC-721 Token ID
unwrap
解包装ERC-721为ACC-20
pub async fn unwrap(
&self,
wrapper_address: &Address,
token_id: u256,
eth_owner: &EthAddress,
nac_recipient: &Address,
) -> Result<u128>
参数:
wrapper_address- 包装器合约地址token_id- ERC-721 Token IDeth_owner- 以太坊链上的所有者地址nac_recipient- NAC链上的接收者地址
返回:解包装的ACC-20数量
查询方法
get_wrapped_asset
查询包装资产信息
pub async fn get_wrapped_asset(
&self,
wrapper_address: &Address,
token_id: u256,
) -> Result<WrappedAsset>
get_locked_holdings
查询锁定的持有量
pub async fn get_locked_holdings(
&self,
wrapper_address: &Address,
owner: &Address,
) -> Result<u128>
get_wrapper_config
查询包装器配置
pub async fn get_wrapper_config(
&self,
wrapper_address: &Address,
) -> Result<WrapperConfig>
get_wrapper_status
查询包装器状态
pub async fn get_wrapper_status(
&self,
wrapper_address: &Address,
) -> Result<WrapperStatus>
get_metadata_uri
获取元数据URI
pub async fn get_metadata_uri(
&self,
wrapper_address: &Address,
token_id: u256,
) -> Result<String>
管理方法
freeze_wrapped_asset
冻结包装资产
pub async fn freeze_wrapped_asset(
&self,
wrapper_address: &Address,
token_id: u256,
) -> Result<()>
unfreeze_wrapped_asset
解冻包装资产
pub async fn unfreeze_wrapped_asset(
&self,
wrapper_address: &Address,
token_id: u256,
) -> Result<()>
手续费计算
calculate_wrap_fee
计算包装手续费
pub async fn calculate_wrap_fee(
&self,
wrapper_address: &Address,
amount: u128,
) -> Result<u128>
calculate_unwrap_fee
计算解包装手续费
pub async fn calculate_unwrap_fee(
&self,
wrapper_address: &Address,
amount: u128,
) -> Result<u128>
数据结构
WrappedAsset
包装后的资产
pub struct WrappedAsset {
pub token_id: u256,
pub original_holdings: u128,
pub original_owner: Address,
pub current_owner: EthAddress,
pub gnacs_code: GNACSCode,
pub wrapped_at: Timestamp,
pub metadata_uri: String,
pub compliance_snapshot: ComplianceSnapshot,
pub status: WrappedAssetStatus,
}
WrapperConfig
包装器配置
pub struct WrapperConfig {
pub acc20_per_nft: u128,
pub allow_partial_wrap: bool,
pub wrap_fee_bps: u16,
pub unwrap_fee_bps: u16,
pub fee_recipient: Address,
pub preserve_compliance: bool,
pub min_wrap_amount: u128,
pub max_wrap_amount: u128,
}
ComplianceSnapshot
合规快照
pub struct ComplianceSnapshot {
pub kyc_level: u8,
pub aml_status: u8,
pub compliance_level: u8,
pub jurisdiction: u8,
pub snapshot_at: Timestamp,
pub snapshot_hash: Hash,
}
完整示例
跨链流程示例
use nac_sdk::client::NacLensClient;
use nac_sdk::protocols::ACC20C;
use nac_udm::primitives::Address;
use nac_udm::l1_protocol::acc20c::EthAddress;
#[tokio::main]
async fn main() -> Result<()> {
// 1. 创建客户端
let client = NacLensClient::new("https://rpc.newassetchain.io");
let acc20c = ACC20C::new(client);
// 2. 准备地址
let wrapper_address = Address::from_hex("0x1234...")?;
let nac_owner = Address::from_hex("0x2234...")?;
let eth_trader = EthAddress([0x33; 20]);
// 3. 包装ACC-20
let amount = 5_000_000_000_000_000_000u128;
let token_id = acc20c.wrap(
&wrapper_address,
&nac_owner,
ð_trader,
amount,
).await?;
println!("✓ Wrapped: Token ID {}", token_id.low);
// 4. 在OpenSea交易(模拟)
let new_eth_owner = EthAddress([0x44; 20]);
println!("✓ Traded on OpenSea");
// 5. 解包装回NAC
let new_nac_owner = Address::from_hex("0x3234...")?;
let unwrapped = acc20c.unwrap(
&wrapper_address,
token_id,
&new_eth_owner,
&new_nac_owner,
).await?;
println!("✓ Unwrapped: {} ACC-20", unwrapped);
Ok(())
}
最佳实践
1. 包装前检查
- 验证包装器状态是否为Active
- 检查包装数量是否在允许范围内
- 计算手续费,确保用户了解成本
2. 合规保留
- 包装前确保通过KYC/AML检查
- 定期验证合规快照
- 发现问题及时冻结资产
3. 手续费管理
- 使用基点(bps)计算手续费:1基点 = 0.01%
- 包装和解包装都会收取手续费
- 手续费由包装器配置决定
4. 状态同步
- 包装后等待同步引擎确认
- 解包装前验证ERC-721所有权
- 监听跨链事件确保状态一致
5. 元数据管理
- 元数据URI符合ERC-721标准
- 包含GNACS编码信息
- 在OpenSea上正确显示
与ERC-721的对比
| 特性 | 标准ERC-721 | ACC-20C包装的ERC-721 |
|---|---|---|
| 基础功能 | ✅ | ✅ |
| 合规检查 | ❌ | ✅ |
| 冻结机制 | ❌ | ✅ |
| GNACS编码 | ❌ | ✅ |
| 合规快照 | ❌ | ✅ |
| 双向包装 | ❌ | ✅ |
| 跨链同步 | ❌ | ✅ |
错误处理
use nac_sdk::error::{NACError, Result};
match acc20c.wrap(&wrapper_address, &owner, ð_recipient, amount).await {
Ok(token_id) => println!("Success: {}", token_id.low),
Err(NACError::InvalidAddress(e)) => eprintln!("Invalid address: {}", e),
Err(NACError::InvalidResponse(e)) => eprintln!("Invalid response: {}", e),
Err(e) => eprintln!("Error: {:?}", e),
}
测试
运行单元测试:
cargo test acc20c
运行集成测试(需要NAC节点和以太坊测试网):
cargo test --test acc20c_integration_test -- --ignored
示例代码
完整的示例代码请参考:examples/acc20c_example.rs
运行示例:
cargo run --example acc20c_example
重要说明
⚠️ ACC-20C不是NAC的核心,而是生态扩展
- NAC的核心是ACC-20 Enhanced + GNACS + 主权管理
- ACC-20C只是为了冷启动和流动性
- 随着NAC生态成熟,ACC-20C的重要性会逐渐降低
- 最终目标是建立完全独立的NAC原生生态
相关资源
许可证
MIT License