SAVITRI-721:NFT 标准
SAVITRI-721(SNT1 -- Savitri Non-Fungible Token)是 Savitri Network 的 NFT 标准,等同于以太坊的 ERC-721。每个代币拥有唯一 ID 和单一所有者。
接口
| 函数 | 参数 | 返回值 | 描述 |
|---|---|---|---|
balance_of | owner | u64 | 某地址拥有的 NFT 数量 |
owner_of | token_id | address | 特定代币的所有者 |
transfer_from | from, to, token_id | Result | 转移一个 NFT |
approve | to, token_id | Result | 授权地址转移代币 |
safe_transfer_from | from, to, token_id | Result | 带安全检查的转移 |
token_uri | token_id | String | 获取代币元数据 URI |
mint | to, token_id, uri | Result | 铸造新 NFT |
存储布局
| 槽范围 | 用途 | 派生方式 |
|---|---|---|
| 0-99 | BaseContract(保留) | 直接 |
| 100+ | 代币所有者 | keccak256(100 || token_id) |
| 200+ | 代币余额 | keccak256(200 || address) |
| 300+ | 代币授权 | keccak256(300 || token_id) |
| 400+ | 代币 URI | keccak256(400 || token_id) |
Keccak256 哈希防止类别之间的槽冲突(例如,token_id 100 不会与余额基础槽冲突)。
铸造 NFT
use savitri_contracts::contracts::standards::savitri721::SAVITRI721;
SAVITRI721::mint(
&mut contract_storage,
&storage,
&recipient, // [u8; 32]
42, // token_id: u64
"ipfs://Qm.../meta", // token URI
&mut event_system,
Some(&mut gas_meter),
)?;
转移
// Direct transfer
SAVITRI721::transfer_from(
&mut contract_storage,
&storage,
&from, // current owner
&to, // new owner
42, // token_id
&mut event_system,
Some(&mut gas_meter),
)?;
查询
// Who owns token #42?
let owner = SAVITRI721::owner_of(&contract_storage, &storage, 42)?;
// How many NFTs does this address own?
let count = SAVITRI721::balance_of(&contract_storage, &storage, &address)?;
// Get metadata URI
let uri = SAVITRI721::token_uri(&contract_storage, &storage, 42)?;
事件
| 事件 | 字段 | 描述 |
|---|---|---|
Transfer | from, to, token_id | NFT 已转移 |
Approval | owner, approved, token_id | 授权已授予 |
Mint | to, token_id | 新 NFT 已铸造 |
通过 SDK
use savitri_sdk::{ContractClient, Wallet};
let contract = ContractClient::from_url_and_wallet("http://localhost:8545", wallet)?;
// Mint NFT via contract call
let tx = contract.call_contract(
&nft_contract_address,
b"mint",
&encode_mint_args(recipient, token_id, uri),
Some(0),
).await?;