IPFS CID-ови 2026: Водич за садржајно адресирање

Практични водич за IPFS CID: CIDv0 vs CIDv1, садржајно адресирање, генерисање CID-ова у Node.js и Python-у, провера интегритета. 2026.

Nacho Collаутор Ажурирано: 10 мин читања
Практични водич за IPFS CID: CIDv0 vs CIDv1, садржајно адресирање, генерисање CID-ова у Node.js и Python-у, провера интегритета. 2026.
TL;DR
  • Генеришите репродуцибилан CID из бајтова било ког фајла — исти садржај увек производи исти хеш.
  • Користите CIDv1 за нова отпремања: он је Base32, малим словима, и ради са subdomain gateway-има; CIDv0 не ради.
  • Промена само једног бајта у фајлу потпуно мења његов CID, чинећи манипулацију одмах уочљивом.
  • Адресирање садржаја значи да се фајлови идентификују по томе шта јесу, а не где су хостовани.

Ako ste ikada radili sa IPFS-om (InterPlanetary File System), verovatno ste naišli na nizove poput QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG ili bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi. Ovo nisu nasumične besmislice — to su Content Identifieri (CIDs), kičma IPFS sistema adresiranja sadržaja.

Razumevanje CIDs-a je ključno za svakoga ko gradi na IPFS-u, bilo da otpremate fajlove, gradite decentralizovane aplikacije ili implementirate sisteme distribucije sadržaja. Ovaj vodič će razložiti sve što trebate znati o IPFS CIDs-ima, kako funkcioniše adresiranje sadržaja i kako početi koristiti ih u svojim projektima.

Генеришите CID у 5 редова (Python)#

import hashlib, base58

def cidv0(content: bytes) -> str:
    sha256 = hashlib.sha256(content).digest()
    return base58.b58encode(b"\x12\x20" + sha256).decode()

print(cidv0(b"hello world"))
# QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpvBw3cWE69N3T

Ovaj CID je reproducibilan za bilo koga — pokrenite ga ponovo sa istim bajtovima bilo gde na svetu i dobićete isti niz karaktera. To je adresiranje sadržaja.

Ekvivalent u Node.js:

import { sha256 } from 'multiformats/hashes/sha2';
import { CID } from 'multiformats/cid';

const bytes = new TextEncoder().encode('hello world');
const hash = await sha256.digest(bytes);
const cid = CID.create(1, 0x55, hash); // version 1, raw codec
console.log(cid.toString());
// bafkreif7l7mvyofhyo6fgs6mjf5gguvm5jcahzgvfb3o7t5lmhz3...
IPFS Ninja

Šta je IPFS CID?#

