Skip to main content

5 posts tagged with "midnight"

View All Tags

앱 배포를 위한 협업 절차 안내

· 2 min read
Lauren Lee
Director of Developer Relations

현재 이 단계에서는, 위험 자체 평가 루브릭을 충족한 애플리케이션에 한해 Midnight 네트워크 배포가 허용됩니다. 이 가이드에서는 배포 전 DApp의 위험도를 평가하는 방법을 설명합니다.

Step 1: Read the rubric

Contract Deployment Rubric부터 시작하세요. DApp이 평가받게 될 세 가지 위험 범주를 정의합니다:

  • Privacy-at-risk: ZK에 결함이 생기면 사용자가 잃게 되는 것은 무엇인가?
  • Value-at-risk: 익스플로잇 발생 시 사용자 손실 규모는 어느 정도이며, 복구가 가능한가?
  • State-space-at-risk: 컨트랙트가 생성하는 영구 원장 상태의 규모와 그 증가분이 공격에 악용될 수 있는가?

각 범주는 1~3점으로 채점됩니다. 점수는 발생 가능성이 아니라, 문제 발생 시 실제로 무엇이 영향을 받는지를 반영합니다.

Step 2: Self-assess your contract

루브릭의 등급 정의를 사용하여 세 범주 모두에서 DApp을 솔직하게 채점하세요.

어느 하나의 범주에서라도 3점이 나온다면, 근본 원인을 해결하기 전에는 애플리케이션을 배포해서는 안 됩니다. 3점은 영구적인 상태가 아니라, 아키텍처를 재검토하라는 신호입니다. Discord의 #dev-chat이나 개발자 포럼에서 컨트랙트 구조를 공유해 보세요. DevRel 팀과 Aliit 커뮤니티가 위험도를 낮추는 설계 방향을 함께 고민해 줄 수 있습니다.

모든 범주에서 1 또는 2점이면, 다음 단계로 진행할 준비가 된 것입니다.

Step 3: Pull Request via GitHub

배포 제안은 Midnight Improvement Proposals 저장소에 Pull Request로 제출합니다.

제출 방법:

  1. 저장소를 포크하세요
  2. deployments/ 폴더에 your-dapp-name.md라는 새 파일을 생성하세요
  3. 메인 브랜치에 대해 [Deployment Request] Your DApp Name이라는 제목으로 Pull Request를 열어주세요

파일에 다음 내용을 포함하세요:

  • DApp이 무엇을 하는지에 대한 간략한 설명
  • 각 범주에 대한 자체 평가 점수(1, 2 또는 3)와 각각에 대한 짧은 근거
  • 높은 점수를 받은 범주에 대해 구현한 완화 조치
  • 컨트랙트 코드 또는 저장소 링크

Step 4: What happens next

Midnight Foundation이 제출물을 검토합니다. 점수가 적절하면 배포 자격 증명을 발급받게 됩니다. 검토 과정에서 문제가 확인되면, 재제출 전에 수정해야 할 사항을 피드백으로 안내합니다.

현재 고정된 검토 일정은 없습니다. 결정이 내려지는 대로 안내드리겠습니다.

질문이 있나요? Discord의 #dev-chat에 참여하거나 개발자 포럼에 글을 남겨주세요.

프로젝트를 Midnight 생태계에 등록하세요

· 4 min read
Lauren Lee
Director of Developer Relations

여러분의 프로젝트가 Midnight 생태계에서 눈에 보이고, 집계되고, 인정받게 하기 위한 세 가지 간단한 조치를 안내합니다.

Why this matters

Midnight은 메인넷 출시를 앞두고 있습니다. 이미 수백 명의 개발자가 Compact으로 개발하고, Preprod에 배포하며, 실제 애플리케이션을 출시하고 있습니다. 하지만 출처가 표시되지 않은 활동은 집계에 잡히지 않으며, 이 비가시성은 여러분이 함께 만들어가는 생태계에 실질적인 영향을 미칩니다.

개발 활동의 공개 기록을 명확히 남기면, 블록체인 업계 전체가 Midnight Network의 성장을 인지하게 됩니다. 정확한 출처 표시는 생태계 운영의 필수 요소이며, 기술 기여를 문서화하는 표준 체계를 마련합니다.

The attribution process

Electric Capital은 블록체인 업계에서 가장 널리 인용되는 개발자 리포트를 발행합니다. 투자자, 프로토콜, 미디어 모두 이 리포트를 통해 어떤 생태계가 성장하고, 어떤 것이 정체되어 있으며, 어디에 주목해야 하는지 판단합니다. 방법론은 공개되어 있으며, 주요 블록체인 생태계의 GitHub 커밋 수, 기여자 수, 저장소 메타데이터를 추적합니다. 저장소에 올바른 메타데이터가 없으면, 아무리 활발하고 질 높은 작업이라도 Midnight 생태계로 인식되지 않습니다.

