Dev Lab3 min read
블록체인 데이터베이스, 컨트랙트로 구현한 테이블형 저장소 설계
컨트랙트를 테이블처럼 쓰는 블록체인 데이터베이스 설계. Post·Auth·Relayer·Subscriber·Visitor·YouTube 저장소 구조와 주소/인증 전략까지 한 번에 정리.
#블록체인#데이터베이스#스마트컨트랙트#설계#메타트랜잭션#패스키#인증#릴레이어#아키텍처

왜 블록체인을 DB처럼?
- 중앙화 데이터베이스는 편리하지만 신뢰 최소화·출처 증명·검증 가능 기록에 한계가 있습니다.
- 또한, DB 운영 비용을 절감하려는 목적도 있습니다.
- 반대로 블록체인은 불변성·투명성·검증 가능성을 제공하지만, 스키마·쿼리·비용에서 제약이 큽니다.
- 이 글은 컨트랙트를 테이블로 보는 관점으로 설계를 정리합니다. 결과적으로 읽기(오프체인 인덱싱)와 쓰기(온체인 확정)를 분리해 서비스화를 가능하게 합니다.
- 예제 코드는 in-labs-contract 소스 코드를 기준으로 설명합니다.
컨트랙트 = 테이블: 저장소 맵핑
- 핵심 아이디어는 컨트랙트 1개 = 데이터베이스 테이블 1개입니다. 모든 레코드는
address기반의 키로 귀결됩니다. - 본 블로그 서비스에서 사용하는 주요 “테이블”은 다음과 같습니다.
| 컨트랙트(테이블) | 역할 요약 | 주요 키/함수 |
|---|---|---|
PostStorage | ERC-721 기반 포스트 저장. 추후 확장을 고려한 메타트랜잭션 구조. | post, struct Post, getPosts |
AuthStorage | 생체인증용 passkey 저장소. 다중 암호화로 보호. | registration, addPasskey, DEFAULT_PASSKEY_SLOTS |
RelayerManager | 가스 대납 릴레이어 풀 관리. msg.sender 릴레이어 여부 검증. | onlyRelayer, assertRelayer |
SubscriberStorage | 블로그 구독 관계 저장(다음 글에서 상세) | claimPinCode, addSubscriberEmail, isPinCodeActive |
VisitorStorage | 방문자 트래킹 데이터 저장(다음 글에서 상세) | currentDayId, addHashedVisitor, totalVisitorsOf |
YoutubeStorage | YouTube 영상 ID 보관(게시판 연동). | struct YouTubeVideo, saveVideoFor, updateVideoFor |
주의: 테이블 간 조인은 체인 레벨에서 직접 수행하지 않습니다. 조회는 인덱서/서버에서 결합하고, 정합성은 온체인 키(address, tokenId, hash)로 보장합니다.
주소와 인증: 계정 불러오기 전략
- 모든 데이터는 결국 주소(address) 로 귀속됩니다. 문제는 일반 사용자가 Hex 주소를 관리하기 어렵다는 점입니다.
- 해결책: 생체인증 데이터 + 자체 암호화 패턴으로 주소 파생 규칙을 만들었습니다. 사용자는 자신만 아는 코드로 생체인증을 수행하면, 해당 데이터로 자신의 계정(account)을 자동 매핑해 불러옵니다.
- 즉, 별도의 시드 문구나 복잡한 지갑 UX 없이 “나만의 코드 + 생체인증” 만으로 서비스를 재현 가능하게 합니다.
- passkey 원본은
AuthStorage에서 다중 암호화 후 해시/파생키 형태로 저장하며, 실제 비밀키는 온체인에 직접 보관하지 않습니다.
메타트랜잭션과 릴레이어: 쓰기 비용의 현실 해법
- 사용자가 하나의 주소에서 모든 트랜잭션을 보내면 nonce 경합이 쉽게 발생합니다.(다음 글에서 상세히 설명)
RelayerManager는 여러 릴레이어 주소를 생성·관리하고, 외부 컨트랙트에assertRelayer(msg.sender)를 제공해 안전하게 대납을 허용합니다.PostStorage등 쓰기 함수는 메타트랜잭션을 지원해 유저는 서명만 하고, 릴레이어가 가스비를 대납합니다. 이렇게 하면 UX가 단순해지고, 서비스가 트래픽 급증 시에도 nonce 충돌을 줄일 수 있습니다.- 운영 팁:
- 릴레이어 풀은 최소 3개 이상으로 분산해 스루풋을 높입니다.
- 실패 트랜잭션은 replay 보호(체인ID·만료시간·EIP-712 도메인)로 관리합니다.
- 대납 정책은 요금제/쿼터 개념으로 설계하고, 남용 방지를 위해 서명 재사용 제한을 둡니다.
데이터 모델과 쓰기/읽기 흐름
- 주소/계정 파생: “개인 코드 + 생체인증” → 파생 데이터 → 계정
address결론. - 쓰기(온체인): 유저 서명 → 릴레이어 제출 →
RelayerManager검증 → 각 저장소 컨트랙트에 기록. - 읽기(오프체인): 이벤트(Log) 인덱싱 → 서비스 DB/캐시 적재 → API로 결합 조회.
- 무결성 확인: UI에서 중요 필드의 온체인 증명 링크 제공(예: tx hash, tokenId).

팁: UI에는 최소 1회 이상 온체인 링크(트랜잭션·토큰)를 노출해 검증 가능성을 시각화하세요. 또한 In-Labs YouTube 게시판을 활용하면 YoutubeStorage 와의 연결 사례를 쉽게 확인할 수 있습니다.
한계와 운영 상 고려사항
- 비용: 기록은 무료(가스)입니다. 테스트넷 사용하였습니다.
- 프라이버시: 공개 원장을 쓰므로, 민감 데이터는 암호화/해시만 온체인 원칙을 지킵니다.
- 스키마 진화: 테이블에 해당하는 컨트랙트는 업그레이드 전략(Proxy 또는 신규 배포+마이그레이션)을 사전에 설계해야 합니다.
- 인덱싱 지연: 오프체인 인덱서의 지연을 감안해 UI에 낙관적 업데이트와 재동기화를 병행합니다.
“컨트랙트를 테이블로 본다”는 관점은 불변성·검증·확장성의 균형을 맞추는 실용적 절충입니다.