Content Identifier (CID) je jedinstveni otisak prsta koji predstavlja komad sadržaja na IPFS-u. Za razliku od tradicionalnih web URL-ova koji pokazuju na lokaciju (poput https://example.com/file.pdf), CIDs pokazuju na sam sadržaj, bez obzira gde je sačuvan.

Razmislite o tome ovako:

  • Adresiranje zasnovano na lokaciji: „Idite u Glavnu ulicu 123 i tražite crvenu knjigu”
  • Adresiranje zasnovano na sadržaju: „Pronađite knjigu sa ISBN-om 978-0-123456-78-9” (nije važno koja biblioteka je ima)

CIDs rade slično — identifikuju sadržaj na osnovu njegovog kriptografskog hash-a, čineći sadržaj nepromenljivim i proverljivim. Ako se promeni samo jedan bajt u fajlu, CID se potpuno menja.

Zašto je adresiranje sadržaja važno#

Tradicionalna web arhitektura oslanja se na adresiranje zasnovano na lokaciji. Kada posetite https://example.com/image.jpg, verujete da:

  1. Vlasnik domena nije promenio sadržaj
  2. Server je online i pristupačan
  3. Sadržaj nije bio manipulisan

Sa adresiranjem sadržaja koristeći CIDs:

  1. Nepromenljivost: CID garantuje da se sadržaj nije promenio
  2. Decentralizacija: Sadržaj se može preuzeti sa bilo kog IPFS čvora koji ga ima
  3. Provera: Možete kriptografski proveriti da ste primili tačan sadržaj
  4. Efikasnost: Identičan sadržaj se automatski deduplikuje

Anatomija CID-a#

Razložimo tipičan CID kako bismo razumeli njegove komponente:

bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
└─┬─┘└─────────────────┬─────────────────────────────────┘
  │                   │
  │                   └─ Hash sadržaja (Base32 kodiran)
  └─ Multibase prefiks (označava kodiranje)

CID sadrži nekoliko delova informacija:

1. Multibase prefiks#

Prvi znak označava kako je CID kodiran:

  • Q = Base58 kodiranje (CIDv0)
  • b = Base32 kodiranje (CIDv1)
  • f = Base16/heksadecimalno (CIDv1)
  • z = Base58 (CIDv1)

2. CID verzija#

  • CIDv0: Uvek počinje sa Qm, koristi SHA-256, ograničen na DAG-PB codec
  • CIDv1: Fleksibilniji, podržava više hash funkcija i codeca

3. Multicodec#

Određuje kako je sadržaj strukturiran (DAG-PB, DAG-CBOR, sirovi bajtovi itd.)

4. Multihash#

Stvarna kriptografska hash vrednost sadržaja, uključujući:

  • Identifikator hash funkcije (obično SHA-256)
  • Dužinu hash-a
  • Hash digest

CIDv0 vs CIDv1: Razumevanje razlika#

IPFS je evoluirao kroz dve glavne verzije CID-a, svaka sa različitim karakteristikama:

CIDv0: Originalni format#

CIDv0 CIDs uvek počinju sa Qm i izgledaju ovako:

QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG

Karakteristike:

  • Samo Base58 kodiranje
  • Samo SHA-256 hash funkcija
  • Samo DAG-PB (Protobuf) codec
  • 46 znakova dužine
  • Unatrag kompatibilan sa svim IPFS implementacijama

Kada koristiti CIDv0:

  • Maksimalna kompatibilnost sa starijim IPFS čvorovima
  • Rad sa postojećim sistemima koji očekuju Qm prefikse
  • Skladištenje fajlova (najčešći slučaj upotrebe)

CIDv1: Moderni standard#

CIDv1 CIDs su fleksibilniji i mogu izgledati ovako:

bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi  # Base32
zb2rhj7crUKTQYRGCRATFaQ6YFLTde2YzdqbbhAASkL9uRDXn      # Base58
f01551220d1e2c35...                                      # Base16

Karakteristike:

  • Više formata kodiranja (Base32, Base58, Base16)
  • Podrška za različite hash funkcije (SHA-256, SHA-512, BLAKE2 itd.)
  • Više codeca (Raw, DAG-CBOR, DAG-JSON itd.)
  • Samoopisni format
  • Neosetljiv na velika/mala slova pri Base32 upotrebi

Kada koristiti CIDv1:

  • Izgradnja novih aplikacija
  • Potreba za identifikatorima neosetljivim na velika slova
  • Rad sa strukturisanim podacima (JSON, CBOR)
  • Korišćenje alternativnih hash funkcija

Konverzija između verzija#

Možete konvertovati CIDs između verzija dok održavate istu referencu sadržaja:

// CIDv0
const cidv0 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";

// Convert to CIDv1 Base32
const cidv1 = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi";

// Both reference the same content!

Kako funkcioniše adresiranje sadržaja#

Adresiranje sadržaja u IPFS-u sledi deterministički proces koji obezbeđuje da isti sadržaj uvek proizvodi isti CID:

1. Priprema sadržaja#

Kada dodate sadržaj u IPFS, prvo se razlaže:

  • Mali fajlovi: Sačuvani kao pojedinačni blokovi
  • Veliki fajlovi: Podeljeni u delove i organizovani u Merkle DAG (usmereni aciklički graf)
  • Direktorijumi: Predstavljeni kao DAG strukture koje povezuju sa fajlovima

2. Proces hashinga#

Svaki deo sadržaja prolazi kroz:

  1. Serijalizaciju: Sadržaj se formatira prema svom codecu
  2. Hashing: Kriptografska hash funkcija obrađuje serijalizovane podatke
  3. Multihash kreiranje: Hash se omata informacijama o algoritmu i dužini
  4. CID sklapanje: Verzija, codec i multihash se kombinuju

3. Merkle DAG struktura#

IPFS organizuje sadržaj u Merkle DAG gde:

  • Svaki čvor ima CID
  • Roditeljski čvorovi referenciraju dečje čvorove preko CID-a
  • Promene u bilo kom čvoru se propagiraju kroz drvo
  • Cele strukture se mogu kriptografski proveriti
Root CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
├── file1.txt (QmHash1...)
├── file2.jpg (QmHash2...)
└── subdirectory/
    ├── file3.pdf (QmHash3...)
    └── file4.mp4 (QmHash4...)

Praktični primeri: Rad sa CIDs-ima#

Istražimo kako raditi sa CIDs-ima u praksi koristeći IPFS Ninja API:

Otpremanje sadržaja i dobijanje CID-a#

// Upload a file and get its CID
const uploadFile = async (content, filename) => {
  const response = await fetch('https://api.ipfs.ninja/upload/new', {
    method: 'POST',
    headers: {
      'X-Api-Key': 'bws_1234567890abcdef1234567890abcdef12345678',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      content: btoa(content), // Base64 encode binary content
      description: `Upload of ${filename}`
    })
  });
  
  const result = await response.json();
  console.log('CID:', result.cid);
  console.log('IPFS URL:', result.uris.ipfs);
  console.log('HTTP URL:', result.uris.url);
  
  return result.cid;
};

