Skip to content
Logo

TRC721 tokens

TRC721 is ABI-compatible with ERC721. tronz includes a typed Trc721Instance, so standard NFT operations do not require a separate ABI file or generated binding.

use tronz::contract::Trc721Ext;

Binding to a collection

The extension trait adds .trc721() to every provider:

# async fn run(provider: impl tronz::TronProvider) -> anyhow::Result<()> {
use tronz::contract::Trc721Ext;
 
let collection: tronz::Address = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf".parse()?;
let nft = provider.trc721(collection);
# Ok(()) }

Reading NFT state

Reads are constant calls and do not require a signer:

use tronz::U256;
 
# async fn run(nft: tronz::contract::Trc721Instance<impl tronz::TronProvider>, owner: tronz::Address) -> anyhow::Result<()> {
let token_id = U256::from(1u64);
 
let name = nft.name().await?;
let symbol = nft.symbol().await?;
let balance = nft.balance_of(owner).await?;
let token_owner = nft.owner_of(token_id).await?;
let uri = nft.token_uri(token_id).await?;
# Ok(()) }

Approval reads are available through get_approved(token_id) and is_approved_for_all(owner, operator).

Transferring an NFT

Writes require a signer-backed provider with TAPOS and a fee limit:

use tronz::U256;
 
# async fn run(nft: tronz::contract::Trc721Instance<impl tronz::TronProvider>, from: tronz::Address, to: tronz::Address) -> anyhow::Result<()> {
let pending = nft.transfer_from(from, to, U256::from(1u64)).await?;
let receipt = pending.get_receipt().await?;
# Ok(()) }

Use safe_transfer_from when the recipient may be a smart contract. It invokes the recipient's ERC721 receiver hook and reverts if the contract cannot accept the token.

Approvals

Approve a spender for one token:

# async fn run(nft: tronz::contract::Trc721Instance<impl tronz::TronProvider>, spender: tronz::Address) -> anyhow::Result<()> {
nft.approve(spender, tronz::U256::from(1u64)).await?;
# Ok(()) }

Or approve/revoke an operator for all of the owner's tokens:

# async fn run(nft: tronz::contract::Trc721Instance<impl tronz::TronProvider>, operator: tronz::Address) -> anyhow::Result<()> {
nft.set_approval_for_all(operator, true).await?;
# Ok(()) }

After any contract write, inspect both the transaction status and contract_result; inclusion on-chain does not guarantee successful TVM execution.

See the runnable examples for queries, transfers, and approvals.