Zenith EVM: Testnet 문서

빠른 시작

아래 섹션에서는 표준 Ethereum 도구를 사용하여 간단한 Solidity 컨트랙트를 Zenith EVM Testnet에 배포하는 단계를 살펴봅니다.

Zenith EVM은 Reth 기반 환경으로, 표준 Ethereum JSON-RPC 엔드포인트를 제공합니다. 대부분의 EVM 워크플로는 네트워크 설정만 변경하면 됩니다.

지갑에 testnet 추가하기

MetaMask 또는 다른 EVM 지갑에서 Zenith EVM Testnet을 사용자 지정 네트워크로 추가합니다.

FieldValue
Network nameZenith EVM Testnet
RPC URLhttps://rpc.testnet.zenith.network/
RPC nameZenith EVM Testnet RPC
Chain ID936485
Token symbolZTH
Block explorer URLhttps://explorer.testnet.zenith.network/

지갑에 자금 넣기

testnet 토큰 받기

Zenith EVM testnet 파우셋을 사용하세요:

ZTH는 Zenith EVM testnet의 네이티브 가스 토큰입니다. 18자리 소수점(decimals)을 사용하며, 컨트랙트를 배포하고 트랜잭션을 전송하는 데 필요합니다.

기본 EVM 빠른 시작에는 ZTH만 있으면 됩니다. Testnet wCTN(Wrapped Canton)은 로컬 Canton 테스트 네트워크와 직접 상호 작용하는 Canton 네이티브 워크플로에만 관련이 있습니다.

간단한 컨트랙트 만들기

아래는 Zenith EVM에 대한 컨트랙트 배포를 테스트하는 데 사용할 수 있는 간단한 컨트랙트 예제입니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Counter {
uint256 public number;
event NumberChanged(uint256 newNumber);
function setNumber(uint256 newNumber) external {
number = newNumber;
emit NumberChanged(newNumber);
}
function increment() external {
number += 1;
emit NumberChanged(number);
}
}

환경 구성하기

테스트를 위해 RPC URL, 체인 ID, 배포자 개인 키를 환경 변수로 설정할 수 있습니다.

export ZENITH_RPC_URL="<zenith-evm-rpc-url>"
export ZENITH_CHAIN_ID="<zenith-evm-chain-id>"
export PRIVATE_KEY="<your-private-key>"

중요 사항: 개인 키를 환경 변수로 저장하는 것은 개발 및 테스트에서 일반적이지만, 프로덕션에서는 다음을 준수해야 합니다:

  • .env 파일을 절대 버전 관리에 커밋하지 마세요
  • .env를 .gitignore에 추가하세요
  • 프로덕션 배포에는 시크릿 관리자(예: AWS Secrets Manager, HashiCorp Vault) 사용을 고려하세요
  • 필요한 자금만 보유한 전용 배포자 지갑을 사용하세요

Foundry로 배포하기

Foundry를 사용하여 컨트랙트를 배포하려면 아래 지침을 따르세요:

forge init zenith-counter
cd zenith-counter
# Replace the default Counter with the contract above.
forge build
forge create \
--rpc-url "$ZENITH_RPC_URL" \
--private-key "$PRIVATE_KEY" \
src/Counter.sol:Counter

배포 명령은 배포된 컨트랙트 주소와 트랜잭션 해시를 반환합니다.

컨트랙트와 상호 작용하기

컨트랙트가 배포되면 Foundry의 cast 도구를 사용하여 명령줄에서 직접 상태를 읽고 트랜잭션을 전송할 수 있습니다.

export COUNTER_ADDRESS="<deployed-contract-address>"
cast call \
--rpc-url "$ZENITH_RPC_URL" \
"$COUNTER_ADDRESS" \
"number()(uint256)"
cast send \
--rpc-url "$ZENITH_RPC_URL" \
--private-key "$PRIVATE_KEY" \
"$COUNTER_ADDRESS" \
"increment()"

트랜잭션 확인하기

익스플로러는 Canton 레이어와 EVM 레이어를 모두 실시간으로 모니터링하며, 현재 Canton 업데이트와 EVM 블록을 동기화 상태로 추적하고 있습니다.

Zenith Explorer 열기:

상단의 검색창을 사용하여 EVM 트랜잭션 해시를 검색하세요. 익스플로러는 다음 보기를 제공합니다:

  • Blocks: EVM 블록 기록 탐색
  • Transactions: 인덱싱된 EVM 트랜잭션의 전체 목록
  • Linked Transactions: 해당 Canton 업데이트와 연결된 EVM 트랜잭션 표시
  • Contracts: 배포된 컨트랙트 세부 정보 확인

트랜잭션 페이지에는 표준 EVM 트랜잭션 세부 정보, 로그, 컨트랙트 상호 작용이 표시됩니다.

Linked transactions 보기는 Zenith 고유의 기능으로, 각 EVM 트랜잭션에 해당하는 Canton 업데이트 ID를 표시하여 EVM에서 Canton까지 트랜잭션의 전체 수명 주기를 추적할 수 있게 해줍니다.

