Hosting NFT metadata on BTFS
Upload your NFT image and metadata JSON to BTFS — TRON's decentralized file network — and use the resulting URIs as your tokenURI.
Prerequisites
BitTorrent File System (BTFS) is a decentralized file-sharing protocol built on the TRON network and the BitTorrent ecosystem. NFT metadata — JSON files describing each token's name, image, and attributes — is stored off-chain and referenced by URI from the contract's tokenURI function. BTFS provides one option for hosting that metadata in a way that does not depend on a single web host staying online.
This guide walks you through uploading both an image and a metadata JSON to BTFS, getting the URIs you can plug into your TRC-721 contract.
Where to host metadata: BTFS vs alternatives
| Option | Cost | Persistence | Decentralization |
|---|---|---|---|
| BTFS | Pay in BTT per MB per month | As long as BTT is paid | Decentralized over BTFS network |
| IPFS + pinning service (e.g., Pinata) | Subscription or pay-per-pin | As long as pinned | Decentralized over IPFS network |
| Arweave | One-time payment for permanent storage | Permanent | Decentralized |
| Self-hosted CDN | Hosting fee | As long as you maintain the host | Centralized |
BTFS is a natural choice within the TRON ecosystem.
Step 1 — Install and initialize BTFS
For installation steps, follow the BTFS installation instructions.
When btfs init initializes the local node, the command generates a TRON wallet account associated with the node. Check the TRON address corresponding to the wallet through btfs id.
Step 2 — Fund your BTFS node with BTT
Uploading files to BTFS uses BTT as the payment token. The current storage price is approximately 0.0037 BTT per MB per month (verify with the BTFS documentation for the latest rate). Files are split into 30 redundancy copies of which any 10 reconstruct the original — for the uploader this means the effective price is roughly 3 × 0.0037 BTT per MB per month.
First, deposit BTT into the node's TRON account, then transfer that BTT to the BTFS network's accounting system.
Set a wallet password
Set a password for the node wallet:
btfs wallet password <YOUR_PASSWORD>Deposit BTT to the BTFS accounting system
The following command transfers BTT from the local BTFS node account to the BTFS network's accounting system. The minimum transfer amount is 10 BTT, and the unit is μBTT (1 BTT = 1,000,000 μBTT):
btfs wallet deposit -p <YOUR_PASSWORD> 10000000Step 3 — Upload the image
Step 3.1 — Add the image to your local node
Prepare an image file (this guide uses coral.jpeg). Add it to the local BTFS node using reed-Solomon chunking:
btfs add --chunker=reed-solomon coral.jpeg
The output includes a hash like QmUK9nwtLEiHBJ48HAZHNmSQ53U6ADbRhATxs2tomadwKw — copy this hash for the next step.
Step 3.2 — Upload to the BTFS network
Upload the file by hash:
btfs storage upload QmUK9nwtLEiHBJ48HAZHNmSQ53U6ADbRhATxs2tomadwKwWhen the btfs daemon window shows File storage successful, the upload has succeeded.
Step 3.3 — Verify the file is downloadable
Open the BTFS gateway URL in your browser:
https://gateway.btfs.io/btfs/QmUK9nwtLEiHBJ48HAZHNmSQ53U6ADbRhATxs2tomadwKw
If the image displays, the upload is complete and downloadable.
Step 4 — Construct the metadata JSON
Create a JSON file (this guide uses coral.json) following the TRC-721 metadata schema. Set the image field to the BTFS URL of the image you just uploaded:
{
"name": "Coral #1",
"description": "A unique TRC-721 collectible.",
"image": "https://gateway.btfs.io/btfs/QmUK9nwtLEiHBJ48HAZHNmSQ53U6ADbRhATxs2tomadwKw",
"attributes": [
{ "trait_type": "Color", "value": "Pink" },
{ "trait_type": "Rarity", "value": "Rare" }
]
}Step 5 — Upload the metadata JSON
Upload the JSON to BTFS the same way as the image — btfs add then btfs storage upload — to get a hash for the metadata file:
Open the metadata URI in the browser to confirm:
https://gateway.btfs.io/btfs/QmWq4cp588QD8tzrSxvPs2bGikDdKyA35BT3iysBcP1jFD
The browser should render the JSON content.
Step 6 — Use the URI as tokenURI when minting
tokenURI when mintingUse the metadata URL from Step 5 as the tokenURI argument when calling mintWithTokenURI on your deployed TRC-721 contract. See Issuing a TRC-721 token for the full minting flow.
Related resources
- TRC-721 — standard overview
- TRC-721 protocol interfaces — function and event reference for TRC-721
- Issuing a TRC-721 token — deployment and minting walkthrough
Updated 11 days ago