블록체인 데이터 저장 설계: 온체인 앵커와 IPFS·Filecoin의 역할

블록체인 데이터 저장에서 온체인 앵커, IPFS 핀닝, Filecoin 딜을 조합해 무결성·영속성·비용을 설계하는 방법을 정리한다.

2026-08-14 · 최초 발행 2025-10-31

체인에는 원본 대신 검증 가능한 참조를 남긴다

블록체인에 데이터를 저장할 때는 무결성·영속성·비용·성능을 동시에 다뤄야 한다. 원본 데이터를 온체인에 직접 두기보다, 오프체인에 보관한 뒤 CID나 해시를 체인에 앵커링하는 방식이 이 균형을 잡는 기본 구조다.

온체인 저장은 트랜잭션 데이터, 로그, 상태(state)에 데이터를 직접 영속화한다. 불변성과 검증 가능성은 강하지만 가스 비용과 확장성 제약이 뒤따른다. 따라서 소용량 데이터, 핵심 지표, 해시 앵커처럼 체인에서 직접 보장해야 하는 정보에 맞는다.

오프체인 저장은 블록체인 바깥의 스토리지에 원본을 두고, 체인에는 CID 또는 해시 같은 참조값만 기록한다. 대용량 데이터를 다루기 쉽고 비용과 확장성 측면에서 유리하다. 데이터 무결성은 해시 앵커와 콘텐츠 주소화로 확인한다.

IPFS는 콘텐츠 주소화(content addressing)와 분산 P2P 전송을 제공한다. CID를 이용하면 조회한 데이터가 참조 대상과 같은지 검증할 수 있다. 다만 기본 가용성은 “최선형(best-effort)”이므로, 핀(Pinning) 또는 백엔드 스토리지 연계가 필요하다.

Filecoin은 스토리지 계약(Deal), Proof-of-Replication, Proof-of-Spacetime에 기반한 탈중앙 스토리지 네트워크다. IPFS와 같은 CID 기반 참조를 사용하면서 장기 보관과 SLA 유사 속성을 보완한다.

저장 경로와 장애 대응을 함께 구성한다

성공실패실패가용장애검증 실패검증 성공클라이언트/서비스데이터 생성사전 처리압축·암호화·ChunkingIPFS 업로드CID 획득 성공 여부Pinning 서비스다중 리전재시도/백오프에러 로깅Filecoin 제출(자동/예약) 상태 모니터링대체 스토리지/프로바이더자동 재시도스마트컨트랙트CID/해시 앵커 기록이벤트/상태 동기화인덱싱사용자 조회게이트웨이 가용성IPFS 게이트웨이/노드CID로 조회대체 게이트웨이·자체 노드Failover무결성 검증CID/해시 대조오류 알림·재복제경보콘텐츠 제공

데이터는 생성 뒤 압축·암호화·Chunking을 거쳐 IPFS에 올라가고 CID를 얻는다. 이후 핀과 Filecoin 딜을 구성하면서 CID 또는 해시를 스마트컨트랙트에 기록한다. 조회 경로에서는 게이트웨이 또는 노드가 CID로 콘텐츠를 가져오고, CID·해시 대조를 통과한 데이터만 제공한다.

핀이나 딜이 실패하면 지수 백오프와 프로바이더 교체를 적용한다. 게이트웨이 장애에는 대체 게이트웨이와 자체 노드 페일오버가 대응 경로가 된다. 체인 앵커는 체인 최종성 이후 신뢰를 확보하며, 오프체인 데이터는 CID 검증으로 강한 콘텐츠 일관성을 제공한다.

앵커의 범위와 보관 정책을 분리해 설계한다

CID·해시, 핵심 메타데이터, 검증에 필요한 최소 증거는 온체인에 남긴다. 대용량 바이너리는 이벤트 로그와 외부 저장소를 조합하는 편이 적합하다.

CID는 CIDv1(멀티코덱/멀티베이스)을 채택하고, 파일 변경 시 신규 CID를 발급한다. 이전 CID와 최신 CID의 매핑 테이블은 온체인에서 관리할 수 있다.

