NAC_Blockchain/_archive/v1_legacy_nrpc3/bak_files/acc721.rs.bak2

522 lines
17 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! ACC-721: 唯一资产证书协议接口
//!
//! 提供与NAC区块链上ACC-721证书交互的客户端接口
use crate::client::NRPC3Client;
use crate::error::{NACError, Result};
use crate::types::*;
use nac_udm::primitives::{Address, Hash, Timestamp};
use nac_udm::l1_protocol::gnacs::GNACSCode;
use nac_udm::l1_protocol::acc::acc721::{
AssetId, SovereigntyType, AssetDNA, AssetValuation,
CustodyInfo, InsuranceInfo, CollateralInfo, FragmentationPool,
};
use serde_json::json;
/// ACC-721唯一资产证书接口
pub struct ACC721 {
client: NRPC3Client,
}
impl ACC721 {
/// 创建新的ACC-721接口实例
pub fn new(client: NRPC3Client) -> Self {
Self { client }
}
/// 获取资产持有者
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 资产持有者地址
pub async fn get_asset_holder(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<Address> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getAssetHolder", params).await?;
let holder_hex = response["result"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing holder address".to_string()))?;
Address::from_hex(holder_hex)
.map_err(|e| NACError::InvalidAddress(format!("Invalid holder address: {}", e)))
}
/// 铸造唯一资产
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `to` - 接收者地址
/// * `asset_id` - 资产ID
/// * `metadata_uri` - 资产元数据URI
/// * `physical_fingerprint` - 物理指纹哈希
/// * `legal_document_hash` - 法律文件哈希
/// * `custodian` - 托管方地址
/// * `insurer` - 保险方地址
/// * `insurance_coverage` - 保险金额XTZH
/// * `insurance_expiry` - 保险到期时间
///
/// # 返回
/// 资产DNA
pub async fn mint_asset(
&self,
certificate_address: &Address,
to: &Address,
asset_id: AssetId,
metadata_uri: String,
physical_fingerprint: Hash,
legal_document_hash: Hash,
custodian: Address,
insurer: Address,
insurance_coverage: u128,
insurance_expiry: Timestamp,
) -> Result<AssetDNA> {
let params = json!({
"certificate_address": certificate_address,
"to": to,
"asset_id": asset_id,
"metadata_uri": metadata_uri,
"physical_fingerprint": physical_fingerprint,
"legal_document_hash": legal_document_hash,
"custodian": custodian,
"insurer": insurer,
"insurance_coverage": insurance_coverage,
"insurance_expiry": insurance_expiry,
});
let response = self.client.call("acc721_mintAsset", params).await?;
// 解析AssetDNA
let dna_data = &response["result"];
let asset_dna = AssetDNA {
dna_hash: Hash::from_hex(
dna_data["dna_hash"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
)?,
physical_fingerprint,
legal_document_hash,
generated_at: Timestamp::from_secs(
dna_data["generated_at"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
),
};
Ok(asset_dna)
}
/// 转移唯一资产
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `from` - 发送者地址
/// * `to` - 接收者地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 宪法收据哈希
pub async fn transfer_asset(
&self,
certificate_address: &Address,
from: &Address,
to: &Address,
asset_id: AssetId,
) -> Result<Hash> {
let params = json!({
"certificate_address": certificate_address,
"from": from,
"to": to,
"asset_id": asset_id,
});
let response = self.client.call("acc721_transferAsset", params).await?;
let receipt_hash = response["result"]["constitutional_receipt"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing constitutional_receipt".to_string()))?;
Hash::from_hex(receipt_hash)
.map_err(|e| NACError::InvalidHash(format!("Invalid receipt hash: {}", e)))
}
/// 授权资产
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `owner` - 资产持有者地址
/// * `approved` - 被授权者地址
/// * `asset_id` - 资产ID
pub async fn approve_asset(
&self,
certificate_address: &Address,
owner: &Address,
approved: &Address,
asset_id: AssetId,
) -> Result<()> {
let params = json!({
"certificate_address": certificate_address,
"owner": owner,
"approved": approved,
"asset_id": asset_id,
});
self.client.call("acc721_approveAsset", params).await?;
Ok(())
}
/// 销毁资产
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `owner` - 资产持有者地址
/// * `asset_id` - 资产ID
pub async fn burn_asset(
&self,
certificate_address: &Address,
owner: &Address,
asset_id: AssetId,
) -> Result<()> {
let params = json!({
"certificate_address": certificate_address,
"owner": owner,
"asset_id": asset_id,
});
self.client.call("acc721_burnAsset", params).await?;
Ok(())
}
/// 碎片化资产
///
/// 将唯一资产碎片化为多个ACC-20代币
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `owner` - 资产持有者地址
/// * `asset_id` - 资产ID
/// * `fragment_count` - 碎片总数
/// * `fragment_price` - 碎片价格XTZH
///
/// # 返回
/// 碎片化池信息
pub async fn fragmentize_asset(
&self,
certificate_address: &Address,
owner: &Address,
asset_id: AssetId,
fragment_count: u64,
fragment_price: u128,
) -> Result<FragmentationPool> {
let params = json!({
"certificate_address": certificate_address,
"owner": owner,
"asset_id": asset_id,
"fragment_count": fragment_count,
"fragment_price": fragment_price,
});
let response = self.client.call("acc721_fragmentizeAsset", params).await?;
// 解析FragmentationPool
let pool_data = &response["result"];
let pool = FragmentationPool {
fragment_token_address: Address::from_hex(
pool_data["fragment_token_address"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing fragment_token_address".to_string()))?
)?,
total_fragments: pool_data["total_fragments"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing total_fragments".to_string()))?,
fragment_price_xtzh: pool_data["fragment_price_xtzh"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing fragment_price_xtzh".to_string()))?
.parse()
.map_err(|e| NACError::InvalidResponse(format!("Invalid fragment_price: {}", e)))?,
fragmentized_at: Timestamp::from_secs(
pool_data["fragmentized_at"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing fragmentized_at".to_string()))?
),
is_recomposable: pool_data["is_recomposable"]
.as_bool()
.ok_or(NACError::InvalidResponse("Missing is_recomposable".to_string()))?,
};
Ok(pool)
}
/// 更新资产估值
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
/// * `valuation` - 新的资产估值
pub async fn update_valuation(
&self,
certificate_address: &Address,
asset_id: AssetId,
valuation: AssetValuation,
) -> Result<()> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
"valuation": {
"value_xtzh": valuation.value_xtzh.to_string(),
"valuation_provider": valuation.valuation_provider,
"valued_at": valuation.valued_at.as_secs(),
"validity_period": valuation.validity_period,
},
});
self.client.call("acc721_updateValuation", params).await?;
Ok(())
}
/// 获取资产估值
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 资产估值
pub async fn get_asset_valuation(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<AssetValuation> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getAssetValuation", params).await?;
// 解析AssetValuation
let val_data = &response["result"];
let valuation = AssetValuation {
value_xtzh: val_data["value_xtzh"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing value_xtzh".to_string()))?
.parse()
.map_err(|e| NACError::InvalidResponse(format!("Invalid value_xtzh: {}", e)))?,
valuation_provider: Address::from_hex(
val_data["valuation_provider"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing valuation_provider".to_string()))?
)?,
valued_at: Timestamp::from_secs(
val_data["valued_at"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing valued_at".to_string()))?
),
validity_period: val_data["validity_period"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing validity_period".to_string()))?,
};
Ok(valuation)
}
/// 获取资产DNA
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 资产DNA
pub async fn get_asset_dna(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<AssetDNA> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getAssetDNA", params).await?;
// 解析AssetDNA
let dna_data = &response["result"];
let asset_dna = AssetDNA {
dna_hash: Hash::from_hex(
dna_data["dna_hash"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
)?,
physical_fingerprint: Hash::from_hex(
dna_data["physical_fingerprint"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing physical_fingerprint".to_string()))?
)?,
legal_document_hash: Hash::from_hex(
dna_data["legal_document_hash"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing legal_document_hash".to_string()))?
)?,
generated_at: Timestamp::from_secs(
dna_data["generated_at"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
),
};
Ok(asset_dna)
}
/// 获取资产元数据
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 资产元数据URI
pub async fn get_asset_metadata(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<String> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getAssetMetadata", params).await?;
let metadata_uri = response["result"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing metadata URI".to_string()))?
.to_string();
Ok(metadata_uri)
}
/// 获取托管信息
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 托管信息
pub async fn get_custody_info(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<CustodyInfo> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getCustodyInfo", params).await?;
// 解析CustodyInfo
let custody_data = &response["result"];
let custody_info = CustodyInfo {
custodian: Address::from_hex(
custody_data["custodian"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing custodian".to_string()))?
)?,
custody_start: Timestamp::from_secs(
custody_data["custody_start"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing custody_start".to_string()))?
),
is_active: custody_data["is_active"]
.as_bool()
.ok_or(NACError::InvalidResponse("Missing is_active".to_string()))?,
custody_proof: Hash::from_hex(
custody_data["custody_proof"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing custody_proof".to_string()))?
)?,
};
Ok(custody_info)
}
/// 获取保险信息
///
/// # 参数
/// * `certificate_address` - 证书地址
/// * `asset_id` - 资产ID
///
/// # 返回
/// 保险信息
pub async fn get_insurance_info(
&self,
certificate_address: &Address,
asset_id: AssetId,
) -> Result<InsuranceInfo> {
let params = json!({
"certificate_address": certificate_address,
"asset_id": asset_id,
});
let response = self.client.call("acc721_getInsuranceInfo", params).await?;
// 解析InsuranceInfo
let insurance_data = &response["result"];
let insurance_info = InsuranceInfo {
insurer: Address::from_hex(
insurance_data["insurer"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing insurer".to_string()))?
)?,
coverage_xtzh: insurance_data["coverage_xtzh"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing coverage_xtzh".to_string()))?
.parse()
.map_err(|e| NACError::InvalidResponse(format!("Invalid coverage_xtzh: {}", e)))?,
insurance_start: Timestamp::from_secs(
insurance_data["insurance_start"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing insurance_start".to_string()))?
),
insurance_expiry: Timestamp::from_secs(
insurance_data["insurance_expiry"]
.as_u64()
.ok_or(NACError::InvalidResponse("Missing insurance_expiry".to_string()))?
),
policy_number: insurance_data["policy_number"]
.as_str()
.ok_or(NACError::InvalidResponse("Missing policy_number".to_string()))?
.to_string(),
};
Ok(insurance_info)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_acc721_interface() {
// 这里只是接口测试实际需要连接到NAC节点
let client = NRPC3Client::new("https://rpc.newassetchain.io");
let acc721 = ACC721::new(client);
// 测试将在实际连接到NAC节点后进行
assert!(true);
}
}