평균 지연 시간에 대한 참고: 대시보드에서 3-4초의 평균 지연 시간은 Canton 테스트 네트워크에서 제출부터 최종성(finality)까지의 종단 간 트랜잭션 처리 시간을 의미합니다.

내부적으로는 RPC를 통해 제출된 EVM 트랜잭션이 Zenith EVM Sequencer에 의해 수집되어 Canton이 중재하는 블록 제안에 포함됩니다. 이는 표준 EVM 개발자 워크플로를 변경하지 않습니다.

추가 EVM 개발자 리소스

EVM 기본 개념, Solidity 개발 패턴, 그리고 Zenith EVM과 완전히 호환되는 표준 도구에 대해 더 깊이 알아보려면 Ethereum 개발자 문서를 참고하세요:

개발자 가이드

MetaMask 구성하기

  1. MetaMask를 엽니다
  2. 네트워크 드롭다운을 선택합니다
  3. 사용자 지정 네트워크 추가를 선택합니다
  4. 아래와 같이 Zenith EVM Testnet 세부 정보를 입력합니다
FieldValue
Network nameZenith EVM Testnet
RPC URLhttps://rpc.testnet.zenith.network/
RPC nameZenith EVM Testnet RPC
Chain ID936485
Token symbolZTH
Block explorer URLhttps://explorer.testnet.zenith.network/

또는 한 번의 클릭으로 네트워크를 추가할 수 있습니다:

네트워크를 추가한 후 https://explorer.testnet.zenith.network/faucet에서 testnet ZTH를 요청하세요.

가스 및 수수료

현재 Zenith EVM testnet은 실행 레이어에서 표준 EVM 가스 시맨틱스를 사용합니다. 가스 추정치와 트랜잭션 영수증은 eth_estimateGaseth_getTransactionReceipt과 같은 표준 Ethereum JSON-RPC 메서드를 통해 확인할 수 있습니다.

가스는 Zenith EVM Testnet의 네이티브 통화인 ZTH로 지불합니다.

Foundry 구성하기

Foundry는 별도 설정 없이 Zenith EVM에서 바로 작동하며, 필요한 유일한 설정은 testnet RPC 엔드포인트를 추가하는 것입니다. 아래 예제는 간단한 Counter 컨트랙트를 사용하여 빌드 → 배포 → 트랜잭션 → 읽기의 전체 워크플로를 보여줍니다.

foundry.toml에 Zenith EVM RPC 별칭을 추가합니다.

[rpc_endpoints]
zenith_testnet = "${ZENITH_RPC_URL}"

변경될 수 있는 값에는 환경 변수를 사용하세요.

export ZENITH_RPC_URL="<zenith-evm-rpc-url>"
export PRIVATE_KEY="<your-private-key>"

빌드 및 배포:

forge build
forge create \
--rpc-url zenith_testnet \
--private-key "$PRIVATE_KEY" \
src/Counter.sol:Counter

트랜잭션 전송:

cast send \
--rpc-url zenith_testnet \
--private-key "$PRIVATE_KEY" \
"$COUNTER_ADDRESS" \
"increment()"

상태 읽기:

cast call \
--rpc-url zenith_testnet \
"$COUNTER_ADDRESS" \
"number()(uint256)"

Hardhat 구성하기

Hardhat 프로젝트는 testnet RPC를 가리키는 네트워크 항목을 추가하여 Zenith EVM에 연결합니다. 아래 설정은 TypeScript와 공식 Hardhat Toolbox 플러그인을 사용하지만, JavaScript 설정도 동일하게 작동합니다.

필요한 경우 Hardhat을 설치합니다:

npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox

Hardhat 설정 파일을 생성하거나 업데이트합니다:

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
zenithTestnet: {
url: process.env.ZENITH_RPC_URL || "",
chainId: Number(process.env.ZENITH_CHAIN_ID || "0"),
accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
},
},
};
export default config;

환경을 설정합니다:

export ZENITH_RPC_URL="<zenith-evm-rpc-url>"
export ZENITH_CHAIN_ID="<zenith-evm-chain-id>"
export PRIVATE_KEY="<your-private-key>"

배포:

npx hardhat compile
npx hardhat run scripts/deploy.ts --network zenithTestnet

배포 스크립트 예제:

import { ethers } from "hardhat";
async function main() {
const Counter = await ethers.getContractFactory("Counter");
const counter = await Counter.deploy();
await counter.waitForDeployment();
console.log("Counter deployed to:", await counter.getAddress());
console.log("Deployment tx:", counter.deploymentTransaction()?.hash);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

Remix 구성하기

Remix는 로컬 설치가 필요 없으며, MetaMask를 Zenith EVM testnet에 연결하고 브라우저에서 직접 배포하기만 하면 됩니다.

MetaMask를 통해 Remix를 사용합니다.

  1. Zenith EVM Testnet을 MetaMask에 추가합니다.
  2. 계정에 testnet ZTH를 충전합니다.
  3. Remix를 엽니다.
  4. Solidity 컨트랙트를 컴파일합니다.
  5. Deploy & Run Transactions에서 Injected Provider - MetaMask를 선택합니다.
  6. MetaMask가 Zenith EVM Testnet에 연결되어 있는지 확인합니다.
  7. 다른 EVM 체인에서와 같은 방식으로 배포합니다.

Remix는 MetaMask를 통해 트랜잭션을 Zenith EVM RPC 엔드포인트로 전송합니다.

참고: 개발자는 Remix의 "External HTTP Provider" 옵션을 사용하여 RPC URL을 직접 입력할 수도 있습니다.

스마트 컨트랙트 배포하기

Zenith EVM에 배포하는 것은 Ethereum이나 다른 EVM 호환 체인에 배포하는 것과 동일합니다. 아래 표는 동일하게 유지되는 사항과 유의해야 할 몇 가지 사항을 요약한 것입니다.

주제안내
컴파일러평소 사용하는 Solidity 컴파일러 설정을 사용하세요.
배포표준 EVM 배포 트랜잭션을 사용하세요.
가스 토큰가스를 ZTH로 지불합니다.
논스(Nonce)일반적인 Ethereum 계정 논스 동작을 사용하세요.
영수증표준 트랜잭션 영수증을 사용하세요.
이벤트표준 EVM 로그와 ABI 디코딩을 사용하세요.
검증컨트랙트 검증은 Zenith EVM의 testnet 익스플로러에서 지원됩니다.
무작위성Ethereum 비콘 체인(Beacon Chain) 방식의 검증자 선택 무작위성을 위해 block.prevrandao에 의존하지 마세요. 컨트랙트에 무작위성이 필요한 경우, Zenith EVM에 적합한 애플리케이션 수준의 무작위성 소스 또는 오라클 패턴을 사용하세요.

컨트랙트와 상호 작용하기

컨트랙트가 배포되면 표준 Ethereum 라이브러리를 사용하여 상태를 읽고 트랜잭션을 전송할 수 있습니다. 아래 예제는 배포 단계에서 사용한 것과 동일한 Counter 컨트랙트를 사용하며, Ethereum에서와 동일하게 작동합니다. 프로바이더를 Zenith EVM RPC 엔드포인트로 지정하기만 하면 됩니다.

Ethers.js 예제

import { Contract, JsonRpcProvider, Wallet } from "ethers";
import counterAbi from "./Counter.abi.json" assert { type: "json" };
const provider = new JsonRpcProvider(process.env.ZENITH_RPC_URL);
const wallet = new Wallet(process.env.PRIVATE_KEY!, provider);
const counter = new Contract(
process.env.COUNTER_ADDRESS!,
counterAbi,
wallet
);
const before = await counter.number();
console.log("Before:", before.toString());
const tx = await counter.increment();
console.log("Tx hash:", tx.hash);
const receipt = await tx.wait();
console.log("Included in block:", receipt?.blockNumber);
const after = await counter.number();
console.log("After:", after.toString());

Web3.js 예제

import Web3 from "web3";
import counterAbi from "./Counter.abi.json" assert { type: "json" };
const web3 = new Web3(process.env.ZENITH_RPC_URL!);
const account = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY!);
web3.eth.accounts.wallet.add(account);
const counter = new web3.eth.Contract(
counterAbi as any,
process.env.COUNTER_ADDRESS
);
const before = await counter.methods.number().call();
console.log("Before:", before);
const receipt = await counter.methods.increment().send({
from: account.address,
});
console.log("Tx hash:", receipt.transactionHash);

Zenith EVM RPC가 트랜잭션 영수증을 반환하면 해당 트랜잭션은 Canton을 통해 최종 확정된 것입니다. 애플리케이션은 확률적 최종성을 가진 체인에서처럼 여러 블록 확인을 기다릴 필요가 없습니다.

Canton 워크플로에 대해 더 알아보기

Canton 네이티브 워크플로를 더 자세히 살펴보려면 아래 리소스가 좋은 출발점이 될 수 있습니다:

리소스링크용도
Canton Network 문서https://docs.canton.network/Canton, Daml, SDK 및 애플리케이션 개발을 위한 단일 진입점입니다.
Global Synchronizer 문서https://docs.canton.network/global-synchronizer/understand/overview검증자 및 노드 운영, 그리고 LocalNet / DevNet / TestNet / MainNet 환경 모델입니다.
Canton API 레퍼런스https://docs.canton.network/api-referenceLedger API(gRPC 및 JSON), 토큰 표준과 Canton Coin OpenAPI 엔드포인트, Wallet SDK 및 dApp SDK 클라이언트 라이브러리입니다.
Canton에서의 앱 개발https://docs.canton.network/appdev/get-started/choose-your-path역할 기반 학습 경로, Daml SDK 및 도구 설정, 그리고 단계별 모듈 트랙입니다.

네트워크 정보

Testnet 세부 정보