// Example usage
uploadFile('Hello, IPFS!', 'greeting.txt');
// Returns: bafkreifjxz6zwqh27k5xnr5qfbx4w6n5vuwwwdcngguwjewzj2e3xxfgvi

Pinovanje postojećeg sadržaja po CID-u#

Ako već imate CID, možete ga pinovati kako biste obezbedili dostupnost:

const pinByCID = async (cid) => {
  const response = await fetch('https://api.ipfs.ninja/pin', {
    method: 'POST',
    headers: {
      'X-Api-Key': 'bws_1234567890abcdef1234567890abcdef12345678',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cid: cid,
      description: 'Pinned via API'
    })
  });
  
  const result = await response.json();
  console.log('Pinned CID:', result.cid);
  
  return result;
};

// Pin the "Hello World" of IPFS
pinByCID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u');

Pristup sadržaju preko CID-a#

Jednom kada imate CID, možete pristupiti sadržaju preko različitih metoda:

// Direct IPFS gateway access
const ipfsUrl = `https://ipfs.ninja/ipfs/${cid}`;

// Custom gateway (if configured)
const customGatewayUrl = `https://my-app.gw.ipfs.ninja/ipfs/${cid}`;

// Fetch content programmatically
const fetchContent = async (cid) => {
  const response = await fetch(`https://ipfs.ninja/ipfs/${cid}`);
  const content = await response.text();
  return content;
};

Najbolje prakse CID-a za programere#

1. Uvek validirajte CIDs#

Pre korišćenja CID-a u vašoj aplikaciji, validirajte njegov format:

const isValidCID = (cid) => {
  // Basic validation patterns
  const cidv0Pattern = /^Qm[1-9A-HJ-NP-Za-km-z]{44}$/;
  const cidv1Pattern = /^[bf][a-z2-7]{58}$/;
  
  return cidv0Pattern.test(cid) || cidv1Pattern.test(cid);
};

2. Rukujte obe verzije CID-a#

Vaša aplikacija bi trebalo da radi sa CIDv0 i CIDv1:

const normalizeCID = (cid) => {
  if (cid.startsWith('Qm')) {
    // CIDv0 - can convert to CIDv1 if needed
    return cid;
  } else if (cid.startsWith('b') || cid.startsWith('f') || cid.startsWith('z')) {
    // CIDv1
    return cid;
  } else {
    throw new Error('Invalid CID format');
  }
};

3. Keširajte CID mapiranja#

Ako često generišete CIDs, razmotrite keširanje:

const cidCache = new Map();

const getCachedCID = (content) => {
  const contentHash = btoa(content);
  
  if (cidCache.has(contentHash)) {
    return cidCache.get(contentHash);
  }
  
  // Upload and cache result
  return uploadFile(content).then(cid => {
    cidCache.set(contentHash, cid);
    return cid;
  });
};

4. Koristite smislene opise#

Pri otpremanju sadržaja, uključite opisne metapodatke:

const uploadWithMetadata = async (content, metadata) => {
  return fetch('https://api.ipfs.ninja/upload/new', {
    method: 'POST',
    headers: {
      'X-Api-Key': 'bws_1234567890abcdef1234567890abcdef12345678',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      content: btoa(content),
      description: metadata.name || 'Uploaded file',
      metadata: {
        filename: metadata.filename,
        contentType: metadata.contentType,
        uploadedAt: new Date().toISOString(),
        version: metadata.version || '1.0'
      }
    })
  });
};

Uobičajeni slučajevi upotrebe CID-a#

1. Implementacija statičkih web sajtova#

Implementirajte cele web sajtove na IPFS i referencirajte ih preko CID-a:

// Upload website directory structure
const deployWebsite = async (files) => {
  const uploads = await Promise.all(
    files.map(file => uploadFile(file.content, file.path))
  );
  
  // Root CID references entire site
  const rootCID = uploads.find(u => u.path === 'index.html').cid;
  console.log(`Website deployed: https://ipfs.ninja/ipfs/${rootCID}`);
  
  return rootCID;
};

Za više informacija o implementaciji web sajtova, pogledajte naš vodič o tome kako otpremiti fajlove na IPFS.