Midnight은 메인넷 출시 전 처음으로 Electric Capital에 생태계 맵을 제출합니다. 생태계의 출발점을 신뢰할 수 있는 공개 기록으로 남길 수 있는 단 한 번의 기회입니다. 메인넷 출시 전후 몇 주간의 개발자 수는 새 생태계의 순위와 보도에 반영되는 롤링 윈도우에 포착됩니다. 이 윈도우에서 강한 수치를 보여주는 생태계는 주목받고, 그렇지 못한 생태계는 수개월간 만회하기 어려운 불리한 출발을 하게 됩니다.

Compounding developer results

아래 변경 사항은 저장소당 5분도 걸리지 않습니다. 작지만 영구적이고 중요한 작업입니다. 코드 작성 외에도 이런 메타데이터 표준을 적용하는 것은 생태계 성장에 큰 영향을 미칩니다. 이 작업을 완료한 저장소의 개발자는 Midnight 생태계 기여자로 공식 인정됩니다.

TL;DR: Midnight의 개발자 생태계는 실재하며 성장하고 있습니다. 이 세 단계를 통해 업계가 주목하는 도구와 리포트에서 그 성장이 가시적으로 드러나도록 합니다.

Step 1: Add GitHub topics

GitHub 토픽은 Electric Capital을 비롯한 생태계 추적 도구가 저장소의 소속 생태계를 자동으로 식별하는 수단입니다. 토픽이 없으면 아무리 활발하게 관리되는 저장소라도 추적 도구에 잡히지 않습니다.

저장소에 토픽을 추가하려면:

  1. GitHub에서 저장소로 이동하세요

  2. 오른쪽 사이드바에서 About 섹션을 찾으세요

  3. 옆에 있는 기어 아이콘을 클릭하세요

  4. Topics 필드에 아래 표의 관련 토픽을 추가하세요

  5. Save changes를 클릭하세요

TopicWhen to use
midnightntwrk모든 Midnight 생태계 프로젝트에 필수
compact프로젝트가 Compact 언어를 사용하는 경우에만 추가
warning

사용하지 마세요: midnight, midnight-network, midnight-compact, midnight-ecosystem. 이러한 변형은 추적되지 않으며 프로젝트를 생태계와 연결하지 않습니다.

Step 2: Add one attribution sentence to your README

Electric Capital의 도구는 README 파일을 스캔하여 저장소가 해당 생태계와 관련 있는지 확인합니다. README 상단 근처에 한 문장만 추가하면 됩니다. 반드시 아래 표의 정확한 문구를 사용하세요. 임의로 수정하면 자동화 시스템이 인식하지 못할 수 있습니다.

Your project typeAttribution sentence
Midnight 위에서 직접 실행되는 dApp, 컨트랙트 또는 도구"This project is built on the Midnight Network."
SDK, 인프라, 지갑 또는 서비스"This project integrates with the Midnight Network."
개발자 도구, 프레임워크 또는 라이브러리"This project extends the Midnight Network with additional developer tooling."

Step 3: Open a PR to the Awesome dApps list

Midnight Awesome dApps list는 커뮤니티가 관리하는 생태계 프로젝트 디렉터리입니다. PR을 열면 해당 기록에 프로젝트가 추가되어 다른 개발자, 파트너, 생태계를 평가하는 팀이 발견할 수 있게 됩니다.

프로젝트를 제출하세요: github.com/midnightntwrk/midnight-awesome-dapps.

Earn Zealy points while you're at it!

위 세 단계 각각에 해당하는 Zealy 퀘스트가 있습니다. 완료하면 포인트를 획득하고 Midnight 생태계 리더보드에 등장합니다. 세 퀘스트 링크는 아래와 같습니다.

Three steps, once per repo, permanent record

이 변경은 코드 동작에는 영향을 주지 않습니다. 여러분의 작업이 어떻게 보이는지에 영향을 줍니다. Midnight의 최초 공개 개발자 수는 향후 수년간 업계 리포트, 투자자 브리핑, 생태계 비교에 계속 인용됩니다. 여러분의 저장소가 그 수에 반드시 포함되어야 합니다.

질문이 있으면 Midnight Discord의 #dev-chat에서 찾아주시거나, 이 글에 답글을 남겨주세요.

Midnight의 FungibleToken 컨트랙트 소개

· 9 min read
Claude Barde
Developer Relations

Introduction to the FungibleToken contract on Midnight

Midnight은 탈중앙화 애플리케이션에 프라이버시를 제공하기 위해 설계된 프라이버시 우선 블록체인입니다. 영지식 증명, 프로그래밍 가능한 데이터 보호, 그리고 개발자 친화적 도구Compact(TypeScript 기반 DSL, 도메인 특화 언어)을 통해 이를 실현합니다.

