130 lines
4.8 KiB
Plaintext
130 lines
4.8 KiB
Plaintext
# ACC-20C 兼容层协议 - 元数据生成合约
|
|
# 版本: 1.0
|
|
# 路径: charter-std/acc/acc20c_metadata.ch
|
|
|
|
# --- 核心原则 ---
|
|
# 1. 动态生成: 元数据是动态生成的,反映底层 RWA 资产的最新状态。
|
|
# 2. 链上数据源: 所有元数据都来源于链上数据,或由预言机提供的、经过宪法验证的数据。
|
|
# 3. 标准兼容: 生成的元数据结构兼容 ERC-721 标准,并包含 ACC-20 的扩展属性。
|
|
|
|
# --- 标准库与接口导入 ---
|
|
import std::types::{ Address, Uint256, Uint64, Bool, String }
|
|
import std::json::{ to_json_string, JsonObject, JsonValue }
|
|
|
|
# 导入包装器合约接口,用于获取资产信息
|
|
import charter-std::acc::acc20c_wrapper::{ IAcc20CWrapper }
|
|
|
|
# 导入 ACC-20 资产信息接口(假定存在)
|
|
import charter-std::acc::i_acc20_info::{ IAcc20InfoProvider, RWAInfo }
|
|
|
|
# --- 合约状态定义 ---
|
|
state {
|
|
# 包装器合约的地址
|
|
wrapper_contract: Address,
|
|
# ACC-20 信息提供者合约的地址(例如,一个预言机聚合器)
|
|
info_provider: Address,
|
|
}
|
|
|
|
# --- 数据结构定义 ---
|
|
|
|
# ERC-721 标准元数据属性
|
|
struct Attribute {
|
|
trait_type: String,
|
|
value: String,
|
|
}
|
|
|
|
# ERC-721 标准元数据结构
|
|
struct Erc721Metadata {
|
|
name: String,
|
|
description: String,
|
|
image: String,
|
|
external_url: String,
|
|
attributes: Vec<Attribute>,
|
|
}
|
|
|
|
# --- 合约初始化 ---
|
|
|
|
fn constructor(wrapper_addr: Address, provider_addr: Address) {
|
|
state.wrapper_contract = wrapper_addr;
|
|
state.info_provider = provider_addr;
|
|
}
|
|
|
|
# --- 核心功能函数 ---
|
|
|
|
# @dev 为指定的包装资产生成完整的元数据 URI
|
|
# @param wrapper_token_id 包装资产的 ID
|
|
# @returns Base64 编码的 JSON 元数据字符串
|
|
fn token_uri(wrapper_token_id: Uint256) -> String {
|
|
let wrapper = IAcc20CWrapper(state.wrapper_contract);
|
|
let asset = wrapper.get_wrapped_asset(wrapper_token_id);
|
|
|
|
# 从信息提供者获取底层 RWA 的最新信息
|
|
let provider = IAcc20InfoProvider(state.info_provider);
|
|
let rwa_info = provider.get_rwa_info(asset.acc20_deed_address, asset.acc20_deed_token_id);
|
|
|
|
# 构建元数据
|
|
let metadata = build_metadata(wrapper_token_id, rwa_info);
|
|
|
|
# 将元数据结构序列化为 JSON 字符串
|
|
let json_string = serialize_metadata_to_json(metadata);
|
|
|
|
# 返回 Base64 编码的 Data URI
|
|
return to_data_uri(json_string, "application/json");
|
|
}
|
|
|
|
# --- 内部辅助函数 ---
|
|
|
|
# @dev 构建元数据结构体
|
|
fn build_metadata(wrapper_id: Uint256, rwa: RWAInfo) -> Erc721Metadata {
|
|
let mut attributes: Vec<Attribute> = Vec::new();
|
|
|
|
# 添加核心属性
|
|
attributes.push(Attribute { trait_type: "资产类型", value: rwa.asset_type });
|
|
attributes.push(Attribute { trait_type: "估值 (XTZH)", value: rwa.valuation.to_string() });
|
|
attributes.push(Attribute { trait_type: "风险等级", value: rwa.risk_level.to_string() });
|
|
attributes.push(Attribute { trait_type: "GNACS 编码", value: rwa.gnacs_code });
|
|
attributes.push(Attribute { trait_type: "上次估值时间", value: format_timestamp(rwa.last_valuation_time) });
|
|
|
|
return Erc721Metadata {
|
|
name: format!("NAC RWA #{} - {}", wrapper_id, rwa.asset_name),
|
|
description: rwa.description,
|
|
image: rwa.image_url, # 图像 URL 应指向 IPFS 或其他去中心化存储
|
|
external_url: format!("https://explorer.newassetchain.io/rwa/{}", wrapper_id),
|
|
attributes: attributes,
|
|
};
|
|
}
|
|
|
|
# @dev 将元数据结构序列化为 JSON 字符串
|
|
fn serialize_metadata_to_json(metadata: Erc721Metadata) -> String {
|
|
let mut root = JsonObject::new();
|
|
root.insert("name", JsonValue::String(metadata.name));
|
|
root.insert("description", JsonValue::String(metadata.description));
|
|
root.insert("image", JsonValue::String(metadata.image));
|
|
root.insert("external_url", JsonValue::String(metadata.external_url));
|
|
|
|
let mut attrs_array: Vec<JsonValue> = Vec::new();
|
|
for attr in metadata.attributes {
|
|
let mut attr_obj = JsonObject::new();
|
|
attr_obj.insert("trait_type", JsonValue::String(attr.trait_type));
|
|
attr_obj.insert("value", JsonValue::String(attr.value));
|
|
attrs_array.push(JsonValue::Object(attr_obj));
|
|
}
|
|
root.insert("attributes", JsonValue::Array(attrs_array));
|
|
|
|
return to_json_string(JsonValue::Object(root));
|
|
}
|
|
|
|
# @dev 将字符串转换为 Base64 编码的 Data URI
|
|
fn to_data_uri(content: String, mime_type: String) -> String {
|
|
# Charter 标准库应提供 base64 编码功能
|
|
let base64_content = std::crypto::base64_encode(content.as_bytes());
|
|
return format!("data:{};base64,{}", mime_type, base64_content);
|
|
}
|
|
|
|
# @dev 格式化时间戳
|
|
fn format_timestamp(timestamp: Uint64) -> String {
|
|
# 此处应调用标准库中的日期时间格式化函数
|
|
# 为简化,此处仅返回时间戳字符串
|
|
return timestamp.to_string();
|
|
}
|