오픈 소스를 위한 온체인 평판 그래프(Onchain Reputation Graph) 구축하기
요약
오픈 소스 기여 활동을 플랫폼에 구애받지 않고 검증 가능한 데이터로 구축하기 위한 온체인 평판 그래프 기술을 소개합니다. 결정론적 ID와 지식 그래프 모델을 사용하여 흩어진 기여 데이터를 통합하고 온체인에 발행하는 파이프라인을 제안합니다.
핵심 포인트
- 중앙 집중식 API 의존성을 탈피한 검증 가능한 오픈 소스 평판 구축
- 원자(Atoms)와 트리플(Triples) 구조를 활용한 지식 그래프 모델링
- 별도의 레지스트리 없이 동일한 ID를 도출하는 결정론적 ID 방식
- 데이터 수집부터 온체인 발행까지 이어지는 6단계 파이프라인
문제점 (The Problem)
오픈 소스 기여는 여기저기 흩어져 있습니다. Alice는 GitHub에서 30개의 저장소(repos)에 기여하고, 5개의 npm 패키지를 유지 관리하며, GitLab에서 PR(Pull Request)을 리뷰하고, 개인 블로그에 문서를 작성할 수도 있습니다. **누가 이것을 만들었는가?**라는 간단한 질문에 답할 수 있는 통합되고, 휴대 가능하며, 플랫폼에 구애받지 않는 방법이 현재는 없습니다.
전통적인 솔루션들은 Dune 대시보드, 커스텀 스크레이퍼(scrapers), GitHub 자체 API와 같은 중앙 집중식 데이터베이스에 의존합니다. 이러한 방식은 다음과 같은 한계가 있습니다:
- 취약함 (Fragile) — API가 변경되면 작동이 중단됨
- 비휴대성 (Non-portable) — 단일 플랫폼의 데이터 모델에 종속됨
- 검증 불가능 (Not verifiable) — 온체인 증거(onchain proof) 없이 누구나 무엇이든 주장할 수 있음
만약 우리가 오픈 소스 소프트웨어(OSS) 평판을 기여 활동 그 자체처럼 **결정론적(deterministic)**이고, **검증 가능(verifiable)**하며, **조합 가능(composable)**하게 만들 수 있다면 어떨까요?
접근 방식 (The Approach)
원자(Atoms) + 트리플(Triples) = 지식 그래프 (A Knowledge Graph)
Intuition 프로토콜은 세상을 **원자(atoms, 엔티티)**와 **트리플(triples, 관계)**로 모델링합니다. 원자는 사람, 저장소(repo), npm 패키지 등 무엇이든 식별할 수 있는 고유 식별자입니다. 트리플은 술어(predicate)를 통해 두 원자를 연결하는 유향 에지(directed edge)입니다.
// 이 트리플은 다음과 같이 말합니다: "fisker가 prettier/prettier에 기여했다(contributedTo)"
{
subjectId: "0xabc...", // GitHub 사용자 "fisker"에 대한 결정론적 원자 ID
...
결정론적 ID (Deterministic IDs) — 핵심 통찰
원자 ID는 **결정론적(deterministic)**입니다. 동일한 입력 데이터가 주어지면 항상 동일한 32바이트 식별자를 얻게 되며, 온체인 조회(onchain lookup)가 필요하지 않습니다.
import { buildAtom } from '@0xintuition/primitives'
// 이것은 언제 어디서나 항상 동일한 ID를 생성합니다
...
이는 서로 다른 머신에서 실행되는 두 개의 서로 다른 애플리케이션이 동일한 GitHub 사용자에 대해 **정확히 동일한 원자 ID(atom ID)**를 도출할 것을 의미합니다. 별도의 조정(coordination)이나 중앙 레지스트리(central registry)가 필요하지 않습니다.
파이프라인 (The Pipeline)
수집(ingest) 파이프라인은 6단계로 구성됩니다:
1단계: 가져오기 및 정규화 (Fetch & Normalize)
├── GitHub REST API → 저장소 메타데이터, 기여자, PR, 이슈
└── npm Registry API → 패키지 이름, 버전
...
기술적 심층 분석 (Technical Deep Dive)
온체인 발행 (Onchain Publishing)
--publish 옵션과 함께 실행하면, 이 도구는 viem을 통해 Intuition 테스트넷(testnet)에 연결하고, MultiVault 컨트랙트로부터 현재 atom 생성 비용을 가져와 배치(batch) 단위로 발행합니다:
import { multiVaultCreateAtoms, multiVaultGetAtomCost } from '@0xintuition/protocol'
import { getMultiVaultAddressFromChainId } from '@0xintuition/deployments'
import { createWalletClient, http } from 'viem'
...
이 도구는 다음과 같은 여러 예외 상황(edge cases)을 유연하게 처리합니다:
MultiVault_AtomExists— atom이 이미 온체인(onchain)에 존재하는 경우, 건너뛰고 재시도합니다.MultiVault_TermDoesNotExist— 참조된 atom이 아직 존재하지 않는 경우, 해당 트리플(triple)을 건너뜁니다.Insufficient balance— 배치 작업 도중 지갑 잔액이 부족해지는 경우, 가능한 범위 내에서만 발행합니다.
트리플 그래프 (Triple Graph)
트리플은 atom들을 연결하여 하나의 그래프를 형성합니다:
┌──────────┐ contributedTo ┌──────────────────┐
│ Person │ ─────────────────→ │ Repository │
│ (fisker) │ │ (prettier/prettier)│
...
각 관계 유형은 **커스텀 술어 (custom predicate)**이며, 그 자체로 온체인 상의 atom입니다:
| 술어 (Predicate) | 주어 (Subject) | 목적어 (Object) | 의미 (Semantic) |
|---|---|---|---|
contributedTo | Person | Repo | 해당 인물이 최소 하나 이상의 기여를 함 |
| ... |
평판 점수 산정 (Reputation Scoring) — 완전 로컬 방식
평판 점수는 전적으로 로컬 그래프를 기반으로 계산됩니다. 온체인 읽기(onchain reads)가 전혀 필요하지 않습니다:
function computeReputation(githubHandle: string): ContributorReputation {
const atom = lookupByGithubHandle(githubHandle)
const triples = getAllTriples()
...
웹 익스플로러 (The Web Explorer)
web/ 디렉토리에는 **읽기 전용 익스플로러 (read-only explorer)**가 포함되어 있습니다. 프레임워크나 빌드 단계 없이 순수 HTML/CSS/JS(vanilla HTML/CSS/JS)로 구성되어 있습니다:
이 익스플로러는 Intuition GraphQL API (https://testnet.intuition.sh/v1/graphql)에 쿼리를 보내며, 해당 프로젝트의 지갑에 의해 생성된 atom 및 트리플만을 표시합니다. 임의의 atom을 클릭하면 해당 atom의 관계를 상세히 파헤쳐 볼 수 있습니다.
주요 설계 결정 사항:
- 지갑 연결 없음 (No wallet connection) — 익스플로러(explorer)는 순수하게 정보 제공 목적으로만 작동합니다.
- 생성자에 의한 필터링 (Filtered by creator) — 이 도구에 의해 게시된 데이터만 표시합니다.
- 정적 배포 (Static deploy) — 단일 HTML 파일로 구성되어 Vercel, Netlify 또는 모든 정적 호스트에 배포 가능합니다.
- 실시간 상태 (Live status) — 데이터가 인덱싱(indexed)되면 녹색 점, 인덱서(indexer)를 기다리는 중에는 황색 점을 표시합니다.
프로젝트 구조 (Project Structure)
who-built-this/
├── index.ts # 엔트리 포인트 (Entry point)
├── src/
...
도전 과제 및 학습 내용 (Challenges & Lessons Learned)
1. MultiVault 비용 계산 (The MultiVault Cost Calculation)
초기 구현에서는 예치 금액만을 msg.value로 전송했으나, Intuition MultiVault 컨트랙트는 그 외에 **기본 atom 생성 비용 (base atom creation cost)**을 추가로 부과합니다. 이를 해결하기 위해 multiVaultGetAtomCost()를 호출하여 assets 배열과 value 모두에 포함시켜야 했습니다.
// ❌ 잘못된 방식 — atom 비용 누락
const totalValue = ATOM_DEPOSIT * BigInt(batch.length)
...
2. 우아한 에러 핸들링 (Graceful Error Handling)
컨트랙트는 여러 가지 이유로 리버트(revert)될 수 있습니다. 이미 존재하는 atom, 존재하지 않는 atom을 참조하는 트리플(triples), 배치(batch) 중간의 잔액 부족 등이 그 예입니다. 이제 이 도구는 각 케이스를 다음과 같이 처리합니다:
// 재시도 루프를 통해 실패하는 항목을 하나씩 제거
while (pending.length > 0) {
try {
...
3. GraphQL 인덱서 지연 (GraphQL Indexer Latency)
트랜잭션은 RPC에 즉시 나타나지만 (상태 0x1), Hasura 기반의 GraphQL API는 테스트넷(testnet)에서 몇 분 또는 그 이상 지연될 수 있습니다. 익스플로러는 이를 알리기 위해 실시간 상태 표시기를 표시합니다.
기여 방법 (How to Contribute)
리포지토리는 github.com/harishkotra/who-built-this에 있습니다.
아이디어 제안 (Quick Ideas)
| 기능 (Feature) | 난이도 (Difficulty) | 포함 내용 (What's Involved) |
|---|---|---|
| GitLab 지원 (GitLab support) | 중간 (Medium) | GitHub 클라이언트와 함께 GitLab API 클라이언트 추가 |
| ... |
설정 (Setup)
git clone https://github.com/harishkotra/who-built-this.git
cd who-built-this
npm install
...
다음 단계 (What's Next)
- Intuition Mainnet — 술어 원자(predicate atoms)를 배포하고 프로덕션(production)에 게시
- Dependency Graph (의존성 그래프) — npm 의존성 트리(dependency trees)를 위한
dependsOn트리플(triples) 게시 - Scheduled Re-ingestion (예약된 재수집) — 새로운 데이터를 가져오기 위해 매주 저장소(repos)를 재수집하는 GitHub Action
- Reputation Leaderboard (평판 리더보드) — 전 세계 기여자(contributors)의 순위를 매기는 익스플로러(explorer)의
/leaderboard페이지 - Wallet-Connected Vouch (지갑 연결 보증) — 웹 UI에서 누구나 기여자를 직접 보증(vouch)할 수 있는 기능
Links
- GitHub: github.com/harishkotra/who-built-this
- Live Explorer: who-built-this.vercel.app
- Intuition Protocol: intuition.systems
- Intuition Testnet Explorer: testnet.explorer.intuition.systems
- Intuition GraphQL API: testnet.intuition.sh/v1/graphql
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기