· Nacho Coll · Guides · 9 min di lettura
Archiviazione dei metadati NFT: La guida completa a IPFS per i creatori di NFT
Guida passo passo per archiviare i metadati NFT su IPFS. Include i pattern tokenURI ERC-721, esempi in Python e JavaScript.

Creare NFT richiede più del semplice deployment di smart contract — hai bisogno di uno storage decentralizzato e affidabile per i tuoi metadati e asset. Questa guida completa ti accompagna passo passo nell’archiviazione di metadati NFT su IPFS utilizzando le migliori pratiche del settore, con esempi di codice per sviluppatori Python e JavaScript.

Perché IPFS per l’archiviazione dei metadati NFT?
L’hosting web tradizionale crea rischi di centralizzazione per i progetti NFT. Quando i metadati risiedono su server convenzionali, gli NFT possono “rompersi” se il servizio di hosting va in tilt o cambia gli URL. IPFS (InterPlanetary File System) risolve questo problema fornendo:
- Indirizzamento immutabile del contenuto: Ogni file ottiene un Content Identifier (CID) unico che non cambia mai
- Archiviazione decentralizzata: Il contenuto esiste su più nodi nel mondo
- Verifica crittografica: L’integrità del file è garantita tramite hashing del contenuto
- URL a prova di futuro: I link IPFS funzionano indefinitamente, proteggendo il valore a lungo termine
Per una comprensione più approfondita dei fondamenti di IPFS, dai un’occhiata alla nostra guida cos’è l’IPFS pinning.
Comprendere la struttura dei metadati ERC-721
Lo standard ERC-721 definisce come dovrebbero essere strutturati i metadati NFT. La funzione tokenURI del tuo smart contract restituisce un URL che punta a metadati JSON seguenti questo pattern:
{
"name": "My Amazing NFT #1",
"description": "A unique digital artwork showcasing...",
"image": "ipfs://QmYourImageCIDHere",
"attributes": [
{
"trait_type": "Background",
"value": "Blue"
},
{
"trait_type": "Rarity",
"value": "Common"
}
],
"external_url": "https://yourproject.com/token/1"
}Campi chiave dei metadati
- name: Il titolo dell’NFT mostrato nei wallet e nei marketplace
- description: Informazioni dettagliate sull’NFT
- image: URL IPFS verso l’asset visivo principale
- attributes: Proprietà basate sui tratti per filtraggio e calcoli di rarità
- external_url: Link opzionale a contenuti aggiuntivi o al sito web del tuo progetto
Processo passo passo di archiviazione NFT su IPFS
Passo 1: Prepara i tuoi asset e metadati
Prima di caricare qualsiasi cosa, organizza i tuoi file:
- Asset principali: Immagini, video o altri contenuti primari
- File di metadati: File JSON che descrivono ogni NFT
- Metadati della collezione: Informazioni opzionali a livello di collezione
Passo 2: Carica gli asset su IPFS
Inizia caricando i tuoi asset NFT principali (immagini, video, ecc.) per ottenere i loro CID IPFS. Farai riferimento a questi CID nei tuoi file JSON di metadati.
Ecco come caricare un’immagine usando Python:
import requests
import base64
import json
def upload_image_to_ipfs(image_path, api_key):
"""Upload an image file to IPFS and return its CID"""
# Read and encode image
with open(image_path, 'rb') as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
# Prepare upload payload
payload = {
"content": image_data,
"description": f"NFT Asset: {image_path}"
}
headers = {
"Content-Type": "application/json",
"X-Api-Key": api_key
}
# Upload to IPFS.NINJA
response = requests.post(
"https://api.ipfs.ninja/upload/new",
headers=headers,
json=payload
)
if response.status_code == 200:
result = response.json()
print(f"✅ Image uploaded successfully!")
print(f"CID: {result['cid']}")
print(f"IPFS URL: {result['uris']['ipfs']}")
print(f"Gateway URL: {result['uris']['url']}")
return result['cid']
else:
print(f"❌ Upload failed: {response.text}")
return None
# Example usage
API_KEY = "bws_1234567890abcdef1234567890abcdef" # Replace with your actual key
image_cid = upload_image_to_ipfs("my-nft-artwork.png", API_KEY)Passo 3: Crea e carica il JSON dei metadati
Una volta ottenuti i CID dei tuoi asset, crea i file JSON dei metadati e caricali:
def create_and_upload_metadata(name, description, image_cid, attributes, api_key):
"""Create NFT metadata JSON and upload to IPFS"""
# Create metadata object
metadata = {
"name": name,
"description": description,
"image": f"ipfs://{image_cid}",
"attributes": attributes
}
# Convert to JSON string and encode
metadata_json = json.dumps(metadata, indent=2)
metadata_b64 = base64.b64encode(metadata_json.encode('utf-8')).decode('utf-8')
# Upload metadata
payload = {
"content": metadata_b64,
"description": f"NFT Metadata: {name}",
"metadata": {
"contentType": "application/json",
"nftTokenId": name.split('#')[1] if '#' in name else "1"
}
}
headers = {
"Content-Type": "application/json",
"X-Api-Key": api_key
}
response = requests.post(
"https://api.ipfs.ninja/upload/new",
headers=headers,
json=payload
)
if response.status_code == 200:
result = response.json()
print(f"✅ Metadata uploaded successfully!")
print(f"Metadata CID: {result['cid']}")
return result['cid']
else:
print(f"❌ Metadata upload failed: {response.text}")
return None
# Example usage
attributes = [
{"trait_type": "Background", "value": "Cosmic Blue"},
{"trait_type": "Eyes", "value": "Laser"},
{"trait_type": "Rarity", "value": "Epic"}
]
metadata_cid = create_and_upload_metadata(
name="Cosmic Warrior #001",
description="A fierce warrior from the distant galaxies, wielding the power of stars.",
image_cid=image_cid,
attributes=attributes,
api_key=API_KEY
)Passo 4: Implementazione in JavaScript
Per applicazioni web o progetti Node.js, ecco l’equivalente JavaScript:
class NFTStorage {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.ipfs.ninja';
}
async uploadFile(fileContent, description) {
const payload = {
content: fileContent, // base64 encoded
description: description
};
const response = await fetch(`${this.baseUrl}/upload/new`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': this.apiKey
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return await response.json();
}
async uploadImageFromFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async (e) => {
try {
const base64Content = e.target.result.split(',')[1]; // Remove data:image/...;base64, prefix
const result = await this.uploadFile(base64Content, `NFT Image: ${file.name}`);
resolve(result.cid);
} catch (error) {
reject(error);
}
};
reader.readAsDataURL(file);
});
}
async uploadMetadata(name, description, imageCid, attributes = []) {
const metadata = {
name,
description,
image: `ipfs://${imageCid}`,
attributes
};
const metadataJson = JSON.stringify(metadata, null, 2);
const base64Metadata = btoa(metadataJson);
const result = await this.uploadFile(base64Metadata, `NFT Metadata: ${name}`);
return result.cid;
}
}
// Usage example
const storage = new NFTStorage('bws_1234567890abcdef1234567890abcdef'); // Replace with your key
// Upload process
async function createNFT() {
try {
// Assuming you have a file input element
const fileInput = document.getElementById('nft-image');
const imageFile = fileInput.files[0];
console.log('Uploading image...');
const imageCid = await storage.uploadImageFromFile(imageFile);
console.log(`Image uploaded: ${imageCid}`);
console.log('Uploading metadata...');
const metadataCid = await storage.uploadMetadata(
'Galaxy Explorer #042',
'A mysterious explorer traversing the cosmic void.',
imageCid,
[
{ trait_type: 'Class', value: 'Explorer' },
{ trait_type: 'Galaxy', value: 'Andromeda' },
{ trait_type: 'Rarity', value: 'Legendary' }
]
);
console.log(`Metadata uploaded: ${metadataCid}`);
console.log(`Token URI: ipfs://${metadataCid}`);
} catch (error) {
console.error('Upload failed:', error);
}
}Implementare tokenURI nel tuo smart contract
Una volta che i tuoi metadati sono caricati su IPFS, implementa la funzione tokenURI nel tuo contratto ERC-721:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFTCollection is ERC721, Ownable {
mapping(uint256 => string) private _tokenURIs;
string private _baseTokenURI;
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function setTokenURI(uint256 tokenId, string memory uri) external onlyOwner {
require(_exists(tokenId), "Token does not exist");
_tokenURIs[tokenId] = uri;
}
function setBaseURI(string memory baseURI) external onlyOwner {
_baseTokenURI = baseURI;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string) {
require(_exists(tokenId), "Token does not exist");
string memory _tokenURI = _tokenURIs[tokenId];
// Return specific token URI if set
if (bytes(_tokenURI).length > 0) {
return _tokenURI;
}
// Fall back to base URI + token ID pattern
if (bytes(_baseTokenURI).length > 0) {
return string(abi.encodePacked(_baseTokenURI, tokenId.toString()));
}
return "";
}
function mintWithURI(address to, uint256 tokenId, string memory uri) external onlyOwner {
_mint(to, tokenId);
_tokenURIs[tokenId] = uri;
}
}Operazioni in batch per grandi collezioni
Per grandi collezioni NFT, le operazioni in batch fanno risparmiare tempo e costi di gas:
def batch_upload_collection(collection_data, api_key):
"""Upload an entire NFT collection in batches"""
print(f"Starting batch upload of {len(collection_data)} NFTs...")
results = []
for i, nft_data in enumerate(collection_data):
print(f"Processing NFT {i+1}/{len(collection_data)}: {nft_data['name']}")
try:
# Upload image
image_cid = upload_image_to_ipfs(nft_data['image_path'], api_key)
if image_cid:
# Upload metadata
metadata_cid = create_and_upload_metadata(
name=nft_data['name'],
description=nft_data['description'],
image_cid=image_cid,
attributes=nft_data['attributes'],
api_key=api_key
)
if metadata_cid:
results.append({
'token_id': i + 1,
'name': nft_data['name'],
'image_cid': image_cid,
'metadata_cid': metadata_cid,
'token_uri': f"ipfs://{metadata_cid}"
})
except Exception as e:
print(f"❌ Error processing {nft_data['name']}: {e}")
print(f"✅ Batch upload complete! {len(results)} NFTs processed successfully.")
return results
# Example collection data
collection_data = [
{
'name': 'Cosmic Warrior #001',
'description': 'A fierce warrior from distant galaxies.',
'image_path': 'images/warrior_001.png',
'attributes': [
{'trait_type': 'Class', 'value': 'Warrior'},
{'trait_type': 'Rarity', 'value': 'Epic'}
]
},
# Add more NFTs...
]
results = batch_upload_collection(collection_data, API_KEY)Migliori pratiche per l’archiviazione dei metadati NFT
1. Usa nomi di file descrittivi
Quando carichi su IPFS, usa descrizioni significative per aiutare con l’organizzazione:
payload = {
"content": base64_content,
"description": f"Collection: {collection_name} | Token: {token_id} | Type: {file_type}"
}2. Implementa una gestione degli errori adeguata
Gestisci sempre i fallimenti di upload in modo elegante:
import time
def upload_with_retry(upload_function, max_retries=3, delay=2):
"""Upload with exponential backoff retry logic"""
for attempt in range(max_retries):
try:
return upload_function()
except Exception as e:
if attempt == max_retries - 1:
raise e
print(f"Attempt {attempt + 1} failed: {e}. Retrying in {delay} seconds...")
time.sleep(delay)
delay *= 2 # Exponential backoff3. Valida la struttura dei metadati
Assicurati che i tuoi metadati rispettino gli standard:
def validate_metadata(metadata):
"""Validate NFT metadata structure"""
required_fields = ['name', 'description', 'image']
for field in required_fields:
if field not in metadata:
raise ValueError(f"Missing required field: {field}")
if not metadata['image'].startswith('ipfs://'):
raise ValueError("Image must be an IPFS URL")
if 'attributes' in metadata:
for attr in metadata['attributes']:
if 'trait_type' not in attr or 'value' not in attr:
raise ValueError("Invalid attribute structure")
return TrueScegliere il servizio di pinning IPFS giusto
Quando selezioni un servizio di pinning IPFS per il tuo progetto NFT, considera:
- Affidabilità: Tempo di attività garantito per archiviazione a lungo termine
- Performance: Velocità di recupero rapide in tutto il mondo
- Prezzo: Conveniente per le dimensioni della tua collezione
- Funzionalità: Capacità API, analytics e strumenti per sviluppatori
Per un confronto dettagliato dei servizi di pinning, leggi il nostro confronto IPFS Ninja vs Pinata e la nostra guida ai migliori servizi di pinning IPFS.
Funzionalità avanzate: Gateway personalizzati e analytics
IPFS Ninja offre funzionalità aggiuntive per progetti NFT professionali:
Configurazione di gateway personalizzato
Crea gateway IPFS brandizzati per la tua collezione:
// Access your NFT through a custom gateway
const customGateway = 'https://my-collection.gw.ipfs.ninja';
const nftUrl = `${customGateway}/ipfs/${metadataCid}`;Analytics di upload
Monitora l’utilizzo dello storage dei tuoi NFT e i pattern di accesso tramite l’analytics della dashboard, aiutandoti a capire le performance della collezione e ottimizzare i costi di storage.
Risolvere problemi comuni
I metadati non si caricano
- Verifica che gli URL IPFS usino il protocollo
ipfs:// - Controlla che il JSON dei metadati sia valido
- Assicurati che il servizio di pinning stia mantenendo il contenuto
Le immagini non vengono mostrate
- Conferma che i CID delle immagini siano corretti nei metadati
- Testa gli URL delle immagini nei gateway IPFS
- Verifica che i formati dei file immagine siano compatibili con il web
Errori di stima del gas
- Assicurati che la funzione
tokenURIrestituisca stringhe valide - Controlla riferimenti circolari nei metadati
- Valida tutti i CID IPFS prima del minting
Monitorare e mantenere il tuo storage NFT
Dopo aver distribuito la tua collezione:
- Controlli regolari dello stato: Verifica che metadati e immagini rimangano accessibili
- Backup dei CID importanti: Mantieni un registro di tutti gli identificatori di contenuto caricati
- Monitora le analytics: Tieni traccia dei pattern di accesso e dell’utilizzo dello storage
- Pianifica per la scala: Considera l’aggiornamento del tuo servizio di pinning man mano che la collezione cresce
Per maggiori dettagli sulla gestione programmatica degli upload, vedi il nostro tutorial dell’API di upload IPFS.
Conclusione
Archiviare i metadati NFT su IPFS garantisce che i tuoi asset digitali rimangano accessibili e di valore a lungo termine. Seguendo questa guida, hai imparato a:
- Strutturare metadati conformi a ERC-721
- Caricare asset e metadati usando Python e JavaScript
- Implementare funzioni
tokenURIappropriate - Gestire operazioni in batch per grandi collezioni
- Applicare le migliori pratiche per i deployment di produzione
La combinazione dell’architettura decentralizzata di IPFS e dei servizi di pinning affidabili crea le fondamenta per progetti NFT di successo che resistono alla prova del tempo.
Pronto per iniziare a fare pinning? Crea un account gratuito — 50 file, 1 GB di storage, 2 GB di banda/mese. Nessuna carta di credito richiesta.
