For the complete documentation index, see llms.txt
Compact as a privacy-first language
Midnight의 스마트 컨트랙트 모델은 비공개 연산, 공개 transcript, zero-knowledge proof, verifier key를 중심으로 합니다. 이런 모델을 위한 언어는 프라이버시를 부가 기능으로 다룰 수 없습니다.
Compact은 그러한 설계 결정을 반영합니다. 프라이버시를 고려한 circuit이 개발 모델에서 일급 요소이며, 이 언어는 public state, 오프체인 로직, 비공개 데이터 사이의 경계를 표현합니다. 이 페이지는 Smart contracts on Midnight과 Kachina의 개념을 토대로 합니다. Compact 문법과 코드 예시는 Compact language를 참고하세요.
A privacy-first model needs more than a Solidity extension
많은 공개 스마트 컨트랙트 플랫폼에서는 특별한 기법으로 숨기지 않는 한 데이터, 로직, 입력, 출력이 모두 노출됩니다. 스마트 컨트랙트는 프로그램으로서 온체인에서 실행되고, 네트워크는 공개 연산을 재실행하거나 검사해 실행을 검증합니다. 이 모델은 충분히 자리를 잡았지만, 공개 가시성에서 출발합니다.
Midnight은 다른 전제에서 출발합니다. 프라이버시 보존 스마트 컨트랙트는 공개 컨트랙트에 프라이버시 계층을 덧붙인 것이 아닙니다. 이 모델은 공개될 수 있는 것과 비공개로 남아야 하는 것을 분리하고, 영지식 증명으로 양쪽을 연결합니다. 이 차이는 언어가 표현해야 하는 바를 바꿉니다.
기존 언어에 프라이버시 라이브러리를 덧붙이면 개발자는 공개 스마트 컨트랙트 모델과 그 위에 얹힌 프라이버시 모델, 두 가지 사고 틀을 동시에 다뤄야 합니다. Compact은 다른 접근을 취합니다. 프라이버시를 고려한 모델에 고유한 언어 표면을 부여하여, 개발자가 스마트 컨트랙트 동작을 기술하는 방식 안에서 Midnight의 프라이버시 구조가 드러나게 합니다.
Compact treats circuits as first-class citizens
가장 중요한 설계 전환은 Compact이 circuit을 스마트 컨트랙트 모델의 핵심 부분으로 다룬다는 점입니다.
기존의 공개 스마트 컨트랙트 환경에서 개발자는 스마트 컨트랙트를 온체인에서 실행되는 코드로 이해합니다. 네트워크는 입력을 보고, 로직을 실행하며, 그 결과로 생기는 상태 전이를 검사합니다.
Midnight의 모델은 다릅니다. Midnight 스마트 컨트랙트를 작성하면 상호작용이 세 부분으로 나뉩니다. 사용자 기기에서 실행되는 local 부분, public state를 기록하는 ledger 부분, 그리고 둘을 연결하는 규칙을 인코딩하는 circuit 부분입니다. 블록체인은 상호작용을 검증하기 위해 모든 비공개 입력을 볼 필요가 없습니다. 상호작용이 규칙을 따랐다는 영지식 증명과, ledger state에 적용할 수 있는 공개 transcript만 있으면 됩니다.
Compact은 그러한 규칙을 기술하기 위해 존재합니다. Compact을 단순히 실행 가능한 온체인 코드를 작성하는 언어가 아니라, 무엇을 증명해야 하는지를 정의하는 언어로 생각하세요.
Compact 컴파일러는 ledger와의 상호작용이 정확함을 증명하는 영지식 circuit을 출력합니다. Compact 스마트 컨트랙트는 애플리케이션 로직만 만들어 내지 않습니다. 컨트랙트 상호작용이 요구된 규칙을 따랐음을 거래가 입증하도록 해 주는 증명 시스템에 기여합니다.
circuit은 부수적인 산출물이 아닙니다. 이 언어가 표현하는 핵심 대상 중 하나입니다.
Public, private, and proof environments
프라이버시와 증명이 핵심이 되면, 언어는 서로 다른 종류의 데이터와 실행을 개발자에게 드러내야 합니다.
Compact은 Midnight 스마트 컨트랙트 상호작용에 관여하는 주요 환경을 분리해 이를 수행합니다. 언어에서 이들은 세 가지 구문으로 대응됩니다.
ledger: 온체인 컨트랙트 상태에 속하는 public state.circuit: 증명 생성에 참여하고 validator가 검사하는 규칙을 인코딩하는 로직.witness: 사용자 기기에서 실행되는 오프체인 함수. witness로 private state를 가져올 수 있고, 나눗셈처럼 온체인에서 수행하기 어렵거나 지원되지 않는 연산도 처리할 수 있습니다. 컨트랙트는 circuit 안에서 witness 결과를 검증하므로, 오프체인 연산에 대한 온체인 검증을 얻게 됩니다. 이 패턴의 실제 예시는 calculator 예제를 참고하세요. witness는 circuit 내 연산을 기반으로 private state를 업데이트하는 데에도 핵심적입니다.
이 구문들이 실제로 어떻게 함께 동작하는지 자세히 보려면 Writing a contract를 참고하세요.
이 분리는 신뢰 모델로 거슬러 올라갑니다. 공개 측면은 네트워크에 보여야 합니다. 개발자는 비공개 측면을 불필요하게 드러내서는 안 됩니다. 증명은 숨겨진 입력과 로컬 연산이 공개 결과를 정당화한다는 것을 보여 주어 둘을 연결합니다.
명시적 경계가 없으면 개발자는 값이 어디에 있는지, 누가 볼 수 있는지, 그에 대해 무엇을 증명해야 하는지를 놓치게 됩니다. 이 위험은 프라이버시 보존 애플리케이션에서 특히 높습니다.
비공개로 남아야 할 값이 실수로 공개되어서는 안 됩니다. 네트워크는 상호작용이 비공개 측 규칙을 충족했다는 검증 없이 public state 전이를 받아들여서는 안 됩니다. 스마트 컨트랙트의 형태만 봐도 그러한 경계가 어디에 있는지 알 수 있어야 합니다.
Compact의 언어 모델은 그러한 분리를 개발 표면의 일부로 만듭니다.
Explicit disclosure turns privacy into a deliberate choice
프라이버시 보존 시스템에도 disclosure는 필요합니다.
결제 시스템은 거래가 유효함을 밝혀야 할 수 있습니다. 컴플라이언스 워크플로는 인가된 당사자에게 특정 사실을 보여 줘야 할 수 있습니다. 게임은 일부 플레이어 입력을 비공개로 유지하면서 공개 점수를 업데이트해야 할 수 있습니다.
문제는 무언가가 공개되어야 하는지 여부가 아니라, 누가 무엇을 언제 보는가입니다.
Compact은 disclose() 키워드를 통해 명시적 disclosure를 강제합니다. disclose() 호출 자체가 데이터를 공개하지는 않습니다. 이는 witness에서 파생된 값을 공개 영역으로 들여보내려는 의도를 컴파일러에 알립니다. 값은 가시성 경계를 넘을 때만 공개됩니다. ledger 쓰기, exported circuit에서의 반환, 컨트랙트 간 호출이 그러한 경계입니다. 컴파일러는 witness에서 파생된 값이 disclose() 래퍼 없이 그러한 경계를 넘는 프로그램을 모두 거부합니다. 프라이버시가 기본값이며, disclosure에는 의도적인 표기가 필요합니다.
이 설계는 Midnight의 더 넓은 selective disclosure 방향과 직접 맞아떨어집니다. selective disclosure는 완전한 비밀로서의 프라이버시가 아닙니다. 통제된 가시성으로서의 프라이버시입니다. 시스템은 무관한 데이터는 비공개로 유지하면서 특정 상호작용에 필요한 정보만 밝힐 수 있습니다. 해시, commitment, Merkle tree 같은 실용적인 shielding 패턴은 Keeping data private를 참고하세요.
Why a domain-specific language makes sense here
Compact은 도메인 특화 언어입니다. 이 선택이 중요한 이유는, Midnight이 프로토콜이 요구하는 증명 중심 워크플로로 컴파일되는 프라이버시 고려 스마트 컨트랙트 규칙을 개발자가 표현하도록 해야 하기 때문입니다.
범용 언어는 유연할 수 있지만, 유연함이 늘 명료함과 같지는 않습니다. 프라이버시 경계, 증명 로직, ledger state가 모델의 핵심 부분일 때, 언어는 그러한 개념을 드러내야 합니다. 개발자가 평범한 공개 실행 로직 안에 묻힌 라이브러리 호출에서 그것들을 추론해야 해서는 안 됩니다.
도메인 특화 언어는 중요한 개념을 적절한 추상화 수준에서 드러낼 수 있습니다. 개발자는 여전히 Midnight이 스마트 컨트랙트 상호작용을 어떻게 구성하는지 익혀야 하지만, Compact은 관련 개념을 언어 자체의 일부로 만들어 그 학습을 안내합니다.
Compact은 TypeScript와 비슷한 표면을 가지므로, 암호학 전문가가 아닌 개발자의 학습 곡선을 낮추는 한편, 범용 언어라면 가려졌을 프라이버시 고유의 구조를 드러냅니다.
Compact is a design boundary, not a syntax choice
Compact은 경계를 긋습니다. EVM 스타일 스마트 컨트랙트가 "이것이 온체인에서 무엇을 실행하는가?"에서 출발한다면, Midnight 스마트 컨트랙트는 "무엇이 공개되어야 하고, 무엇이 비공개로 남을 수 있으며, 어떤 증명이 그 전이가 유효함을 보여 주는가?"에서 출발합니다. Compact은 그 두 번째 관점을 중심으로 구축된 언어 계층입니다.
Start learning Compact
개념에서 코드로 넘어갈 준비가 되었다면, 권장 경로는 다음과 같습니다.
- Write your first contract: 완전한 Compact 스마트 컨트랙트를 만들고
ledger,circuit,witness가 어떻게 함께 동작하는지 살펴봅니다. - Understand explicit disclosure:
disclose()키워드가 컴파일러 수준에서 의도적인 데이터 가시성을 어떻게 강제하는지 익힙니다. - Keep data private: 해시, commitment, Merkle tree, commitment/nullifier 패턴을 포함한 실용적인 shielding 패턴을 살펴봅니다.
- Build a bulletin board DApp: Compact 컨트랙트와 동작하는 DApp을 결합한 튜토리얼에서 배운 내용을 적용해 봅니다.
환경을 먼저 구성하고 싶다면 Install the Toolchain과 Create your first contract부터 시작하세요.
Additional resources
- Compact language: Compact과 영지식 circuit 생성에서의 역할에 대한 개요.
- Smart contracts on Midnight: Compact이 컴파일되어 들어가는 transcript, 증명, verifier key 모델.
- Zero-knowledge proofs: ZK-SNARK의 동작 방식과 Midnight의 활용 방식.
- Kachina: public state와 private state 분리의 바탕이 되는 정형 모델.
- Example contracts: 선거, 경매, 토큰 전송 등 다양한 Compact 컨트랙트 둘러보기.