OpenZeppelin은 Ethereum 생태계에서 실전 검증된 스마트 컨트랙트 라이브러리로 유명하며, 온체인에서 수조 달러 규모의 가치를 보호해 왔습니다. 최근 OpenZeppelin은 Midnight과 파트너십을 맺고 ERC-20과 같은 친숙한 표준을 프라이버시 보존 버전으로 적용하여 Compact 생태계에 유사한 도구를 제공하고 있습니다.

Ethereum 세계에서 ERC-20 표준은 balanceOf, transfer, approve 등의 공개 원장 함수를 가진 대체 가능 토큰을 정의합니다. 트랜잭션 데이터를 투명하게 노출하며 내장된 프라이버시가 없습니다. Midnight의 FungibleToken 컨트랙트는 여기서 영감을 얻었지만, Midnight의 영지식, 선택적 공개 프레임워크 안에서 동작합니다.

대체 가능 토큰(Fungible Token)은 블록체인 생태계의 핵심 요소로, 전통 화폐처럼 서로 교환 가능한 디지털 자산입니다. 거래 촉진, DeFi 프로토콜 운영, 디지털 커뮤니티 내 소유권 표현, 게임 내 경제 구동 등 폭넓게 활용됩니다.

각각 고유한 NFT와 달리, 대체 가능 토큰은 같은 종류끼리 동일한 가치를 지니므로 분할과 교환이 필요한 사용 사례에 적합합니다. 이런 폭넓은 채택은 유동적이고 상호 연결된 디지털 경제에서 대체 가능 토큰이 얼마나 중요한지를 보여줍니다.

이 글에서는 컨트랙트의 핵심 기능을 다룹니다. 원장 상태 변수 관리, 민팅/소각/전송 등 주요 진입점과 서킷, 그리고 UtilsInitializable 모듈의 안전 및 유틸리티 함수를 살펴봅니다. 이 구성 요소들의 관계를 이해하면, FungibleToken 컨트랙트가 대체 가능성, 사용성, 프라이버시를 어떻게 균형 있게 달성하는지 파악할 수 있습니다. Midnight에서 프라이버시 보존 DeFi, 신원 확인, 토큰화 자산을 구현하기 위한 필수 빌딩 블록입니다.


Features of the FungibleToken Contract

Midnight의 FungibleToken 컨트랙트는 원장 상태 변수를 활용하여 잔액, 허용량, 총 공급량, 이름, 심볼, 소수점을 추적합니다. 기능은 Mint, Burn, Transfer, Approve, TransferFrom, Initialize 등의 "서킷"(진입점)을 통해 노출되며, 모두 특정 영지식 검증 전환을 강제하고 토큰 상태의 무결성을 유지합니다.

Ledger State Variables

Compact에서 컨트랙트는 토큰 잔액과 허용량을 저장하는 구조화된 상태를 정의합니다. ERC-20과 유사합니다. _balances 맵은 사용자의 토큰 잔액을 추적하며 전송이 발생할 때 업데이트됩니다. _allowances 맵은 다른 사용자를 대신하여 토큰을 사용할 수 있도록 특정 사용자에게 부여된 권한을 추적합니다:

export ledger _balances: Map<Either<ZswapCoinPublicKey, ContractAddress>, Uint<128>>;
export ledger _allowances: Map<Either<ZswapCoinPublicKey, ContractAddress>, Map<Either<ZswapCoinPublicKey, ContractAddress>, Uint<128>>>;

이 값들은 컨트랙트의 원장에 저장되며, 컨트랙트로 전송된 트랜잭션을 통해 업데이트됩니다.

컨트랙트 배포 시 설정되는 다른 값들도 있습니다:

export ledger _totalSupply: Uint<128>;
export sealed ledger _name: Opaque<"string">;
export sealed ledger _symbol: Opaque<"string">;
export sealed ledger _decimals: Uint<8>;

이 값들은 컨트랙트가 관리하는 토큰에 대한 다양한 정보를 제공합니다. 총 공급량, 이름, 심볼, 소수점(표시용) 등입니다.

Entry Points and Circuits

Compact에서 진입점은 서킷(Solidity 함수와 유사)으로 정의되며, 각각 영지식 검증 전환을 모델링합니다. 서킷 진입점과 서킷의 차이점은 진입점은 트랜잭션을 통해 호출할 수 있지만, 진입점이 아닌 서킷은 내부용이라는 것입니다. 핵심 서킷은 다음과 같습니다:

  • Mint / Burn (새 토큰을 민팅하거나 기존 토큰을 소각).

  • Transfer: 주소 간 토큰 이동.

  • Approve, TransferFrom: 표준 ERC-20 스타일 위임 메커니즘.

  • Initialize: Initializable 모듈을 통한 컨트랙트 설정.

각 서킷은 필요한 제약 조건을 강제합니다. 예를 들어 충분한 잔액 확인, 허용량 차감 관리, 총 공급량 보존 등입니다.