Zenith EVM Testnet은 프로덕션으로 이동하기 전에 컨트랙트를 배포하고, 트랜잭션을 시작하고, 네트워크를 탐색할 수 있는 공개 테스트 환경입니다. 아래 세부 정보를 사용하여 지갑이나 도구를 구성하고 파우셋에서 testnet 토큰을 받아 시작하세요.

FieldValue
Network nameZenith EVM Testnet
Chain ID936485
Zenit EVM Testnet RPChttps://rpc.testnet.zenith.network/
Explorerhttps://explorer.testnet.zenith.network/
Faucethttps://explorer.testnet.zenith.network/faucet
Native currency nameZenith token
Currency symbolZTH
Decimals18

JSON-RPC

Zenith EVM은 표준 Ethereum JSON-RPC 엔드포인트를 제공하며, Ethereum JSON-RPC API를 구현하는 Reth에 포함된 표준 JSON-RPC 메서드를 지원합니다. 일반적으로 사용되는 메서드는 다음과 같습니다:

카테고리메서드
체인 상태eth_chainId, net_version, web3_clientVersion, eth_blockNumber
계정 및 잔액eth_getBalance, eth_getTransactionCount, eth_getCode, eth_getStorageAt
호출 및 가스eth_call, eth_estimateGas, eth_gasPrice, eth_feeHistory
트랜잭션eth_sendRawTransaction, eth_getTransactionByHash, eth_getTransactionReceipt
블록eth_getBlockByHash, eth_getBlockByNumber, eth_getBlockTransactionCountByHash, eth_getBlockTransactionCountByNumber
로그eth_getLogs, eth_newFilter, eth_getFilterChanges, eth_uninstallFilter

지원되는 메서드의 전체 목록은 Ethereum JSON-RPC API 문서를 참고하세요.

공개 Ethereum JSON-RPC 인터페이스를 통해 제출된 트랜잭션은 개발자 관점에서 표준 EVM 제출 모델을 따릅니다. 내부적으로 Zenith EVM은 이를 Sequencer와 Canton이 중재하는 블록 제안 흐름을 통해 라우팅합니다.

기본 JSON-RPC 요청

RPC 요청을 보낼 때는 Ethereum 노드에 사용하는 것과 동일한 요청 형식을 사용할 수 있습니다.

curl "$ZENITH_RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_chainId",
"params": [],
"id": 1
}'
curl "$ZENITH_RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
"id": 1
}'

사용자 지정 RPC 메서드

Zenith EVM은 공개 testnet RPC 엔드포인트에서 사용자 지정 RPC 메서드를 제공하지 않습니다.

일부 Zenith 검증자 인프라는 Canton이 중재하는 블록 생성 과정에서 blockBuilder_buildBlock과 같은 내부 블록 빌더 RPC 메서드를 사용합니다. 이러한 메서드는 공개 개발자 RPC 표면에 포함되지 않으며 표준 EVM 애플리케이션 개발에 필요하지 않습니다.

익스플로러

익스플로러는 Canton 레이어와 EVM 레이어를 모두 실시간으로 모니터링하며, 현재 Canton 업데이트와 EVM 블록을 동기화 상태로 추적하고 있습니다.

Zenith Explorer 열기:

상단의 검색창을 사용하여 EVM 트랜잭션 해시를 검색하세요. 익스플로러는 다음 보기를 제공합니다:

  • Blocks: EVM 블록 기록 탐색
  • Transactions: 인덱싱된 EVM 트랜잭션의 전체 목록
  • Linked Transactions: 해당 Canton 업데이트와 연결된 EVM 트랜잭션 표시
  • Contracts: 배포된 컨트랙트 세부 정보 확인

트랜잭션 페이지에는 표준 EVM 트랜잭션 세부 정보, 로그, 컨트랙트 상호 작용이 표시됩니다.

평균 지연 시간에 대한 참고: 대시보드에서 3-4초의 평균 지연 시간은 Canton 테스트 네트워크에서 제출부터 최종성(finality)까지의 종단 간 트랜잭션 처리 시간을 의미합니다.

Linked Transactions 보기는 Zenith 고유의 기능으로, 각 EVM 트랜잭션에 해당하는 Canton 업데이트 ID를 표시하여 EVM에서 Canton까지 트랜잭션의 전체 수명 주기를 추적할 수 있게 해줍니다.

개념 및 아키텍처

이 섹션에서는 Zenith EVM에 대한 기술 개요, 작동 방식, Canton과의 관계, 그리고 Canton이 중재하는 블록 생성을 통해 EVM 실행이 조율되는 방식을 설명합니다.

Zenith EVM이란?

Zenith EVM은 고성능 모듈형 Ethereum 실행 클라이언트인 Reth를 기반으로 구축된 레퍼런스 EVM 실행 환경입니다. 표준 Ethereum JSON-RPC 인터페이스를 제공하므로, 개발자는 Ethereum 호환 체인에서와 완전히 동일한 방식으로 Zenith EVM과 상호 작용할 수 있습니다.

