Skip to main content

Create your first Midnight contract

이 튜토리얼에서는 첫 번째 Compact smart contract를 작성하고, Preprod 테스트 네트워크에 배포한 뒤, 프라이버시 보존 로직으로 blockchain에 Hello World 메시지를 기록합니다.

완료하면 다음을 수행할 수 있습니다:

  • 상태를 저장하는 Compact smart contract 작성
  • Contract를 zero-knowledge circuit으로 컴파일
  • Preprod 테스트 네트워크에 contract 배포
  • Blockchain에 Hello World 메시지 기록

Prerequisites

시작하기 전에 다음을 확인하세요:

1

Set up project

스타터 레포를 클론하세요:

git clone https://github.com/midnightntwrk/example-hello-world.git

의존성을 설치하세요:

npm install

필요한 디렉토리를 생성하세요:

mkdir contracts

contracts 폴더에 Compact smart contract 소스 파일을 저장합니다.

2

Create the contract file

contracts 디렉토리에 hello-world.compact라는 새 파일을 생성하세요:

touch contracts/hello-world.compact

VS Code에서 이 파일을 여세요:

code .
3

Create the Compact Smart Contract

pragma language_version 0.22;

export ledger message: Opaque<"string">;

export circuit storeMessage(newMessage: Opaque<"string">): [] {
message = disclose(newMessage);
}
  • pragma language_version은 contract가 사용하는 Compact 버전을 지정합니다.
  • ledger message는 온체인 상태에 문자열 값을 저장하는 message라는 state variable을 생성합니다. 온체인 상태는 blockchain에서 공개적이고 영구적입니다.
  • circuit storeMessage는 온체인 상태를 수정하는 로직을 정의하는 Compact circuit입니다.
  • newMessage: Opaque<"string">는 입력 파라미터입니다. Circuit 파라미터는 기본적으로 비공개입니다. disclose() 함수는 비공개 값을 공개 저장해도 안전하다고 표시합니다. 이 함수 없이 newMessage를 ledger에 직접 할당하면 컴파일러 오류가 발생합니다.
4

Compile the contract

컴파일은 Compact 코드를 zero-knowledge circuit으로 변환하고, 암호화 키를 생성하며, DApp에서 사용할 TypeScript API와 JavaScript 구현을 만들어 줍니다.

프로젝트 루트에서 컴파일러를 실행하세요:

npm run compile

다음과 같은 출력이 표시됩니다:

Compiling 1 circuits:
circuit "storeMessage" (k=6, rows=26)

컴파일 과정에서 수행되는 작업:

  1. Compact 코드를 파싱하고 유효성을 검사합니다.
  2. 로직에서 zero-knowledge circuit을 생성합니다.
  3. Circuit용 proving key와 verifying key를 생성합니다.
  4. Contract용 TypeScript API와 JavaScript 구현을 생성합니다.

컴파일이 완료되면 새로운 디렉토리 구조가 나타납니다:

contracts/
├── managed/
| └── hello-world/
| ├── compiler/
| ├── contract/
| ├── keys/
| └── zkir/
└── hello-world.compact

각 디렉토리의 역할:

  • contract/: JavaScript 구현과 타입 정의가 포함된 컴파일된 contract artifact.
  • keys/: Zero-knowledge proof 생성에 필요한 암호화 proving key와 verifying key.
  • zkir/: Zero-Knowledge Intermediate Representation. Compact와 ZK 백엔드 사이의 중간 표현.
  • compiler/: 다른 도구에서 contract 구조를 파악하는 데 활용할 수 있는 컴파일러 생성 JSON 출력.
5

Deploy Contract to Preprod

Contract 컴파일이 완료되었으므로 blockchain에 배포합니다.

Docker 엔진이 실행 중인지 확인하고, 별도의 터미널에서 proof server를 시작하세요:

npm run start-proof-server

다음 단계를 위해 proof server를 실행 상태로 유지하세요.

Contract 배포에는 wallet이 필요합니다. 배포 스크립트가 새 wallet 생성을 안내합니다.

note

다음 단계에서 필요하므로 seed phrase를 반드시 저장하세요.

배포 스크립트를 실행하세요:

npm run deploy
6

Deployment Failed!

Contract 배포가 실패합니다:

(FiberFailure) Wallet.Transacting: Not enough Dust generated to pay the fee

Midnight 네트워크에서 transaction을 실행하려면 DUST가 필요합니다. DUST는 faucet에서 받은 NIGHT로부터 생성되지만, 생성에 시간이 걸립니다. NIGHT가 많을수록 DUST가 더 빠르게 생성됩니다. 잠시 후 다시 시도하세요.

배포 스크립트를 다시 실행하되, 이번에는 옵션 2 'Restore from seed'를 선택하고 이전에 생성한 wallet의 seed를 붙여넣으세요:

npm run deploy

배포가 완료되면 다음과 유사한 출력이 표시됩니다:

✅ Contract deployed successfully!

Contract Address: 0x1234567890abcdef...

Saved to deployment.json
7

Contract interaction

Contract가 성공적으로 배포되었습니다. 이제 상호작용해 봅시다:

npm run cli

프롬프트가 나타나면 wallet seed를 입력하고 Preprod 네트워크에 연결될 때까지 기다리세요.

옵션 [2]를 선택해서 현재 메시지가 "(empty)"인지 확인하세요:

  [1] Store a message
[2] Read current message
[3] Exit

그다음 옵션 1을 선택하고 "Hello World!"를 입력하세요. 메시지가 성공적으로 저장됩니다:

 ✅ Message stored!
Transaction: 0007f15ce66f14b01ff7d5c2b4fbf4a40f65630cd7950785a81832b11103c5a0f1
Block: 402893

옵션 [2]를 다시 선택하면 "Hello World!" 메시지가 표시됩니다:

  Reading message from blockchain...
Current message: "Hello World!"

Hello World! 첫 번째 Midnight DApp을 성공적으로 만들었습니다. 더 다양한 DApp 빌드 방법은 튜토리얼을 참고하세요!

Troubleshoot

컴파일 중 발생할 수 있는 일반적인 문제와 해결 방법입니다.

Compiler not found

compact compile 명령어가 인식되지 않으면 설치 상태를 확인하세요:

  1. Compact 개발 도구가 설치되어 있는지 확인: which compact 또는 compact --version
  2. 1단계가 성공하면 컴파일러 toolchain 설치 여부 확인: compact compile --version
  3. 자세한 내용은 Toolchain 설치 가이드를 참고하세요.

Compilation errors

구문 또는 타입 오류가 발생하면:

  • pragma language_version이 컴파일러 버전과 일치하는지 확인하세요.
  • 필요한 import가 모두 있는지 확인하세요.
  • 필요한 위치에 disclose 연산자를 사용했는지 확인하세요.
  • 오류 메시지의 라인 번호와 구체적인 문제를 확인하세요.

Next steps

Midnight DApp 빌드에 대해 더 알아보려면 튜토리얼을 살펴보세요. 다양한 DApp의 간략한 워크스루는 예제에서 확인할 수 있습니다.