컨트랙트 수명 주기의 다음 단계에서는 컨트랙트의 원장에 저장된 다양한 메타데이터가 안전하게 초기화됩니다.

Initialization and Metadata**

다음 서킷들은 대체 가능 토큰 메타데이터와 사용자 잔액을 위한 필수 설정 및 조회 로직을 정의하며, 올바른 초기화를 강제합니다.

  • initialize(name_, symbol_, decimals_) 일회성 설정입니다. Initializable_initialize()를 호출한 뒤, (공개된) 이름, 심볼, 소수점을 저장합니다. 다른 모든 공개 서킷은 먼저 컨트랙트가 초기화되었는지 확인합니다.

  • name() / symbol() / decimals() / totalSupply() 초기화 여부를 먼저 확인한 뒤 봉인된(읽기 전용) 원장 값을 반환하는 간단한 게터입니다.

  • balanceOf(account) 키가 없는 경우 컨트랙트 실패를 방지하기 위해 0을 반환하는 안전한 맵 조회입니다.


The Transfer Family

FungibleToken 컨트랙트의 전송 서킷은 토큰 이동을 관리합니다. 주요 서킷은 다음과 같습니다: 안전한 사용자 주도 전송을 위한 transfer, 내부 토큰 이동을 위한 _unsafeTransfer, 관리자 전송을 위한 _transfer, 저수준 토큰 이동을 위한 _unsafeUncheckedTransfer, 그리고 모든 토큰 작업의 중앙 회계 함수인 _update.

안전한 변형과 안전하지 않은 변형으로 나뉘는 이유는 현재 컨트랙트 주소로의 전송이 허용되지 않기 때문입니다(컨트랙트 간 상호작용이 지원될 때까지).

"안전한" 서킷은 이 정책을 강제하고, "안전하지 않은" 서킷은 이를 우회할 수 있으며, 주석에 위험하다고 명시적으로 표시되어 있습니다.

  • transfer(to, value) -> Boolean 안전한 사용자 주도 전송: toContractAddress이면 거부합니다. 내부적으로는 검사 후 안전하지 않은 변형으로 전달합니다.

  • _unsafeTransfer(to, value) -> Boolean 소유자가 호출자(left(ownPublicKey()))입니다. 검사 없는 내부 이동 함수를 사용하여 값을 이동한 뒤 true를 반환합니다.

  • _transfer(from, to, value) -> [] 관리자/확장 훅으로, 임의의 from에서 토큰을 이동합니다(반드시 호출자일 필요 없음). "컨트랙트를 to로 사용할 수 없음" 규칙은 여전히 강제되며, 내부적으로 동일한 이동 함수를 사용합니다.

  • _unsafeUncheckedTransfer(from, to, value) -> [] 저수준 이동 함수로, 양쪽이 영/소각 주소가 아닌지 확인한 뒤 실제 회계를 _update에 위임합니다.

  • _update(from, to, value) -> [] 모든 민팅/소각/전송 경로에서 사용되는 중앙 회계 함수입니다. 내부 서킷으로, 트랜잭션을 통해 호출할 수 없습니다.

    • from이 영 주소이면 민팅 서킷이 호출되어 uint128 오버플로우가 없는지 확인하고 _totalSupply를 증가시킵니다.

    • 그렇지 않으면 from 잔액에서 차감합니다(잔액 부족 시 되돌림).

    • to가 영 주소이면 소각 서킷이 호출되어 _totalSupply를 감소시킵니다.

    • 그렇지 않으면 to 잔액에 추가합니다. 이 단일 함수가 모든 가치 이동에 대한 불변성을 보장합니다.

"전송 계열" 서킷은 안전한 토큰 이동을 보장하며, "안전한" 변형은 컨트랙트 주소로의 전송을 차단하고 "안전하지 않은" 변형은 저수준 제어를 제공합니다. 다음으로 허용량이 어떻게 작동하여 위임된 토큰 사용을 가능하게 하는지 살펴보겠습니다.


Allowances (approve / spend / transferFrom)