개발자 관점에서:

  • Solidity, Foundry, Hardhat 또는 모든 EVM 툴체인을 사용하여 수정 없이 스마트 컨트랙트를 배포할 수 있습니다.
  • Zenith EVM을 사용자 지정 네트워크로 추가하여 MetaMask와 같은 지갑을 연결할 수 있습니다.
  • ethers.js, viem, web3.js, OpenZeppelin과 같은 기존 라이브러리를 사용할 수 있으며, 모두 별도 설정 없이 바로 작동합니다.

Zenith EVM이 독립형 EVM 체인과 다른 점은 Canton과의 관계입니다. 모든 EVM 활동은 Canton을 통해 라우팅되고 Canton MainNet에서 정산됩니다. 이를 통해 Zenith EVM은 완전한 Ethereum 개발자 경험을 유지하면서 Canton의 규제 및 컴플라이언스 보장을 갖추게 됩니다.

Zenith EVM은 등록된 Canton 슈퍼 검증자(Super Validator)인 Zenith가 유지 관리합니다. 자체적으로 커스터마이징 가능한 EVM 환경을 구축하려는 기업과 개발자는 Zenith Stack을 통해 이를 수행할 수 있습니다.

Zenith EVM과 Canton의 관계

Zenith EVM은 Canton 상의 EVM 기반 서브넷으로 이해하는 것이 가장 정확합니다. 자체 Ethereum 방식 합의 레이어를 가진 별도의 체인이 아닙니다. 대신 Zenith EVM의 블록 생성, 정식(canonical) 체인 상태, 최종성은 Canton을 통해 중재됩니다.

높은 수준에서 보면:

  • EVM 사용자는 JSON-RPC를 통해 표준 EVM 트랜잭션을 제출합니다.
  • 트랜잭션은 수집되어 Canton 측 블록 제안으로 배치 처리됩니다.
  • 검증자는 동일한 순서의 입력으로부터 제안된 EVM 블록을 재구성합니다.
  • Canton 최종성이 어떤 제안 EVM 블록이 정식 블록이 될지를 결정합니다.
  • 최종 확정된 블록은 다시 EVM 실행 측으로 전파됩니다.

이 아키텍처를 통해 Zenith EVM은 일반적인 Ethereum 도구와 실행 시맨틱스를 유지하면서, 결정론적 최종성과 Canton 네이티브 원자적 조합성(atomic composability)은 Canton에 의존할 수 있습니다.

Canton 상의 온레저(on-ledger) 표현

Zenith EVM은 단일 모놀리식 상태 컨트랙트가 아닌 일련의 Daml 컨트랙트로 Canton 상에 표현됩니다. 이 컨트랙트들은 함께 정식 EVM 체인 상태를 기록하고 새로운 블록이 생성되고 최종 확정되는 방식을 관리합니다.

Canton 측에서 이 온레저 상태를 구성하는 데 사용되는 식별자는 지갑과 EVM 트랜잭션에서 사용되는 Ethereum EIP-155 체인 ID와 구별됩니다.

블록 생성과 정식 체인 상태가 별도의 Ethereum 합의 레이어가 아닌 Canton 컨트랙트와 검증자 확인을 통해 관리되기 때문에, Zenith EVM은 Canton의 최종성과 신뢰 모델을 그대로 물려받습니다. 구체적인 온레저 컨트랙트 설계는 Zenith EVM 구현 내부에 속합니다.

external_call() 프리미티브

Zenith EVM은 external_call()을 사용하여 Canton 측 Daml 워크플로를 결정론적 EVM 실행과 연결합니다.

external_call() 프리미티브는 Canton의 네이티브 2단계 검증 프로세스를 따릅니다:

  1. 제출 단계: 제출하는 참여자가 해석(interpretation) 과정에서 external_call()을 실행하고 결과, 해시, 메타데이터를 트랜잭션 뷰에 포함합니다.
  2. 검증 단계: 검증자들이 각자의 EVM 노드에 대해 로컬에서 동일한 작업을 독립적으로 재실행합니다.
  3. 합의 및 최종성: 임계값 이상의 검증자가 출력에 동의하면 트랜잭션이 확정됩니다. BFT 방식의 정족수 모델에 따라 검증자의 최소 3분의 2가 동의해야 하며, 그렇지 않으면 트랜잭션이 거부됩니다. 필요한 검증자 확인 임계값에 도달하면 Canton 중재자(mediator)가 트랜잭션을 최종 확정합니다.

이 설계는 Canton의 기존 모델을 넘어서는 추가적인 신뢰 가정을 도입하지 않습니다.

Canton과 Zenith EVM에 걸친 트랜잭션에 대한 실질적인 보장은 다음과 같습니다:

  • Canton 측(leg)과 EVM 측이 모두 성공하면 결합된 트랜잭션이 커밋됩니다.
  • 어느 한쪽이라도 실패하면 전체 트랜잭션이 실패합니다.
  • 실패한 워크플로는 부분적으로 커밋된 EVM 또는 Canton 측 상태 전이를 남기지 않습니다.

검증자 노드

