Transaction semantics
Ledger states
Midnight의 원장은 두 가지 항목으로 구성됩니다:
- Zswap 상태
- coin commitment의 Merkle tree
- coin commitment tree에서 첫 번째 빈 슬롯의 인덱스
- nullifier 집합
- 유효한 과거 Merkle tree root 집합
- 컨트랙트 주소에서 컨트랙트 상태로의 맵.
Contract state
컨트랙트 상태는 다음으로 구성됩니다:
- Impact 상태 값
- entry point 이름에서 operation으로의 맵. 여기서 entry point는 컨트랙트에서 내보낸 circuit에 해당합니다.
컨트랙트 operation은 해당 컨트랙트와 entry point에 대한 호출을 검증하는 데 사용되는 SNARK verifier key로 구성됩니다.
Transaction fallibility
트랜잭션은 세 단계로 실행됩니다:
- well-formedness 검사
- guaranteed phase
- fallible phase.
Well-formedness 검사는 상태 없이 실행되며, 트랜잭션의 전반적인 무결성과 일관성을 확인합니다. 반면 guaranteed phase와 fallible phase는 모두 원장 상태를 기반으로 실행되어, 새로운 상태를 생성하거나 실패합니다. Guaranteed phase에서 트랜잭션이 실패하면 해당 트랜잭션은 원장에 포함되지 않습니다. Fallible phase에서 실패하면 guaranteed phase의 효과는 그대로 적용되며, 원장은 해당 트랜잭션을 부분 성공으로 기록합니다.
모든 실행 단계의 수수료는 guaranteed phase에서 징수되며, fallible phase에서 트랜잭션이 실패하면 수수료는 몰수됩니다.
Well-formedness
Well-formedness 검사는 트랜잭션이 정규 형식을 따르는지 확인하며, 구체적으로 다음을 검증합니다:
- Zswap offer 내 모든 영지식 증명의 검증 가능 여부
- 컨트랙트 섹션 내 Schnorr proof의 검증 가능 여부
- guaranteed offer가 아래 조정 사항을 반영했을 때 균형을 이루는지:
- 전체 트랜잭션 수수료 차감
- guaranteed transcript에서 수행된 모든 발행의 추가
- fallible offer가 아래 조정 사항을 반영했을 때 균형을 이루는지:
- fallible transcript에서 수행된 모든 발행의 추가
- 각 컨트랙트 소유 input 또는 output이, 해당 offer의 fallibility와 일치하는 transcript effects 섹션에서 동일한 컨트랙트에 의해 정확히 한 번 claim되는지
- transcript effects 섹션에서 컨트랙트가 생성했다고 claim한 output이 최대 한 번만 claim되며, transcript의 fallibility와 일치하는 offer에 존재하는지
- transcript에서 claim된 모든 컨트랙트 호출이 실제로 존재하고 최대 한 번만 claim되는지
- 컨트랙트 호출이 guaranteed 섹션과 fallible 섹션을 모두 포함하는 경우, fallible 섹션이
ckptoperation으로 시작하는지.
Phase execution
Transaction fallibility 섹션의 참고 사항 외에, guaranteed phase와 fallible phase는 유사하게 동작하지만, guaranteed phase에서는 다음과 같은 추가 작업이 수행됩니다:
- 모든 호출에 대한 컨트랙트 operation이 조회되고, 영지식 증명이 이에 대해 검증됩니다
- fallible Zswap 섹션도 guaranteed 섹션 실행 중에 적용되어, 자체적으로 fallible 섹션을 무효화하는 것을 방지합니다. [^1]
이후 다음 순서로 진행됩니다:
- 해당 단계의 Zswap offer가 적용됩니다. 새로운 commitment를 Merkle tree에 삽입하고, nullifier를 nullifier 집합에 삽입하며(이미 존재하면 중단), 사용된 Merkle root가 유효한 과거 root인지 확인하고(아니면 중단), 과거 root 집합을 갱신합니다.
- Guaranteed phase인 경우 위의 추가 검사가 수행됩니다.
- 각 컨트랙트 호출에 대해 순서대로, 해당 실행 단계에 관련된 transcript가 적용됩니다.
- 컨트랙트의 현재 상태를 로드합니다.
- 트랜잭션으로부터 context를 설정합니다.
- Impact 프로그램이 context, 빈 effects 집합, transcript 프로그램, 선언된 gas limit을 사용하여 verification 모드로 실행됩니다.
- 실행 결과의 effects가 선언된 effects와 동일한지 검사합니다.
- 결과 상태가 "strong"인 경우에만 컨트랙트 상태로 저장됩니다.
[^1] 이 조치가 없으면, 유효하지 않은 지출과 병합하여 모든 fallible 섹션을 무효화하는 것이 가능해집니다.