이 섹션에서는 FungibleToken 컨트랙트의 허용량(allowance) 메커니즘을 다룹니다. 사용자가 다른 주소에 토큰 지출 권한을 위임할 수 있는 서킷들로, 소유자의 개인 키를 직접 노출하지 않고도 대리 전송이 가능합니다.

  • allowance(owner, spender) 중첩된 _allowances 맵을 읽으며, 키가 없을 때 0을 반환합니다(되돌림 없음).

  • approve(spender, value) -> Boolean 소유자가 호출자입니다. _approve(owner, spender, value)로 전달하고 true를 반환합니다.

  • transferFrom(from, to, value) -> Boolean 안전한 위임 전송: "컨트랙트 수신자 불가" 규칙을 강제한 뒤, _unsafeTransferFrom에 위임합니다.

  • _unsafeTransferFrom(from, to, value) -> Boolean 지출자가 호출자입니다. 먼저 _spendAllowance(from, spender, value)를 통해 허용량을 사용한 뒤, _unsafeUncheckedTransfer로 값을 이동합니다. true를 반환합니다.

  • _approve(owner, spender, value) -> [] 소유자와 지출자가 모두 유효한지 확인하고, 필요하면 맵에 소유자 항목을 생성한 뒤 허용량을 기록합니다. (OZ의 ERC-20 패턴인 공개 approve() -> 내부 _approve() 구조를 따릅니다.)

  • _spendAllowance(owner, spender, value) -> [] "무한"이 아닌 한 허용량에서 차감합니다. 구현에서 **MAX_UINT128**을 무한으로 취급합니다: currentAllowance == MAX이면 차감하지 않고, 그렇지 않으면 currentAllowance >= value를 확인한 뒤 currentAllowance - value를 기록합니다. 이는 앱이 MAX를 한 번 설정하면 추가 승인 없이 사용할 수 있는 "무마찰 승인"을 지원하기 때문에 중요합니다.

지금까지 토큰 지출을 다른 주소에 위임하는 허용량 메커니즘을 살펴보았습니다. 다음으로 토큰의 생성(민팅)과 소멸(소각) 방법을 알아보겠습니다.


Minting and Burning

FungibleToken 컨트랙트가 토큰을 생성하고 소멸하는 방법입니다. _mint_burn 함수가 무엇을 하고 주요 회계 시스템과 어떻게 연결되는지 살펴보겠습니다.

  • _mint(account, value) (안전한) -> [] 컨트랙트 주소로의 민팅을 금지합니다(동일한 컨트랙트 간 제한). _unsafeMint로 전달합니다.

  • _unsafeMint(account, value) -> [] 수신자 주소를 검증한 뒤, _update(burnAddress(), account, value)를 호출합니다. 즉, 민팅은 소각/영 주소로부터의 전송으로 모델링됩니다.

  • _burn(account, value) -> [] 발신자 주소를 검증한 뒤, _update(account, burnAddress(), value)를 호출합니다. 즉, 소각은 소각/영 주소로의 전송입니다. 참고: "영/소각" 주소의 실제 개념은 Utils 모듈에서 표준화되어 있습니다. Utils_isKeyOrAddressZeroUtils_isContractAddress 같은 헬퍼도 확인할 수 있습니다.

민팅과 소각도 _update를 통해 라우팅되므로, 총 공급량은 정확히 한 곳에서만 조정되며, 모든 흐름에 동일한 안전 검사가 적용됩니다(민팅 시 uint128 오버플로우 검사 포함).

민팅과 소각 서킷은 _update 함수를 사용함으로써 총 공급량 조정이 항상 일관되고 모든 토큰 흐름에 동일한 안전 검사가 적용되도록 보장합니다. 이제 UtilsInitializable 모듈이 제공하는 추가 안전 및 유틸리티 기능을 살펴보겠습니다.


Safety and Utility Glue (from Utils and Initializable)

UtilsInitializable 모듈이 제공하는 핵심 보호 장치와 유틸리티 함수를 살펴봅니다. 컨트랙트의 무결성을 유지하고 안전한 운영을 보장하는 필수 구성 요소입니다.

  • 초기화 가드: Initializable_initializeInitializable_assertInitialized 함수는 초기화 가드 역할을 합니다. 컨트랙트 상태가 단 한 번만 올바르게 설정되고, 초기화가 완료된 경우에만 이후 작업이 진행되도록 보장합니다. 상태를 읽거나 수정하는 모든 서킷은 assert 함수를 호출하여 초기화 무결성을 검증합니다.

  • 주소 헬퍼:

    • Utils_isContractAddress(either): 사용자 키와 컨트랙트 주소를 구분합니다.

    • Utils_isKeyOrAddressZero(either): _update, _unsafeUncheckedTransfer 등에서 사용되는 영/소각 주소를 감지합니다. 이들은 임시 "컨트랙트 수신자 불가" 정책과 영 주소 검사를 지원합니다.

UtilsInitializable 모듈은 컨트랙트의 올바른 설정과 안전한 운영을 뒷받침합니다. 다음으로 FungibleToken 컨트랙트의 전체 구성 요소가 어떻게 맞물려 동작하는지 살펴보겠습니다.


How the Pieces Fit Together

FungibleToken 컨트랙트의 모든 구성 요소가 어떻게 연결되는지 정리합니다. 직접 전송이든, 위임 전송이든, 민팅이든, 소각이든, 결국 몇 가지 핵심 함수를 거쳐 최종적으로 _update 함수에서 회계 처리됩니다.

  • 사용자 전송: transfer -> (안전 검사) -> _unsafeTransfer -> _unsafeUncheckedTransfer -> _update (잔액/공급량)

  • 위임 전송: transferFrom -> (안전 검사) -> _unsafeTransferFrom -> _spendAllowance -> _unsafeUncheckedTransfer -> _update

  • 민팅/소각: _mint/_unsafeMint 또는 _burn -> _update (한쪽에 영/소각 주소)