Zenith EVM 검증자는 EVM 체인의 블록 생성을 검증하고 확인할 권한을 부여받은 Canton 참여자입니다. 검증자는 이 프로세스에 참여하는 데 필요한 Canton과 EVM 노드 소프트웨어를 모두 실행하지만, 정식 체인은 어느 단일 노드에 의해 결정되지 않습니다.

Zenith EVM 체인의 신뢰할 수 있는 원천(source of truth)은 개별 노드의 로컬 뷰가 아니라 Canton에서 최종 확정된 블록 시퀀스입니다. 노드는 후보 블록을 만들 수 있지만 정식 상태는 Canton 최종성 이후에만 업데이트됩니다.

블록 빌딩

Zenith EVM의 블록 빌딩은 Ethereum mainnet과 다릅니다. Zenith EVM은 Ethereum의 멤풀 기반 제안자-빌더 흐름이나 Ethereum 비콘 체인 검증자 선택을 사용하지 않습니다. 대신 블록은 Canton이 중재하는 제안 흐름을 통해 만들어집니다.

높은 수준에서 보면, 다음 블록에 포함될 트랜잭션은 Canton 측에서 수집되고 정렬됩니다. 다음 블록이 준비되면 권한을 부여받은 검증자가 빌드를 주도합니다:

  • 정렬된 트랜잭션 집합으로부터 후보 블록이 조립되고 실행되며,
  • 다른 검증자들은 동일한 입력으로부터 동일한 블록을 독립적으로 재구성합니다.

그다음 Canton 최종성이 제안된 블록의 정식 블록 여부를 결정하며, 이후 해당 블록은 EVM 실행 레이어로 전파되고 상태가 업데이트됩니다.

검증에 실패한 트랜잭션은 거부되어 결과 블록에서 제외될 수 있습니다. 제출된 트랜잭션이 거부되면 결과 블록에 나타나지 않으며 영수증도 존재하지 않습니다.

최종성 및 지연 시간

Zenith EVM 트랜잭션의 최종성은 Canton 합의에 의해 제공됩니다. 검증자들은 동일한 입력으로부터 제안된 EVM 블록을 독립적으로 재구성하며, 필요한 검증자 확인 임계값에 도달하면 Canton 중재자가 블록 빌딩 트랜잭션을 최종 확정합니다.

EVM 실행이 Canton 트랜잭션 흐름을 통해 조율되기 때문에:

  • 실행은 원자적입니다: 결합된 Canton/EVM 워크플로가 통째로 커밋되거나 전체가 실패합니다.
  • 최종성은 결정론적입니다: Canton 트랜잭션이 확정되면 EVM 상태 전이는 최종적입니다.
  • Canton 최종성 이후 EVM 재구성(reorg)은 없습니다: 정식 EVM 상태는 최종 확정된 Canton 중재 블록 시퀀스를 따릅니다.

현재 testnet에서 Canton 네이티브 트랜잭션 내 추가 EVM 작업의 일반적인 종단 간 지연 시간은 400ms에서 1.5초 사이에서 변동합니다. 이는 약 4–5초 만에 최종성에 도달하는 Canton 전용 트랜잭션과 비교해 최소한의 지연만 추가합니다.

참고: 이 지연 시간 수치는 초기 testnet 측정값이며 아직 최적화되지 않았습니다.

Ethereum Mainnet과의 차이점

Zenith EVM은 Reth를 기반으로 구축되었고 표준 Ethereum RPC 인터페이스를 제공하므로, 동일한 개발 패턴을 Zenith에 그대로 적용할 수 있습니다. 이 섹션에서는 다른 점을 중점적으로 설명합니다.

무엇이 같은가?

영역Zenith EVM 동작
EVM 실행동일한 바이트코드 실행, 동일한 옵코드입니다.
Solidity 컨트랙트표준 Solidity 컨트랙트를 수정 없이 또는 최소한의 수정으로 배포할 수 있습니다.
RPC표준 Ethereum JSON-RPC 인터페이스
도구MetaMask, Foundry, Hardhat, Remix, ethers.js 등 일반적인 EVM 도구와 함께 작동합니다.
트랜잭션표준 EVM 트랜잭션 서명 및 제출입니다.
가스 계산현재 Zenith EVM testnet은 실행 레이어에서 표준 EVM 가스 시맨틱스를 사용합니다.
표준표준 ERC 컨트랙트를 네이티브로 배포하고 사용할 수 있습니다.
포크Ethereum 제네시스 이후의 모든 현행 포크가 Zenith EVM에서 활성화됩니다.

참고: Zenith EVM mainnet의 가스 계산에는 Canton 트랜잭션 수수료를 반영하는 추가 요소가 포함될 예정입니다.

무엇이 다른가?