2. Skladištenje NFT metapodataka#

Skladištite NFT metapodatke nepromenljivo koristeći CIDs:

const nftMetadata = {
  name: "My Awesome NFT",
  description: "A unique digital collectible",
  image: "ipfs://bafkreibc5sgo2plmjkq2tzmhrn54bk3crhnqekiy7u66fqvqm37pu2e5gw",
  attributes: [
    { trait_type: "Color", value: "Blue" },
    { trait_type: "Rarity", value: "Epic" }
  ]
};

const metadataCID = await uploadFile(
  JSON.stringify(nftMetadata, null, 2), 
  'metadata.json'
);

// Use in smart contract
console.log(`Token URI: ipfs://${metadataCID}`);

3. Distribucija sadržaja#

Koristite CIDs za distribuiranu isporuku sadržaja:

// Upload once, access everywhere
const distributeContent = async (content) => {
  const cid = await uploadFile(content, 'content.txt');
  
  // Content available via multiple gateways
  const gateways = [
    `https://ipfs.ninja/ipfs/${cid}`,
    `https://ipfs.io/ipfs/${cid}`,
    `https://cloudflare-ipfs.com/ipfs/${cid}`
  ];
  
  return { cid, gateways };
};

Razumevanje IPFS pinninga sa CIDs-ima#

CIDs su prema podrazumevanim postavkama privremeni — moraju se „pinovati” kako bi ostali dostupni. Saznajte više o ovom ključnom konceptu u našem sveobuhvatnom vodiču o tome šta je IPFS pinning.

Pri odabiru IPFS pinning usluge, razmotrite čitanje našeg poređenja IPFS Ninja vs Pinata ili istražite naš pregled najboljih IPFS pinning usluga dostupnih danas.

Napravite svoj prvi CID za 30 sekundi#

Spremni da napravite svoj prvi CID? Evo brzog primera koristeći IPFS Ninja API:

# Using curl (replace with your actual API key)
curl -X POST https://api.ipfs.ninja/upload/new \
  -H "X-Api-Key: bws_YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "SGVsbG8sIElQRlMgV29ybGQh",
    "description": "My first IPFS upload"
  }'
// Using JavaScript
const createFirstCID = async () => {
  const response = await fetch('https://api.ipfs.ninja/upload/new', {
    method: 'POST',
    headers: {
      'X-Api-Key': 'bws_YOUR_API_KEY_HERE',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      content: btoa('Hello, IPFS World!'), // Base64: "SGVsbG8sIElQRlMgV29ybGQh"
      description: 'My first IPFS upload'
    })
  });
  
  const result = await response.json();
  console.log('🎉 Your first CID:', result.cid);
  console.log('🌐 Access it at:', result.uris.url);
  
  return result;
};

createFirstCID();

Ovo će vratiti nešto poput:

{
  "cid": "bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw",
  "sizeMB": 0.000017,
  "uris": {
    "ipfs": "ipfs://bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw",
    "url": "https://ipfs.ninja/ipfs/bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw"
  }
}

Za detaljnije primere API-ja, pogledajte naš tutorial IPFS upload API.

Zaključak#

CIDs su temelj sistema adresiranja sadržaja IPFS-a, pružajući nepromenljivu, proverljivu i decentralizovanu identifikaciju sadržaja. Razumevanje kako funkcionišu — od tehničkih detalja CIDv0 vs CIDv1 do praktičnih obrazaca implementacije — je ključno za izgradnju robusnih decentralizovanih aplikacija.

Ključni zaključci:

  • CIDs jedinstveno identifikuju sadržaj, ne lokacije
  • CIDv0 pruža maksimalnu kompatibilnost, CIDv1 nudi fleksibilnost
  • Adresiranje sadržaja omogućava proveru i deduplikaciju
  • Pravilno rukovanje CID-om je ključno za produkcijske aplikacije

Bilo da skladištite NFT metapodatke, implementirate decentralizovane web sajtove ili gradite sisteme distribucije sadržaja, CIDs pružaju pouzdanu osnovu koja vam je potrebna za istinski decentralizovane aplikacije.

Spremni započeti pinovanje? Napravite besplatni nalog — 50 fajlova, 1 GB skladišta, 2 GB propusnosti/mesec. Bez kreditne kartice.

Nacho Coll

О аутору

Founder & Engineer at IPFS.NINJA

Nacho founded IPFS.NINJA to make content-addressed storage feel as simple as an S3 PUT — a single API call, a permanent CID, no wallets or peer discovery to reason about. Writes about IPFS internals, decentralized storage patterns, and the pinning-service landscape from the operator side of the wire.

Назад на Блог

Повезани чланци