사용자 전송, 민팅, 소각 등 모든 토큰 작업이 중앙 _update 함수를 통해 일관된 회계를 유지하는 구조를 살펴보았습니다. 마지막으로 Midnight FungibleToken 컨트랙트의 핵심 사항을 정리합니다.


Conclusion

Midnight의 FungibleToken Compact 컨트랙트는 ERC-20 표준을 프라이버시 관점에서 재설계한 것입니다. 잔액, 전송, 승인 등 익숙한 토큰 인터페이스는 그대로 유지하면서, Compact의 ZK 검증 서킷으로 인코딩하여 비공개이면서도 검증 가능한 실행을 달성합니다. 컨트랙트의 상태와 로직은 설계 단계부터 보호되며, 원시 데이터가 아닌 증명만 블록체인에 기록됩니다.

ERC-20 표준은 디지털 자산의 생성과 관리를 위한 공통 프레임워크를 제공하여 상호운용성을 높이고 탈중앙화 애플리케이션의 성장을 가속했습니다. Midnight의 ERC-20 기반 토큰은 이 검증된 표준을 유지하면서 ZK 프라이버시를 결합하여, 기능성과 기밀성 모두를 필요로 하는 개발자와 사용자에게 친숙하면서도 한 단계 발전된 경험을 제공합니다.

모든 토큰 이동과 잔액이 완전히 투명한 Ethereum의 ERC-20과 달리, Midnight은 선택적 공개를 지원합니다. 사용자와 애플리케이션이 무엇을 공개할지 직접 결정합니다. FungibleToken 컨트랙트는 대체 가능성, 사용성, 프라이버시의 균형을 달성하여, Midnight 기반 프라이버시 보존 DeFi, 신원 확인, 토큰화 자산의 필수 빌딩 블록 역할을 합니다.


코드, 컨트랙트, 문서를 직접 살펴보세요.

난관을 넘어 프레임워크를 만들기까지: Midnight 개발기

· 6 min read
Kaleab Abayneh
Kaleab Abayneh
Guest Contributor

올해 세 번의 해커톤에 참가한 뒤, 무엇을 기대해야 하는지 충분히 알고 있다고 생각했습니다. 그런데 네 번째 해커톤은 달랐습니다. 아이디어, 도전, 빈 터미널 화면이라는 똑같은 시작이었지만, 예상치 못한 방향으로 흘러갔습니다.

얼마 전 소프트웨어 엔지니어 직책을 떠나 영지식 프로토콜을 탐구하기 시작했습니다. 경험이 거의 없는 분야였지만, 반드시 도전해야 한다고 느꼈습니다. 영지식 암호학이 수학에서 가장 우아한 분야 중 하나를 기반으로 한다는 점도 있었지만, 블록체인이나 인터넷에서의 프라이버시는 근본적인 가치이며 결코 뒷전으로 밀려서는 안 된다고 믿었기 때문입니다.

어느 날, 멘토가 African Blockchain Championship을 언급하며 Zero-Knowledge 트랙을 살펴보라고 권했습니다. 그 작은 한마디가 전환점이 되었습니다.

바로 그때 Midnight을 발견했습니다!

Meet Midnight: Privacy on the Blockchain

Midnight은 Input Output이 개발한 영지식 증명 기반 프라이버시 체인으로, Cardano의 파트너 체인입니다. 영지식 기술로 더 넓은 생태계에 합리적인 프라이버시를 제공하는 것이 목표입니다. 단순히 또 하나의 블록체인이 아니라, 비공개 분산 컴퓨팅의 기반을 구축하고 있었습니다. 문서를 읽고 도구를 설정하니 준비는 끝났습니다. 남은 건 시작뿐. 나중에야 깨달았지만, 이것은 해커톤의 시작이 아니라 훨씬 더 큰 무언가의 시작이었습니다.

Building on Midnight

Midnight 위에서 개발하는 것은 쉽지 않았습니다. 테스트넷 환경에서는 끊임없이 배워야 했고, 잦은 변경에 계속 적응해야 했습니다. 불과 몇 주 만에 대규모 네트워크 업데이트가 이루어져 기존 예제가 최신 SDK 버전과 호환되지 않게 되었습니다. 결국 예제를 클론해서 한 줄씩 디버깅해야 했습니다. 예제 저장소는 파일과 디렉터리가 겹겹이 쌓여 있어 어디서부터 시작해야 할지 파악하는 것 자체가 도전이었습니다.