영역Ethereum mainnetZenith EVM
합의Ethereum 지분 증명(proof-of-stake) 합의입니다.Canton이 중재하는 검증 및 최종성입니다.
최종성확률적(최종성까지 2 에포크 / 약 13분)결정론적이며 몇 초 이내입니다. 재구성(reorg)이 없습니다.
재구성(Reorg)최종성 이전에는 발생할 수 있습니다.Canton 최종성 이후에는 EVM 재구성이 없습니다.
비콘 체인(Beacon Chain)Ethereum은 합의와 검증자 선택 무작위성을 위해 비콘 체인을 사용합니다.Zenith EVM은 Ethereum 비콘 체인을 사용하지 않습니다.
PREVRANDAOEthereum 합의 컨텍스트로부터 채워집니다.Ethereum 비콘 체인 무작위성이 아니라 Zenith의 Canton 중재 블록 빌딩 흐름이 블록 빌딩 환경 속성(Prev RANDAO)으로 제공합니다. 컨트랙트는 Ethereum mainnet의 검증자 선택 무작위성 시맨틱스를 가정해서는 안 됩니다.
블록 생성Ethereum 검증자가 Ethereum 합의 규칙에 따라 블록을 제안합니다.블록 제안자가 Canton 측 블록 제안을 제출하고, 검증자가 Canton 합의를 통해 블록을 만들고 확인합니다.
블록 타임12초 블록 타임저희 testnet은 5초 블록 타임을 갖게 됩니다. mainnet에서는 1초 블록 타임을 목표로 하고 있습니다.
정산Ethereum mainnet에서 정산됩니다.EVM 블록과 상태 루트가 Canton에서 정산됩니다.
Canton과의 원자적 상호 운용성네이티브로는 제공되지 않습니다.Canton 네이티브 워크플로와 Zenith EVM 실행을 하나의 원자적 Daml 워크플로의 일부로 조율할 수 있습니다.
스테이킹검증자가 32 ETH를 스테이킹합니다검증자는 권한을 부여받은 Canton 참여자이며, 스테이킹 메커니즘이 없습니다
신뢰 모델Ethereum 검증자 집합과 Ethereum 합의 규칙입니다.Canton의 신뢰 모델을 따릅니다
익스플로러 메타데이터EVM 전용 트랜잭션 메타데이터입니다.EVM 트랜잭션 메타데이터에 Canton 업데이트 메타데이터가 추가됩니다.

개발자를 위한 시사점

  • 표준 EVM 워크플로는 그대로 작동합니다: 배포, 상호 작용, 이벤트, 영수증, 도구는 기존과 동일합니다.
  • 확정된 트랜잭션은 최종적입니다: 트랜잭션이 Canton을 통해 최종 확정되면, 애플리케이션은 일반적으로 확률적 최종성 체인에서처럼 여러 블록 확인을 기다릴 필요가 없습니다.
  • 이중 트랜잭션 식별성: EVM 트랜잭션은 자신이 포함된 EVM 블록에 해당하는 Canton 업데이트 ID로 추적할 수 있습니다.
  • Canton 네이티브 워크플로가 EVM 실행을 조율할 수 있습니다: 모든 Zenith EVM 트랜잭션 배치는 원자적 Canton 중재 블록 빌딩 경로를 통해 처리됩니다.
  • 원자적 워크플로를 위한 영수증 확인: EVM 트랜잭션이 거부되면 영수증이 존재하지 않습니다. Canton 측 워크플로는 이를 실패한 EVM 측(leg)으로 처리해야 합니다.
  • Ethereum 비콘 체인 무작위성 시맨틱스에 의존하지 마세요: block.prevrandao를 사용하는 컨트랙트는 Zenith EVM이 이 값을 Ethereum 비콘 체인 검증자 선택 무작위성에서 가져오지 않는다는 사실을 고려해야 합니다.

상호 운용성

Zenith EVM은 상호 보완적인 두 가지 상호 운용성 모델을 지원합니다:

  1. Gateway, Canton 네이티브 워크플로와 Zenith EVM 간의 Zenith 원자적 상호 운용성 경로, 그리고
  2. 외부 생태계 상호 운용성, Zenith EVM을 외부 체인 및 메시징 생태계와 연결하게 될 모델입니다.

Zenith Gateway

Gateway는 Canton과 Zenith EVM 간의 Zenith 원자적 상호 운용성 솔루션입니다.

이는 Canton 워크플로가 Zenith EVM에서의 EVM 실행을 조율하고, 그 결과 상태 전이가 Canton을 통해 정산되는 Canton 네이티브 상호 운용성 경로입니다. 이것이 가능한 이유는 Zenith EVM의 블록 생성과 최종성이 별도의 Ethereum 합의 레이어가 아닌 Canton 컨트랙트와 검증자 확인을 통해 중재되기 때문입니다.

Gateway는 Zenith EVM의 나머지 부분과 동일한 원자적 Canton 중재 블록 처리 경로를 사용합니다. Canton 네이티브 워크플로는 Canton으로 라우팅되는 트랜잭션 배치에 EVM 트랜잭션을 제출할 수 있으며, 결과 EVM 블록은 Canton을 통해 원자적으로 처리되고 최종 확정됩니다.

