Proof Server와 Indexer: Midnight가 트랜잭션을 처리하는 방법

발행: (2026년 4월 15일 PM 08:43 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

번역할 텍스트가 제공되지 않았습니다. 번역을 원하는 본문을 알려주시면 한국어로 번역해 드리겠습니다.

소개

Midnight는 영지식 증명(ZKP)을 사용하여 개인 거래를 가능하게 하는 데이터‑보호 블록체인입니다. 이 시스템의 핵심에는 두 가지 중요한 구성 요소가 있습니다:

  • Proof Server – 회로 입력으로부터 ZK 증명을 생성합니다.
  • Indexer – GraphQL을 통해 블록체인 데이터에 대한 쿼리 가능한 접근을 제공합니다.

이 가이드는 이러한 구성 요소를 설정하고 작업하는 방법을 단계별로 안내하여, Midnight 블록체인과 효율적이고 안전하게 상호 작용하는 애플리케이션을 구축할 수 있도록 도와줍니다.

전제 조건

  • Docker에 대한 기본 이해
  • GraphQL에 대한 친숙함
  • 로컬에 Node.js가 설치되어 있음

아키텍처 이해

트랜잭션 라이프사이클

User Input → Circuit Compilation → Proof Generation → Transaction Submission → Block Inclusion → Indexing

단계 1: 회로 컴파일

  • Midnight의 스마트 계약은 Compact으로 작성됩니다.
  • 이들은 연산을 정의하는 회로로 컴파일됩니다.

단계 2: 증명 생성

  • Proof Server는 회로 입력을 받아 ZK 증명을 생성합니다.
  • 증명은 입력을 공개하지 않고 연산을 검증합니다.
  • 서버는 별도의 Docker 컨테이너로 실행됩니다.

단계 3: 트랜잭션 제출

  • 생성된 증명이 네트워크에 제출됩니다.
  • 채굴자/검증자는 증명을 검증합니다.

단계 4: 블록 포함

  • 유효한 트랜잭션은 블록에 포함되며, 블록은 블록체인에 추가됩니다.

단계 5: 인덱싱

  • 인덱서는 새로운 블록을 스캔하고, 관련 데이터를 추출하여 GraphQL을 통해 쿼리 가능하게 합니다.

Proof 서버 설정

Docker 구성

# Pull the image
docker pull midnightnetwork/proof-server:2.2.0

# Run the container
docker run -d --name midnight-proof-server -p 8080:8080 midnightnetwork/proof-server:2.2.0

# View logs
docker logs midnight-proof-server

GraphQL 쿼리

query GetLatestBlocks {
  blocks(orderBy: height_DESC, limit: 10) {
    height
    hash
    timestamp
  }
}

WebSocket 구독

const ws = new WebSocket('ws://localhost:3000/v1/graphql');

ws.on('message', (data) => {
  const result = JSON.parse(data);
  console.log('New block:', result.payload.data.block);
});

인덱서 접근 패턴

indexerPublicDataProvider

자동 재시도가 포함된 간단한 API:

import { indexerPublicDataProvider } from '@midnight-ntwrk/dapp';

const provider = indexerPublicDataProvider({
  indexerUrl: 'http://localhost:3000'
});

const blocks = await provider.query({
  query: 'query { blocks(limit: 10) { height hash } }'
});

직접 인덱서 접근

요청에 대한 전체 제어:

const response = await fetch('http://localhost:3000/v1/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    query: 'query { blocks(limit: 10) { height hash } }'
  })
});

const data = await response.json();
```}

## 실용 예제: 계약 이벤트 모니터링

```typescript
async function monitorContractEvents(contractId: string) {
  const ws = new WebSocket('ws://localhost:3000/v1/graphql');

  ws.on('open', () => {
    ws.send(JSON.stringify({
      type: 'start',
      id: 'contract-monitor',
      payload: {
        query: `
          subscription ContractEvents($contractId: String!) {
            contractEvent(where: { contractId_eq: $contractId }) {
              eventName
              args
              transaction {
                hash
                timestamp
              }
            }
          }
        `,
        variables: { contractId }
      }
    }));
  });

  ws.on('message', (data) => {
    const event = JSON.parse(data);
    console.log('Contract event:', event);
  });
}

// Example usage
monitorContractEvents('0x1234...abcd');

문제 해결

Proof Server 연결 거부

docker ps | grep proof-server          # Verify container is running
docker start midnight-proof-server     # Start if stopped
docker logs midnight-proof-server       # Inspect logs for errors

버전 불일치

docker stop midnight-proof-server
docker rm midnight-proof-server
docker pull midnightnetwork/proof-server:<tag>
docker run -d --name midnight-proof-server -p 8080:8080 midnightnetwork/proof-server:<tag>

인덱서 동기화 문제

docker restart midnight-indexer
curl http://localhost:3000/health   # Should return a healthy status

주요 내용

  • Proof Server는 개인 거래를 위한 ZK 증명을 생성합니다.
  • Indexer는 블록체인 데이터에 대한 GraphQL 접근을 제공합니다.
  • 원장 버전에 맞는 Docker 태그 매칭이 중요합니다.
  • 두 가지 접근 패턴: dApp용 indexerPublicDataProvider, 백엔드 서비스용 직접 HTTP.
  • 실시간 업데이트는 WebSocket 구독을 통해 이용할 수 있습니다.

리소스

0 조회
Back to Blog

관련 글

더 보기 »

rabbitholes: 페이지를 떠나지 않고 인라인 지식

개요: 나는 지난주에 비잔틴 결함 허용성에 관한 기사를 읽었다. 세 번째 단락에서 “quorum‑based consensus”라는 구절을 마주했는데, 이는 손짓으로는 표현할 수 있지만 정확히 이해하기는 어려웠다.

새로운 스킬 배우기

안녕하세요, 저는 몇 달 동안 관심을 가져온 분야인 사이버 보안을 배우기 위해 100일 파이썬 챌린지를 잠시 중단하려고 합니다.