· 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.

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.

IPFS Ninja

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:

  1. Galvenie aktīvi: Attēli, video vai cits primārais saturs
  2. Metadatu faili: JSON faili, kas apraksta katru NFT
  3. 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 backoff

3. 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 True

Pareizā 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 tokenURI funkcija 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:

  1. Regulāras veselības pārbaudes: Pārbaudiet, vai metadati un attēli paliek pieejami
  2. Dublējiet svarīgus CID: Glabājiet visu augšupielādēto satura identifikatoru ierakstus
  3. Uzraugiet analītiku: Sekojiet līdzi piekļuves modeļiem un krātuves izmantošanai
  4. 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 tokenURI funkcijas
  • 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.

Atpakaļ uz Blogu

Saistītie raksti

Skatīt visus rakstus »