모든 경우에 블록 생성은 Canton을 통해 조율되고 확인됩니다. 검증자들은 동일한 입력으로부터 제안된 EVM 블록을 재구성하며, 필요한 검증자 확인에 도달하면 블록이 최종 확정되어 정식 블록이 됩니다. 그런 다음 Canton 측 워크플로는 자체 상태 변경을 커밋하기 전에 EVM 결과를 검증할 수 있습니다.

Gateway와 외부 브리지 비교

속성Gateway일반적인 외부 상호 운용 / 메시징 프로토콜
주요 범위Canton ↔ Zenith EVMZenith EVM ↔ 외부 생태계
실행 모델Canton이 중재하는 블록 생성 및 최종성크로스체인 메시지 전달 또는 토큰 전송
최종성 모델결합된 워크플로에 대한 Canton 트랜잭션 최종성소스 체인, 대상 체인, 프로토콜 가정에 따라 다름
실패 동작단일 원자적 워크플로에 대해 부분적인 Canton/EVM 커밋 없음일반적으로 비동기적이며, 실패 및 재시도 동작은 프로토콜마다 다름
최적 사용 사례Canton 네이티브 자산, Daml 워크플로, Zenith EVM 컨트랙트Ethereum, Base, Solana 및 기타 외부 생태계와의 상호 운용성

Gateway 워크플로

높은 수준에서 보면, Gateway 워크플로는 Canton 측 작업을 EVM 측 트랜잭션과 조율합니다:

  1. Canton 네이티브 워크플로가 하나 이상의 EVM 트랜잭션을 준비합니다.
  2. 트랜잭션은 EVM 실행 전에 Canton을 통해 라우팅되는 정렬된 배치에 포함됩니다.
  3. 블록 생성은 Canton을 통해 확인됩니다. 검증자들은 동일한 입력으로부터 제안된 EVM 블록을 재구성하며, Canton 최종성에 도달하면 EVM 블록이 정식 블록이 됩니다.
  4. 그런 다음 Canton 측 워크플로는 결과 EVM 블록 데이터와 트랜잭션 영수증을 검사하여 예상한 EVM 트랜잭션이 포함되었는지, 예상한 로그나 이벤트가 발생했는지 확인합니다.

Gateway 트랜잭션은 자체적인 별도 블록이 아니라 블록의 나머지 부분과 함께 포함되고 최종 확정됩니다. 이를 통해 Gateway는 모든 트랜잭션 배치가 Canton의 합의를 통해 라우팅되는 Zenith EVM의 단일 Canton 중재 블록 생성 흐름과 일치하게 유지됩니다.

영수증 기반 검증

Gateway가 작동하려면 Canton 측 워크플로에 결과 블록 해시 이상의 정보가 필요합니다. EVM 트랜잭션 영수증은 표준 Ethereum 트랜잭션 영수증과 동등한 형식의 구조화된 값으로 Canton 워크플로에 제공됩니다. 여기에는 다음이 포함됩니다:

  • 성공 또는 실패 상태,
  • 발생한 로그와 이벤트,
  • EVM 트랜잭션 해시,
  • 발신자,
  • 대상 또는 생성된 컨트랙트 주소.

발생한 로그를 통해 Canton 측 워크플로는 어떤 EVM 상태 전이가 일어났다는 것만 확인하는 데 그치지 않고, 의도한 EVM 이벤트가 발생했는지 검증할 수 있습니다.

각 트랜잭션은 검증되며 거부될 수 있으므로, 영수증은 트랜잭션이 실제로 최종 확정된 블록에 포함된 경우에만 존재합니다. 따라서 영수증의 존재 여부는 워크플로가 성공한 EVM 측과 거부된 EVM 측을 구별하는 방법입니다. 영수증이 없으면 Canton이 조율하는 워크플로는 EVM 실행을 실패로 간주하고 결합된 작업을 중단해야 합니다. Canton 작업 또는 업데이트 ID와의 상관관계는 Canton 측에서 제공되며 별도로 추적됩니다. 이는 EVM 영수증의 일부가 아닙니다.

외부 생태계 상호 운용성

외부 생태계 상호 운용성은 Gateway와는 별개입니다.

Gateway는 워크플로의 양쪽이 모두 Canton을 통해 중재되기 때문에 Canton ↔ Zenith EVM 원자적 조합성을 위해 설계되었습니다. Ethereum, Base, Solana 또는 기타 L1/L2 네트워크와 같은 생태계와의 외부 상호 운용성은 독립적인 네트워크 간의 크로스체인 메시징, 브리징 또는 토큰 전송이라는 다른 모델을 따릅니다.

이러한 통합은 CCIP나 LayerZero와 같은 검증된 크로스체인 메시징 또는 브리지 프로토콜을 사용할 수 있습니다. 이 경우 Gateway의 Canton 중재 원자성이 아니라 선택된 외부 프로토콜의 신뢰, 최종성, 재시도, 실패 가정을 따르게 됩니다.

현재 상태: Gateway는 원자적 워크플로를 위한 기본 Canton ↔ Zenith EVM 상호 운용성 메커니즘입니다. 외부 생태계 통합은 별도의 로드맵 항목입니다.