민감정보와 PII는 전송 전에 AES-GCM으로 암호화하고 KMS/HSM을 적용한다. 접근 통제는 애플리케이션 레이어에서 토큰과 정책으로 제어한다. 삭제 요청에는 암호키 폐기(Key erasure) 전략을 고려하며, 데이터 보존 기간과 지역 주권(데이터 레지던시) 정책도 반영해야 한다.

가용성과 영속성은 핀과 딜을 분리해 운영한다. Pinning은 다중 리전 3+ 복제를, Filecoin은 2+ 딜 병렬화를 권장한다. 주기적 무결성 재검증(Job/SLA), 자동 재복구 파이프라인, 지역·프로바이더 다변화가 함께 필요하다.

앵커 비용은 L2(Optimism/Arbitrum/zk), 압축, Chunk 단위 업로드로 줄일 수 있다. 조회 경로에는 캐시와 CDN을 앞단에 배치해 게이트웨이 비용을 최소화한다.

저장 방식별로 달라지는 제약

항목 온체인 저장 IPFS(+핀) Filecoin
비용(GB) 매우 높음, 비현실적 매우 낮음 낮음(딜 단가 기반)
지연 수백 ms~수 초(체인·L2 의존) 수십~수백 ms(캐시/노드 상태 의존) 초 단위 이상(검색·복호화·전송)
확장성 제한적(블록 가스/크기) 높음(P2P 분산) 높음(프로바이더 확장)
일관성 강한 불변성·최종성 CID 기반 콘텐츠 일관성 증명 기반 내구성·가용성
내구성 체인 영구 보존 핀 유지 조건부 딜 기간·증명 기반
운영 편의 복잡(가스·업그레이드) 중간(핀 관리 필요) 중간~높음(딜·모니터링 필요)
주요 리스크 고비용 핀 누락·게이트웨이 장애 딜 만료·프로바이더 가용성
사용 적합성 해시 앵커·지표 빈번 조회·웹통합 장기 보관·규모 데이터

주: 비용·지연은 네트워크·프로바이더·시점에 따라 변동. 최신 정보 확인 필요.

CID 앵커를 기록하는 스마트컨트랙트

환경은 Solidity 0.8.x, Foundry/Hardhat, EVM 호환 네트워크를 전제로 한다. CIDv1(멀티베이스 base32)을 bytes로 전달하고 이벤트 로그에도 남긴다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract ContentAnchor {
    event Anchored(bytes cid, bytes32 digest, address indexed owner, uint256 indexed idx);

    struct Record {
        bytes cid;        // CIDv1 raw bytes
        bytes32 digest;   // e.g., sha2-256 digest of content for quick check
        address owner;
        uint64  timestamp;
    }

    Record[] public records;

    function anchor(bytes calldata cid, bytes32 digest) external returns (uint256 idx) {
        Record memory r = Record({
            cid: cid,
            digest: digest,
            owner: msg.sender,
            timestamp: uint64(block.timestamp)
        });
        records.push(r);
        idx = records.length - 1;
        emit Anchored(cid, digest, msg.sender, idx);
    }

    function get(uint256 idx) external view returns (Record memory) {
        return records[idx];
    }
}

상태와 이벤트에 CID를 이중으로 보관하고, 원본 대신 CID·해시만 기록해 비용을 줄인다.

IPFS 업로드 뒤 컨트랙트에 앵커링하기

Node.js v18+, ipfs-http-client ^60, ethers ^6 환경을 사용하며 .env에는 RPC_URL, PRIVATE_KEY, CONTRACT_ADDRESS를 둔다.

npm i ipfs-http-client ethers dotenv
// upload-and-anchor.js
import { create } from "ipfs-http-client";
import { ethers } from "ethers";
import fs from "node:fs";
import "dotenv/config";

// 1) IPFS 클라이언트 (Infura/Pinata/자체 노드 게이트웨이 엔드포인트)
const ipfs = create({ url: process.env.IPFS_ENDPOINT }); // e.g., https://ipfs.infura.io:5001/api/v0

