Private Channels 운영자란 무엇인가요?
운영자는 Solana 메인넷과 프라이빗 채널 네트워크를 연결하는, 신뢰할 수 있는 온체인 권한 부여 엔티티입니다. 운영자는 인스턴스 관리자가 AddOperator를 통해 프로비저닝하며, 이 과정에서 온체인 Operator PDA가 생성됩니다. 이 PDA 없이는 어떤 주체도 ReleaseFunds를 호출할 수 없습니다. 실제로 운영자는 입금을 감지하고, 채널 측 토큰을 발행하고, 출금을 감지하며, 메인넷으로 자금을 정산하는 서비스를 운영하는 조직 또는 팀입니다. 인스턴스를 운영하면 사용자에게 Solana 메인넷에 기록되지 않는 프라이빗 대용량 전송, 네이티브 Solana TPS를 초과하는 즉각적인 무수수료 처리량, 그리고 RBAC를 통한 접근 제어 기능을 제공할 수 있습니다.
기존 Private Channels 인스턴스를 직접 배포하는 것이 아니라 통합하는 개발자라면, 빠른 시작 가이드부터 시작하세요.
시작하기 전에
사전 요구 사항
Docker 이미지와 일치하도록 호스트에서 다음 버전을 고정하세요:
- Docker Engine 26 이상 (macOS Apple Silicon: 설정 -> 가상 머신 옵션에서 "Docker VMM" 활성화)
- Node.js 24.7.0 및 pnpm 10.15.1
- Solana CLI 3.1.13 (Agave)
- Rust 1.91.0
- Devnet용 Yellowstone gRPC 엔드포인트 (Helius, Triton, QuickNode에서 이용 가능)
네트워크 요구 사항 및 기본 포트 할당은 저장소의
docs/TECHNICAL_REQUIREMENTS.md를
참조하세요.
고정된 Solana 툴체인을 설치하고 SBF 캐시를 워밍업합니다:
make install-toolchain
서비스
Private Channels 인스턴스를 운영한다는 것은 Docker Compose 스택의 전용 컨테이너가 각각 담당하는 다섯 가지 지속적인 책임을 소유하는 것을 의미합니다:
- 입금을 위한 메인넷 인덱싱 -
indexer-solana는 Yellowstone gRPC를 통해 Solana 메인넷의Deposit이벤트를 감시하고,operator-solana는 확인된 입금을 처리하여 채널 네트워크에서 동등한 토큰 잔액을 발행합니다 - 출금을 위한 채널 인덱싱 -
indexer-private-channel은 매초 채널에서WithdrawFunds소각 이벤트를 폴링하고 데이터베이스에 대기 중인 출금 기록을 씁니다 - 메인넷에서 자금 해제 -
operator-private-channel은 대기 중인 기록을 처리하고 유효한 SMT 제외 증명과 함께 에스크로 프로그램에서ReleaseFunds를 호출합니다 - SMT 루트 관리 -
operator-private-channel은 트리 epoch가 순환될 때 자동으로ResetSmtRoot를 호출합니다. 온체인verify_smt_exclusion_proof검사는 무단 출금에 대한 최후의 방어선입니다 - 게이트웨이 및 인증 서비스 운영 - 게이트웨이는 모든 클라이언트 트래픽을 위한 단일 공개 엔드포인트이며, 인증 서비스(선택 사항)는
JWT_SECRET이 설정된 경우 JWT/RBAC를 적용합니다
전체 서비스 목록 및 포트 할당은 구성 참조를 확인하세요.
보안 참고 사항: 쓰기 노드 및 읽기 노드 포트는 루프백(
127.0.0.1)에만 바인딩되지만, 여러 다른 서비스(게이트웨이, 인증, 운영자 메트릭, Grafana, Prometheus, cAdvisor)는 기본적으로 모든 네트워크 인터페이스에 게시됩니다. 전체 포트 테이블은 구성 참조를 확인하고, 공개 배포 전에 방화벽을 설정하세요. RBAC는 게이트웨이 자체의 JSON-RPC 메서드만 적용되며, 이러한 다른 서비스에는 적용되지 않습니다.
접근 제어: 개방형 vs. RBAC
기본적으로 게이트웨이는 모든 연결을 허용하며 토큰이 필요하지 않습니다. JWT 기반 RBAC를 활성화하려면 JWT_SECRET을 설정하고 --profile auth로 스택을 시작하세요. operator 역할 프로비저닝 및 사용자 지갑 등록 방법을 포함한 전체 구성 참조는 **인증 및 역할**을 확인하세요.
인증을 활성화하는 경우, 스택을 시작하기 전에 환경에 다음을 추가하세요:
JWT_SECRET=<openssl rand -hex 32> # must match on gateway and auth serviceAUTH_PORT=8903
환경 설정
.env.devnet은 이미 저장소에서 추적되고 있으며 devnet 전용 기본값이 채워져 있습니다. 해당 기본값을 덮어쓸 수 있는 .env.example에서 재생성하는 대신, 직접 편집하세요.
아래 배포 단계를 진행하면서 나머지 값을 채우세요. 일부 값은 배포 중간에만 사용 가능합니다. 시크릿은 gitignore된 .env 파일에 넣고, 시크릿이 아닌 변수는 .env.devnet에 넣으세요.
시크릿 - 즉시 설정하세요:
POSTGRES_PASSWORD=<openssl rand -hex 32>POSTGRES_REPLICATION_PASSWORD=<openssl rand -hex 32>
배포 중에 얻는 변수:
ESCROW_INSTANCE_ID=<instance address - from Step 3>ADMIN_PRIVATE_KEY=<operator keypair as u8 array or base58 - from Step 4>DEVNET_RPC_URL=https://api.devnet.solana.comDEVNET_YELLOWSTONE_ENDPOINT=<your Yellowstone gRPC endpoint>INDEXER_YELLOWSTONE_TOKEN=<your Yellowstone auth token>
ADMIN_PRIVATE_KEY는 오프체인 서비스 자체에 필요한 수수료 지불자 서명자로,
3단계의 온체인 인스턴스 관리자와는 무관합니다. 이 가이드에서는 아래 4단계에서 생성된
운영자 keypair를 ADMIN_PRIVATE_KEY에 넣고 선택적인 OPERATOR_PRIVATE_KEY는
설정하지 않아, 운영자 서명자가 동일한 키로 폴백됩니다. 3단계의 프로토콜 수준 인스턴스 관리자
keypair는 어떤 변수에도 절대 넣지 마세요.
전체 환경 변수 참조는 **구성**을 확인하세요.
배포
Admin UI 설정
Admin UI는 에스크로 인스턴스를 생성하고 구성하기 위한 브라우저 기반 도구입니다: 개발 및
관리 유틸리티로, 사용자 대면 제품이 아니며 필수 런타임 구성 요소도 아닙니다. Admin UI가
수행하는 모든 작업(CreateInstance, AllowMint, AddOperator)은 저장소의
CLI 스크립트를 통해서도 실행할 수 있습니다.
cd admin-uipnpm installecho "PRIVATE_CHANNEL_RPC_URL=http://localhost:8899" > .envpnpm dev # opens at http://localhost:5173
에스크로 인스턴스 생성
- 브라우저 지갑을 Devnet으로 설정하고 수수료를 위한 Devnet SOL이 있는지 확인합니다
- Admin UI에서 새 인스턴스 생성을 클릭하고 트랜잭션을 승인합니다
- 인스턴스 주소를 복사하여
.env.devnet의ESCROW_INSTANCE_ID로 설정합니다
또는 CLI 스크립트를 사용하세요:
cargo run --bin create_instance -- https://api.devnet.solana.com ./keypairs/admin.json
운영자 keypair 생성
solana-keygen new -o operator-keypair.json -s --no-bip39-passphrasesolana-keygen pubkey operator-keypair.json
keypair 내용을 환경의 ADMIN_PRIVATE_KEY로 설정하세요. 공개 키는 환경 변수가 아니며,
아래 "인스턴스 구성" 단계에서 운영자 pubkey로 직접 전달합니다.
환경 변수 최종 설정
ESCROW_INSTANCE_ID, DEVNET_RPC_URL, DEVNET_YELLOWSTONE_ENDPOINT,
INDEXER_YELLOWSTONE_TOKEN으로 .env.devnet을 업데이트하세요. 시크릿
(POSTGRES_PASSWORD, POSTGRES_REPLICATION_PASSWORD, ADMIN_PRIVATE_KEY)은
gitignore된 .env 파일에 넣으세요.
RBAC를 활성화하기로 결정한 경우
(접근 제어: 개방형 vs. RBAC), 지금
JWT_SECRET과 AUTH_PORT도 추가하세요.
모든 서비스 시작
인증 없이:
make docker-devnet-up
인증 포함:
docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet --env-file .env --profile auth up -d
--env-file 플래그가 하나라도 전달되면 Compose는 자동 .env 자동 로드를 비활성화하므로,
마지막의 --env-file .env가 필수입니다. 이것 없이는 .env에 넣은
POSTGRES_PASSWORD, ADMIN_PRIVATE_KEY, JWT_SECRET이 빈 값으로 해석되어
스택이 올바르게 시작되지 않습니다.
인스턴스를 구성하기 전에 서비스를 먼저 시작하세요. 인덱서는 실시간으로 이벤트를 스트리밍하므로, 스택을 먼저 실행하면
AllowMint와 첫 번째 입금이 백필 없이 순서대로 인덱싱됩니다.
인스턴스 구성
스택이 실행 중인 상태에서 Admin UI를 통해 토큰 민트를 허용 목록에 추가하고 운영자를 등록합니다:
- 민트 허용: 관리자 기능 -> 민트 관리 -> 민트 주소 입력 -> 민트 허용
- 운영자 추가: 관리자 기능 -> 운영자 관리 -> 운영자 pubkey 입력 -> 운영자 추가
또는 CLI를 통해:
cargo run --bin add_operator -- \https://api.devnet.solana.com \./keypairs/admin.json \<INSTANCE_ID> \<OPERATOR_PUBKEY>
이 가이드는 Solana devnet을 대상으로 합니다. 메인넷의 경우:
- 프로그램 ID는
declare_id!()를 통해 컴파일 시 포함됩니다: 저장소에서 올바른 메인넷 ID를 사용하고 있는지 확인하세요 - Yellowstone gRPC 엔드포인트는 메인넷 플랜이 필요합니다. devnet 엔드포인트는 메인넷 이벤트를 스트리밍하지 않습니다
- 운영자 지갑은 모든
ReleaseFunds호출에 대해 SOL 수수료를 지불하므로, 예상 출금량에 맞게 SOL 잔액을 조정하세요 - 공개 배포 전에 모든 기본 자격 증명(Grafana, PostgreSQL)을 변경하세요
운영
유용한 명령어
# View logs (all services)make docker-devnet-logs# View logs (specific service)docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-solana# Stop servicesmake docker-devnet-down# Stop and wipe all state (volumes)make docker-devnet-clean
관찰 가능성
스택에는 메트릭 및 컨테이너 모니터링을 위한 Prometheus, Grafana, cAdvisor가 포함되어 있습니다. Grafana는 포트 37429에서 접근할 수 있습니다.
기본 Grafana 비밀번호는 admin입니다. 포트 37429를 localhost 이외의 네트워크에
노출하기 전에 변경하세요.
문제 해결
입금 후 채널 잔액이 업데이트되지 않음
- 메인넷 입금 트랜잭션이 메인넷 익스플로러에서 완료되었는지 확인합니다
indexer-solana가 실행 중인지 확인합니다:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-solanaoperator-solana가 실행 중인지 확인합니다:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-solana- Yellowstone gRPC 엔드포인트에 연결 가능하고 토큰이 유효한지 확인합니다
(
DEVNET_YELLOWSTONE_ENDPOINT,INDEXER_YELLOWSTONE_TOKEN) - 인덱서가 크레딧 처리 전에 최종성 안전 지연을 적용하므로, 온체인 확인 후 최대 30초를 기다립니다
출금이 메인넷으로 정산되지 않음
indexer-private-channel이 실행 중인지 확인합니다:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-private-channeloperator-private-channel이 실행 중인지 확인합니다:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-private-channelADMIN_PRIVATE_KEY의 운영자 keypair가 온체인에서AddOperator로 등록된 키와 일치하는지 확인합니다- 로그에 "SMT root mismatch"가 표시되면 서비스가 잘못된 증명 제출을 방지하기 위해 종료됩니다. 스택을 중지하고 일관된 상태로 복원한 후 재시작하세요
JWT 인증 실패 (모든 요청에서 401)
- 게이트웨이 컨테이너와 인증 서비스 컨테이너에서
JWT_SECRET이 동일한지 확인합니다 - 스택이
--profile auth로 시작되었는지 확인합니다 - 토큰은 24시간 후 만료됩니다. 새 토큰을 얻으려면 다시 인증하세요
첫 번째 빌드가 너무 오래 걸림
정상입니다. 첫 번째 make docker-devnet-build는 모든 Rust 서비스를 컴파일하며 일반적인 하드웨어에서 30~60분이 소요될 수 있습니다. 이후 빌드는 Docker 레이어 캐시를 사용하여 훨씬 빠릅니다.
다음 단계
Is this page helpful?