· Nacho Coll · Guides · 8 min lasīšanas
NFT metadatu glabāšana: Pilnīga IPFS rokasgrāmata NFT veidotājiem
Soli pa solim rokasgrāmata NFT metadatu glabāšanai IPFS. Ietver ERC-721 tokenURI šablonus, Python un JavaScript piemērus.

NFT izveide prasa vairāk nekā tikai viedlīguma izvietošanu — jums ir nepieciešama uzticama, decentralizēta krātuve jūsu metadatiem un aktīviem. Šī visaptverošā rokasgrāmata soli pa solim pavada jūs cauri NFT metadatu glabāšanai IPFS, izmantojot nozares labākās prakses, ar pilnīgiem koda piemēriem Python un JavaScript izstrādātājiem.

Kāpēc IPFS NFT metadatu glabāšanai?
Tradicionālā tīmekļa mitināšana rada centralizācijas riskus NFT projektiem. Kad metadati atrodas tradicionālajos serveros, NFT var kļūt “salauzti”, ja mitināšanas pakalpojums sabrūk vai maina URL. IPFS (InterPlanetary File System) to atrisina, nodrošinot:
- Nemainīga satura adresācija: Katra datne saņem unikālu Content Identifier (CID), kas nekad nemainās
- Decentralizēta krātuve: Saturs eksistē vairākos mezglos visā pasaulē
- Kriptogrāfiskā pārbaude: Datnes integritāti garantē satura jaucējfunkcija
- Nākotnes drošas URL: IPFS saites darbojas neierobežoti, aizsargājot ilgtermiņa vērtību
Lai dziļāk izprastu IPFS pamatus, apskatiet mūsu rokasgrāmatu par to, kas ir IPFS pinning.
ERC-721 metadatu struktūras izpratne
ERC-721 standarts nosaka, kā jābūt strukturētiem NFT metadatiem. Jūsu viedlīguma tokenURI funkcija atgriež URL, kas norāda uz JSON metadatiem, ievērojot šo šablonu:
{
"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"
}Galvenie metadatu lauki
- name: NFT nosaukums, kas tiek parādīts makos un tirgos
- description: Detalizēta informācija par NFT
- image: IPFS URL uz galveno vizuālo aktīvu
- attributes: Uz iezīmēm balstītas īpašības filtrēšanai un retuma aprēķiniem
- external_url: Izvēles saite uz papildu saturu vai jūsu projekta vietni
Soli pa solim NFT glabāšanas process IPFS
1. solis: sagatavojiet savus aktīvus un metadatus
Pirms jebkā augšupielādēšanas sakārtojiet savus failus:
- Galvenie aktīvi: Attēli, video vai cits primārais saturs
- Metadatu faili: JSON faili, kas apraksta katru NFT
- Kolekcijas metadati: Izvēles informācija kolekcijas līmenī
2. solis: augšupielādējiet aktīvus IPFS
Sāciet, augšupielādējot savus galvenos NFT aktīvus (attēlus, video utt.), lai iegūtu to IPFS CID. Jūs atsauksieties uz šiem CID savos JSON metadatu failos.
Lūk, kā augšupielādēt attēlu, izmantojot 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)3. solis: izveidojiet un augšupielādējiet metadatu JSON
Kad jums ir aktīvu CID, izveidojiet metadatu JSON failus un augšupielādējiet tos:
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
)4. solis: JavaScript implementācija
Tīmekļa lietojumprogrammām vai Node.js projektiem šeit ir JavaScript ekvivalents:
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);
}
}tokenURI ieviešana jūsu viedlīgumā
Kad jūsu metadati ir augšupielādēti IPFS, ieviesiet tokenURI funkciju savā ERC-721 līgumā:
// 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;
}
}Sērijveida operācijas lielām kolekcijām
Lielām NFT kolekcijām sērijveida operācijas ietaupa laiku un gas izmaksas:
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)NFT metadatu glabāšanas labākās prakses
1. Izmantojiet aprakstošus failu nosaukumus
Augšupielādējot uz IPFS, izmantojiet jēgpilnus aprakstus, lai palīdzētu organizēšanā:
payload = {
"content": base64_content,
"description": f"Collection: {collection_name} | Token: {token_id} | Type: {file_type}"
}2. Ieviesiet pareizu kļūdu apstrādi
Vienmēr eleganti apstrādājiet augšupielādes neveiksmes:
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. Validējiet metadatu struktūru
Pārliecinieties, ka jūsu metadati atbilst standartiem:
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 TruePareizā IPFS Pinning pakalpojuma izvēle
Izvēloties IPFS pinning pakalpojumu jūsu NFT projektam, apsveriet:
- Uzticamība: Garantēts darbspējas laiks ilgtermiņa glabāšanai
- Veiktspēja: Ātri izgūšanas ātrumi visā pasaulē
- Cenas: Izmaksu efektīvs jūsu kolekcijas izmēram
- Funkcijas: API iespējas, analītika un izstrādātāju rīki
Detalizētam pinning pakalpojumu salīdzinājumam izlasiet mūsu salīdzinājumu IPFS Ninja vs Pinata un mūsu rokasgrāmatu par labākajiem IPFS pinning pakalpojumiem.
Papildu funkcijas: pielāgotas vārtejas un analītika
IPFS Ninja piedāvā papildu funkcijas profesionāliem NFT projektiem:
Pielāgotas vārtejas konfigurācija
Izveidojiet zīmolotas IPFS vārtejas savai kolekcijai:
// Access your NFT through a custom gateway
const customGateway = 'https://my-collection.gw.ipfs.ninja';
const nftUrl = `${customGateway}/ipfs/${metadataCid}`;Augšupielādes analītika
Uzraugiet NFT krātuves izmantošanu un piekļuves modeļus, izmantojot informācijas paneļa analītiku, palīdzot jums izprast kolekcijas veiktspēju un optimizēt glabāšanas izmaksas.
Bieži sastopamo problēmu novēršana
Metadati neielādējas
- Pārbaudiet, vai IPFS URL izmanto
ipfs://protokolu - Pārbaudiet, vai metadatu JSON ir derīgs
- Pārliecinieties, ka pinning pakalpojums uztur saturu
Attēli netiek parādīti
- Apstipriniet, ka attēlu CID metadatos ir pareizi
- Pārbaudiet attēlu URL IPFS vārtejās
- Pārbaudiet, vai attēla failu formāti ir saderīgi ar tīmekli
Gas novērtēšanas kļūdas
- Pārliecinieties, ka
tokenURIfunkcija atgriež derīgas virknes - Pārbaudiet cikliskās atsauces metadatos
- Validējiet visus IPFS CID pirms minting
Jūsu NFT krātuves uzraudzība un uzturēšana
Pēc jūsu kolekcijas izvietošanas:
- Regulāras veselības pārbaudes: Pārbaudiet, vai metadati un attēli paliek pieejami
- Dublējiet svarīgus CID: Glabājiet visu augšupielādēto satura identifikatoru ierakstus
- Uzraugiet analītiku: Sekojiet līdzi piekļuves modeļiem un krātuves izmantošanai
- Plānojiet mērogošanu: Apsveriet sava pinning pakalpojuma jaunināšanu, kolekcijai augot
Plašāku informāciju par programmatisku augšupielāžu pārvaldību skatiet mūsu IPFS upload API apmācībā.
Secinājums
NFT metadatu glabāšana IPFS nodrošina, ka jūsu digitālie aktīvi paliek pieejami un vērtīgi ilgtermiņā. Sekojot šai rokasgrāmatai, jūs esat iemācījušies:
- Strukturēt ar ERC-721 saderīgus metadatus
- Augšupielādēt aktīvus un metadatus, izmantojot Python un JavaScript
- Ieviest piemērotas
tokenURIfunkcijas - Apstrādāt sērijveida operācijas lielām kolekcijām
- Pielietot labākās prakses ražošanas izvietojumiem
IPFS decentralizētās arhitektūras un uzticamu pinning pakalpojumu kombinācija veido pamatu veiksmīgiem NFT projektiem, kas iztur laika pārbaudi.
Gatavi sākt ar pinning? Izveidojiet bezmaksas kontu — 50 faili, 1 GB krātuve, 2 GB joslas platums/mēnesī. Kredītkarte nav nepieciešama.