// 2) 파일 업로드
const data = fs.readFileSync("./artifact.bin"); // 사전 암호화/압축 권장
const addRes = await ipfs.add(data, {
  wrapWithDirectory: false,
  cidVersion: 1,
  pin: true,
});
const cidStr = addRes.cid.toString(); // CIDv1 base32
console.log("CID:", cidStr);

// 3) CID 바이트와 digest 계산
import crypto from "node:crypto";
const digest = "0x" + crypto.createHash("sha256").update(data).digest("hex");

// 멀티포맷 CID 바이트 변환(간소화: base32->bytes)
const cidBytes = ethers.toUtf8Bytes(cidStr);

// 4) 컨트랙트 호출
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const abi = ["function anchor(bytes cid, bytes32 digest) returns (uint256)"];
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS, abi, wallet);

const tx = await contract.anchor(cidBytes, digest, { gasLimit: 200000 });
const receipt = await tx.wait();
console.log("Anchored at tx:", receipt.transactionHash);

업로드가 실패하면 지수 백오프로 재시도하고 다른 IPFS API 엔드포인트로 폴백한다. 앵커링 실패에는 nonce 재동기화와 L2 사용 검토가 필요하다.

Web3.Storage를 통한 Filecoin 장기 보관

Node.js v18+, web3.storage ^7 환경을 사용하며 WEB3_STORAGE_TOKEN 발급이 필요하다.

npm i web3.storage
import { Web3Storage, File } from "web3.storage";
import fs from "node:fs";

const client = new Web3Storage({ token: process.env.WEB3_STORAGE_TOKEN });
const buffer = fs.readFileSync("./artifact.bin");
const files = [new File([buffer], "artifact.bin")];

const cid = await client.put(files, {
  wrapWithDirectory: false,
  maxRetries: 3,
});
console.log("Stored to Web3.Storage CID:", cid);
// 백엔드에서 Filecoin 딜로 마이그레이션/증명 관리

딜 만료 전 갱신과 재복제 정책을 자동화하고, 라우트 인덱싱과 게이트웨이 헬스체크를 구성한다.

원본 데이터와 증거 데이터를 나누어 쓰는 장면

NFT 미디어와 메타데이터는 IPFS/Filecoin에 보관하고, 온체인에는 CID와 저작권 메타정보를 앵커링할 수 있다. 로열티와 버전 이력 추적에도 이 구성이 쓰인다.

규제 로그와 감사 증적은 로그 배치 해시(Merkle root)를 온체인에 기록하고 원본 로그는 오프체인에서 암호화해 보관한다. 규제 감사 시 원본의 무결성을 검증할 수 있다.

머신러닝 아티팩트와 대용량 데이터셋에서는 모델 가중치와 데이터셋을 오프체인에 두고 실험·릴리스 태그를 앵커링한다. 재현성과 서플라이체인 무결성을 확보하는 방식이다.

온체인 게임과 메타버스 에셋은 텍스처·맵 파일을 오프체인에 저장하고, 게임 상태 가운데 핵심 정보만 체인에 둔다. 로딩 지연 완화와 비용 절감을 함께 노릴 수 있다.

비용과 신뢰성의 균형

100KB를 온체인 calldata로 전송하면 가스는 약 1.64M(비영零 바이트 기준 16 gas/byte 가정) 수준이며, 가스가격 20 gwei에서는 약 0.0328 ETH다. 가격 변동성 존재, 최신 정보 확인 필요. 같은 데이터를 오프체인에 두고 CID만 앵커링하면 트랜잭션 가스는 수만 단위로 축소된다.

대용량 데이터의 전송과 조회에는 IPFS 게이트웨이와 CDN 캐시를 활용해 지연을 낮추고, 병렬 분산 전송으로 대역폭을 활용할 수 있다. CID·해시 앵커는 위변조를 방지하며, Filecoin 증명은 장기 내구성을 보강한다. 다중 리전 핀과 딜 구성은 장애 내성도 높인다.

블록체인온체인오프체인IPFSFilecoin데이터 저장