다행히 Midnight의 스마트 컨트랙트 언어인 Compact은 TypeScript와 비슷한 문법을 사용해서 학습 곡선이 완만했습니다. 의미 있는 결과물을 만들겠다는 각오로 밀고 나갔지만, 결국 시도는 부족했습니다. 중간고사가 다가오고 해커톤 제출 마감일이 임박한 상황에서 어려운 결정을 내려야 했습니다. African Blockchain Championship 해커톤에 프로젝트를 제출하지 않기로 한 것입니다. 그래도 아쉬움이 남았습니다. 조금만 노력했더라면 어떻게 되었을까 하는 생각이 계속 맴돌았습니다.

The Extended Deadline

약 일주일 뒤, ABC 팀에서 해커톤 마감 기한이 연장되었다는 이메일이 왔습니다. 기뻤고, 이번에는 전력을 다하겠다고 다짐했습니다. 얼마 지나지 않아 다시 작업에 돌입했습니다. 프로젝트를 마지막으로 손댄 지 몇 주가 지난 사이 네트워크와 SDK가 모두 업데이트되어 있었습니다. 장비를 챙기고 환경을 업데이트한 뒤, 이번에야말로 확실한 결과물을 만들겠다는 새로운 각오로 나섰습니다. 컨트랙트를 작성하고 디버깅을 시작했는데, 수정할 때마다 새로운 복잡성이 생겨났습니다. 한 번의 업데이트가 여러 파일에 걸친 변경을 요구했습니다. 좌절스럽고 지치기도 했지만, 이상하게도 짜릿했습니다. 이 혼돈을 단순화하고 과정을 좀 더 직관적으로 만들 방법을 고민하기 시작했습니다. 바로 그때 워크플로우를 간소화하기 위한 작은 스크립트를 만들기 시작했습니다.

그달 초에 질문을 하려고 Midnight Discord에 가입한 적이 있었습니다. 어느 주, Discord 커뮤니티 콜에 참여했는데, 놀랍게도 비동기로 진행 중인 Midnight 도구 해커톤이 있다는 것을 알게 되었습니다. 그 순간 깨달았습니다. 이것이야말로 처음부터 참가해야 할 해커톤이었다는 것을.

From Personal Tool to Shared Project

개인 도구로 시작한 것이 갑자기 더 큰 의미를 갖게 되었습니다. 해커톤 덕분에 다른 사람들과 작업을 공유하고, Midnight 위에서의 스마트 컨트랙트 개발의 미래를 함께 만들어갈 기회가 생겼습니다. 원래 해커톤 제출물에서 잠시 우회하여 도구를 다듬기 시작했고, 단순히 작동하는 것을 넘어 생태계 입문자에게 진정으로 유용한 것을 만들겠다는 목표를 세웠습니다.

Scaffold Midnight & Create Midnight App

그렇게 Scaffold Midnight이 탄생했습니다. 클론해서 바로 쓸 수 있는 GitHub 스타터 템플릿입니다. 하지만 여기서 멈추지 않았습니다. npm 라이브러리로 만들면 더 유용하겠다는 생각이 들었습니다. 모든 의존성이 번들로 포함되어 설치만 하면 바로 사용할 수 있도록 말입니다. 그래서 프로젝트를 다듬어 create-midnight-app의 첫 버전을 출시했습니다. 하나의 문제를 해결하는 것에 그치고 싶지 않았습니다. 하나를 고칠 때마다 또 다른 문제가 드러났습니다. 여러 차례의 반복을 거쳐 계속 개선했고, 지금은 버전 2.1.7에 이르렀으며 최신 Compact 릴리스와 호환되도록 작업 중입니다. 완벽과는 거리가 멀지만, 그래서 더 흥미롭습니다. 매일 아침 새로운 아이디어, 추가할 기능, 개발자 경험을 개선할 더 나은 방법을 떠올리며 일어납니다!

Create Midnight App

핵심적으로 create-midnight-app은 Midnight을 위한 스캐폴딩 npm 라이브러리로, 전체 설정 과정을 자동화합니다. 개발자는 Compact 컨트랙트 작성에만 집중하면 되고, 나머지는 도구가 처리합니다. 지갑 생성, 파우셋 요청, 잔액 확인, API 설정, CLI 업데이트, 함수와 파일 변경에 따른 임포트 갱신까지 자동으로 이루어집니다. 초기 애플리케이션 설정 시간을 30분 이상에서 단 몇 분으로 줄여줍니다.

이 프로젝트를 진행하면서 짜릿한 순간이 여러 번 있었는데, 특히 기억에 남는 것이 하나 있습니다.

