· Nacho Coll · Guides · 12 分鐘閱讀
IPFS CID 完整解析:它是什麼以及內容定址如何運作
清晰技術性地說明 IPFS 內容識別碼 (CIDs)。內容定址如何運作、CID 版本以及如何建立你的第一個 CID。

如果你曾使用過 IPFS(InterPlanetary File System,星際檔案系統),你可能遇過像 QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG 或 bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 的字串。這些不是隨機的亂碼——它們是內容識別碼(CIDs),IPFS 內容定址系統的骨幹。
理解 CIDs 對任何在 IPFS 上構建應用的人來說都至關重要,無論你是上傳檔案、構建去中心化應用,還是實作內容分發系統。本指南將分解你需要知道關於 IPFS CIDs 的一切、內容定址如何運作,以及如何在你的專案中開始使用它們。

什麼是 IPFS CID?
**內容識別碼(CID)**是代表 IPFS 上一段內容的唯一指紋。與指向某個位置的傳統 web URL(如 https://example.com/file.pdf)不同,CIDs 指向內容本身,不管它儲存在哪裡。
這樣想:
- 基於位置的定址:「去主街 123 號要那本紅色的書」
- 基於內容的定址:「找到 ISBN 為 978-0-123456-78-9 的書」(不管哪間圖書館有它)
CIDs 以類似方式運作——它們根據內容的密碼學雜湊識別內容,使內容不可變且可驗證。如果檔案中只變更一個位元組,CID 就會完全改變。
為什麼內容定址很重要
傳統 web 架構依賴基於位置的定址。當你訪問 https://example.com/image.jpg 時,你信任:
- 域名擁有者沒有更改內容
- 伺服器在線且可訪問
- 內容沒有被竄改
使用 CIDs 進行內容定址:
- 不可變性:CID 保證內容沒有改變
- 去中心化:可以從任何擁有它的 IPFS 節點檢索內容
- 驗證:你可以以密碼學方式驗證收到了正確的內容
- 效率:相同內容會自動去重
CID 的剖析
讓我們分解一個典型的 CID 來理解它的組成部分:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
└─┬─┘└─────────────────┬─────────────────────────────────┘
│ │
│ └─ 內容雜湊(Base32 編碼)
└─ Multibase 前綴(指示編碼)一個 CID 包含多個資訊片段:
1. Multibase 前綴
第一個字元指示 CID 的編碼方式:
Q= Base58 編碼(CIDv0)b= Base32 編碼(CIDv1)f= Base16/十六進制(CIDv1)z= Base58(CIDv1)
2. CID 版本
- CIDv0:總是以
Qm開頭,使用 SHA-256,限於 DAG-PB 編解碼器 - CIDv1:更靈活,支援多種雜湊函數和編解碼器
3. Multicodec
指定內容的結構化方式(DAG-PB、DAG-CBOR、原始位元組等)
4. Multihash
內容的實際密碼學雜湊,包括:
- 雜湊函數識別碼(通常為 SHA-256)
- 雜湊長度
- 雜湊摘要
CIDv0 vs CIDv1:理解差異
IPFS 已演進通過兩個主要 CID 版本,每個都有獨特特性:
CIDv0:原始格式
CIDv0 CIDs 總是以 Qm 開頭,看起來像:
QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG特性:
- 僅 Base58 編碼
- 僅 SHA-256 雜湊函數
- 僅 DAG-PB(Protobuf)編解碼器
- 46 個字元長
- 與所有 IPFS 實作向後相容
何時使用 CIDv0:
- 與舊 IPFS 節點的最大相容性
- 與期望
Qm前綴的現有系統合作 - 檔案儲存(最常見的用例)
CIDv1:現代標準
CIDv1 CIDs 更靈活,可能看起來像:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi # Base32
zb2rhj7crUKTQYRGCRATFaQ6YFLTde2YzdqbbhAASkL9uRDXn # Base58
f01551220d1e2c35... # Base16特性:
- 多種編碼格式(Base32、Base58、Base16)
- 支援不同雜湊函數(SHA-256、SHA-512、BLAKE2 等)
- 多種編解碼器(Raw、DAG-CBOR、DAG-JSON 等)
- 自描述格式
- 使用 Base32 時不區分大小寫
何時使用 CIDv1:
- 構建新應用
- 需要不區分大小寫的識別碼
- 處理結構化資料(JSON、CBOR)
- 使用替代雜湊函數
版本之間的轉換
你可以在版本之間轉換 CIDs,同時保持相同的內容引用:
// CIDv0
const cidv0 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
// Convert to CIDv1 Base32
const cidv1 = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi";
// Both reference the same content!內容定址如何運作
IPFS 中的內容定址遵循確定性過程,確保相同內容總是產生相同 CID:
1. 內容準備
當你將內容新增到 IPFS 時,它首先會被分解:
- 小檔案:儲存為單一區塊
- 大檔案:分割成片段並組織在 Merkle DAG(有向無環圖)中
- 目錄:表示為連結到檔案的 DAG 結構
2. 雜湊處理過程
每一塊內容經歷:
- 序列化:內容根據其編解碼器格式化
- 雜湊:密碼學雜湊函數處理序列化資料
- Multihash 建立:雜湊被包裝為演算法和長度資訊
- CID 組裝:版本、編解碼器和 multihash 結合
3. Merkle DAG 結構
IPFS 將內容組織在 Merkle DAG 中,其中:
- 每個節點有一個 CID
- 父節點透過 CID 引用子節點
- 任何節點中的變更會在樹中向上傳播
- 整個結構可以用密碼學方式驗證
Root CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
├── file1.txt (QmHash1...)
├── file2.jpg (QmHash2...)
└── subdirectory/
├── file3.pdf (QmHash3...)
└── file4.mp4 (QmHash4...)實用範例:使用 CIDs
讓我們探索如何使用 IPFS Ninja API 在實踐中使用 CIDs:
上傳內容並取得 CID
// 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透過 CID 釘選現有內容
如果你已有 CID,你可以釘選它以確保可用性:
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');透過 CID 存取內容
一旦你有了 CID,你可以透過各種方法存取內容:
// 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;
};開發者的 CID 最佳實踐
1. 永遠驗證 CIDs
在你的應用中使用 CID 之前,驗證其格式:
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. 處理兩種 CID 版本
你的應用應該同時處理 CIDv0 和 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. 快取 CID 映射
如果你經常產生 CIDs,考慮快取:
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. 使用有意義的描述
上傳內容時,包含描述性元資料:
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'
}
})
});
};常見 CID 用例
1. 靜態網站部署
將整個網站部署到 IPFS 並透過 CID 引用它們:
// 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;
};要了解更多關於網站部署的資訊,查看我們關於如何將檔案上傳到 IPFS 的指南。
2. NFT 元資料儲存
使用 CIDs 不可變地儲存 NFT 元資料:
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. 內容分發
使用 CIDs 進行分散式內容交付:
// 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 };
};使用 CIDs 理解 IPFS 釘選
CIDs 預設是臨時的——它們必須被「釘選」才能保持可用。在我們關於什麼是 IPFS 釘選 的完整指南中了解更多關於這個關鍵概念。
選擇 IPFS 釘選服務時,考慮閱讀我們的 IPFS Ninja vs Pinata 比較或探索我們對今天可用的最佳 IPFS 釘選服務 的綜述。
在 30 秒內建立你的第一個 CID
準備好產生你的第一個 CID 了嗎?這是使用 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();這將回傳類似:
{
"cid": "bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw",
"sizeMB": 0.000017,
"uris": {
"ipfs": "ipfs://bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw",
"url": "https://ipfs.ninja/ipfs/bafkreif2pall7dybz7vecqka3zo24irdwabf7rbiiweuhau7a2hjlqvfjw"
}
}更詳細的 API 範例,請查看我們的 IPFS 上傳 API 教學。
結論
CIDs 是 IPFS 內容定址系統的基礎,提供不可變、可驗證和去中心化的內容識別。理解它們如何運作——從 CIDv0 vs CIDv1 的技術細節到實際的實作模式——對於構建強大的去中心化應用至關重要。
關鍵要點:
- CIDs 唯一識別內容,而非位置
- CIDv0 提供最大相容性,CIDv1 提供靈活性
- 內容定址實現驗證和去重
- 正確的 CID 處理對生產應用至關重要
無論你是儲存 NFT 元資料、部署去中心化網站,還是構建內容分發系統,CIDs 都提供你真正去中心化應用所需的可靠基礎。
準備好開始釘選了嗎? 建立免費帳戶 —— 50 個檔案、1 GB 儲存、2 GB 頻寬/月。無需信用卡。
