Midnight에서 smart contracts 작성 방법
Source: Dev.to
정신 모델: 기본 프라이버시
코드를 한 줄이라도 쓰기 전에 접근 방식을 바꿔야 합니다.
Midnight에서는:
- 사용자가 제공하는 모든 것은 기본적으로 비공개입니다.
- “우연히” 공개되는 일은 없습니다.
- 프라이버시는 암시적으로가 아니라 명시적으로 제어됩니다.
이는 Midnight의 스마트 계약 언어 Compact와 **Zero‑Knowledge Proofs (zkSNARKs)**를 사용해 데이터를 노출하지 않고 트랜잭션을 검증함으로써 구현됩니다.
Compact란?
Compact는 프라이버시‑우선 애플리케이션을 만들기 위해 특별히 설계된 선언형 언어입니다.
Compact로 계약을 작성하면:
- 비즈니스 로직을 정의합니다.
- 어떤 데이터가 공개될지 정의합니다.
- 어떤 데이터가 비공개로 유지될지 정의합니다.
컴파일러는 다음을 생성합니다:
- DApp을 위한 JavaScript / TypeScript API
- ZK 증명을 생성하는 데 필요한 암호학적 아티팩트
이 모든 과정은 개발자 로컬 환경에서 이루어집니다.
Compact 계약의 기본 구성 요소
Midnight의 모든 계약은 동일한 블록들로 구성됩니다:
Ledger state (공개 상태)
체인에 저장되고 모든 사람이 볼 수 있는 데이터.
export ledger value: Uint;
Witnesses (비공개 입력)
Witness는 사용자나 프론트엔드에서 전달되는 데이터를 나타냅니다. 기본적으로 비공개이며 Compact는 실수로 누출되는 것을 허용하지 않습니다.
witness getSecret(): Bytes;
Circuits (검증 가능한 로직)
Circuit은 계약이 수행할 수 있는 작업을 정의합니다. export 로 표시된 circuit만 외부에서 호출할 수 있습니다.
export circuit get(): Uint {
return value;
}
Constructor
계약을 생성할 때 한 번만 실행됩니다.
constructor(sk: Bytes, v: Uint) {
value = v;
}
선택적 공개: disclose()
Compact의 가장 중요한 규칙 중 하나는 다음과 같습니다:
비공개 데이터를 명시적으로 선언하지 않으면 공개할 수 없습니다.
witness를 직접 ledger에 쓰거나 반환값으로 사용하면 컴파일러가 오류를 발생시킵니다.
올바른 방식:
export ledger publicData: Bytes;
export circuit record(): [] {
publicData = disclose(getSecret());
}
잘못된 방식 (컴파일 오류):
publicData = getSecret(); // ❌
이 규칙은 다른 생태계에서 흔히 발생하는 오류를 완전히 차단합니다.
불투명 타입: Compact가 데이터를 “볼 수 없게” 하는 경우
Compact는 Opaque와 같은 불투명 타입을 지원합니다. 이러한 타입은:
- 저장하거나 전송할 수 있습니다.
- 계약 내부에서 검사할 수 없습니다.
- 프론트엔드(TypeScript)에서는 보이지만 Compact에서는 조작할 수 없습니다.
다음과 같은 경우에 유용합니다:
- 메시지
- 메타데이터
- 임의의 콘텐츠(예: 게시판)
- 커밋 및 해싱
데이터를 노출하지 않는 암호학적 프리미티브
데이터를 노출하지 않고 속성을 증명하기 위해 Compact는 다음을 포함합니다:
persistentCommit(value, random);
transientCommit(value);
이 함수들은 다음에 핵심적으로 사용됩니다:
- 비공개 투표
- 검증 가능한 신원
- 자격 증명을 노출하지 않는 인증
Proof server의 역할
모든 ZK 마법은 블록체인 외부에서 이루어집니다. Proof server는:
- 로컬 또는 관리된 인프라에서 실행됩니다.
- 네트워크에 비공개 데이터를 절대 노출하지 않습니다.
- 유효한 암호학적 증명만 반환합니다.
이를 통해 블록체인은 기본 데이터를 알지 못한 채 사실을 검증할 수 있습니다.
Midnight에서 계약을 설계하는 방법
Midnight에서 코딩할 때 스스로에게 다음 질문을 해보세요:
- 이 데이터가 정말 공개되어야 할까?
- 네트워크가 검증해야 할 것은 무엇이고, 검증하지 않아도 될 것은 무엇인가?
- 값을 노출하지 않고 이 조건을 증명할 수 있는가?
- 누가 proof server를 제어하고 있는가?
Compact는 도구를 제공할 뿐 아니라 데이터 모델을 신중히 설계하도록 강제합니다.
결론
Midnight에서 스마트 계약을 작성한다는 것은 새로운 언어를 배우는 것이 아니라, 탈중앙화 애플리케이션을 설계하는 전혀 다른 방식을 채택하는 것입니다:
- 기본 프라이버시
- 명시적 공개
- 데이터, 로직, 증명의 명확한 분리
- 컴파일러 수준에서 강화된 보안
Solidity나 Plutus와 같은 생태계에서 온 경우 처음엔 다르게 느껴질 수 있습니다. 하지만 모델이 몸에 익으면 다시 돌아가기 어렵습니다. 프라이버시가 “기능”이 아니라 언어 자체의 일부가 됩니다.