꼭 만들고 싶었던 기능 중 하나는 개발자가 코드 에디터를 벗어나지 않고도 테스트넷 토큰을 요청할 수 있는 방법이었습니다. 가장 단순한 아이디어는 터미널에서 공식 Midnight 파우셋으로 직접 요청을 보내는 것이었습니다. 그런데 문제가 있었습니다. 해당 사이트는 스팸과 악용을 방지하기 위해 Cloudflare Turnstile로 보호되어 자동화된 요청을 차단하고 있었습니다. 해커로서 우회 방법을 찾기 시작했습니다. 검색과 지인들의 조언을 통해 CAPTCHA 보호를 우회한다고 주장하는 여러 유료 도구를 시도했습니다. 한나절을 투자했지만 제대로 작동하는 것이 없었습니다. 그때 제네시스 지갑이 떠올랐습니다. 프라이빗 키가 공개되어 있었기 때문입니다. 그래서 파우셋을 호출하는 대신, 제네시스 지갑에서 사용자 지갑으로 직접 토큰을 전송하는 방식으로 우회했습니다. 장기적인 해결책은 아니고 확장성도 부족하지만, 지금은 작동하며 개발자 경험 간소화에 기여하고 있습니다.

Submission and Recognition

마침내 프로젝트를 제출했고, 심사위원들의 반응은 매우 고무적이었습니다. 새 영감을 얻어 원래 해커톤인 African Blockchain Championship으로 돌아갔습니다. 이 대회를 위해 익명의 검열 저항 투표 플랫폼을 구축했습니다. 아프리카 34개국에서 시민의 약 30~40%가 투표를 공정하고 신뢰할 수 있는 과정으로 여기지 않습니다(Afrobarometer, 2023). 따라서 익명 투표는 선택이 아니라 필수입니다. 제 프로젝트 Privote은 영지식 기술로 유권자의 신원과 투표 무결성을 보호하여 이 문제를 해결하고자 합니다.

제출 마감이 다가오면서 큰 난관에 부딪혔습니다. 프런트엔드에 지갑을 통합하는 부분이었습니다. Developer Relations 엔지니어에게 연락하니 예제 코드를 공유해 주셨지만, 시간 안에 동작시킬 수 없었습니다. 마감이 코앞이라 임기응변을 택했습니다. 백엔드에서 터미널을 통해 지갑과 상호작용하는 커스텀 Chrome 확장 프로그램을 급히 만들어 제출 시간에 맞췄습니다. 현재 버전은 프라이버시 면에서 한계가 있지만, 스마트 컨트랙트가 정상적으로 컴파일되고 Midnight 테스트넷에서 상호작용할 수 있어, 탈중앙화 익명 투표의 가능성을 보여줍니다.

Private Hackathon

The Midnight Community

아직 리소스가 풍부하진 않지만, Midnight 커뮤니티가 이를 충분히 메워줍니다. Discord에서 질문하면 거의 항상 답변을 받을 수 있습니다. 해커톤 기간 중 기술적으로는 경쟁 관계인데도, 서로 진심으로 돕는 분위기입니다. 실제로 해커톤 중에 텔레그램 그룹에서 질문에 답하는 일이 잦았습니다. ABC 해커톤에서는 Create Midnight App 사용법에 대한 워크숍을 진행하여 다른 참가자들이 빠르게 시작하고 생태계를 쉽게 탐색할 수 있도록 도왔습니다.

Midnight 팀의 인정도 정말 감사했습니다. CLI 트랙 1위 수상 외에도, 커뮤니티에서 받은 지지와 감사가 진심으로 따뜻했습니다. 커뮤니티 콜에도 참여할 기회가 있었는데, 이번에는 단순한 참가자가 아니라 발표자로서 여정과 배운 점을 공유할 수 있었습니다.

Why Now is the Time to Build on Midnight

독자 여러분, 지금이야말로 Midnight 생태계에 참여하기 가장 좋은 시기입니다. 거의 항상 해커톤이 진행 중이고(정말 놀랍죠!), 현재도 미니 DApp 해커톤이 열려 있습니다. 배우고, 만들고, 프로젝트를 알릴 수 있는 좋은 기회입니다.

Midnight Dapp Hackathon

저는 현재 해커톤을 위한 새로운 프로젝트를 구축하고 있습니다. 프로젝트를 만드는 것도 즐기지만, 인프라 도구를 개발하는 데서 더 큰 보람을 느끼고 있습니다. 장기 목표는 아무것도 설치하지 않고도 Compact 코드를 작성하고 Midnight 테스트넷과 상호작용할 수 있는 웹 기반 Midnight 플레이그라운드를 만드는 것입니다. 앞으로도 Midnight 팀과 협업하며, 특히 영지식 프로토콜 분야에서 역량을 키워나가고 싶습니다.

블록체인 데이터를 조회하는 방법

· 3 min read
Claude Barde
Developer Relations

Midnight blockchain은 DApp의 데이터 프라이버시와 컴플라이언스에 새로운 접근 방식을 도입하며, zero-knowledge proof(ZKP)와 듀얼 토큰 시스템을 활용합니다.

이 글에서는 Midnight blockchain에 연결하는 방법을 안내합니다. Polkadot API를 사용하여 Substrate 기반 blockchain(Midnight 포함)에 접속하고, 새 블록을 실시간으로 수신하며, 블록에서 데이터를 추출하는 방법을 다룹니다.