2023. 9. 8. 18:18ㆍBlockchain/Polygon
금년 3월, Polygon은 지속적으로 연구하던 ZK rollup L2 프로젝트인 Polygon zkEVM을 출시했다(zkEVM 1번 블록). 여러 ZK rollup 프로젝트가 나왔었지만 EVM이 연동이 잘 되지 않는 문제점이 있었고, Polygon에서는 그 문제를 해결하기 위한 프로젝트로 이 zkEVM을 출시했다. Polygon zkEVM의 구조와 L1-L2간의 데이터 교환 방식에 대해 살펴 보고자 한다.
Consensus
Polygon zkEVM의 이전 버전인 Hermez 1.0에서 사용한 PoD(Proof of Donation) consensus를 사용했지만 zkEVM에서는 새로운 consensus mechanism이 필요하다 생각되어 제안된 PoE(Proof of Efficiency)를 사용한다고 한다. 자세한 내용은 나중에 시간되면 찾아보고.. 지금은 제안된 consensus의 컨셉만 보려한다.
PoE
기존 PoD와 같은 합의 메커니즘을 적용하려 하니 발생되는 몇가지 이슈들을 Hermez 팀에서 확인하였다. 그에 따라 새롭게 구성될 consensus는 아래와 같은 요구사항을 충족 시키는 것이 목표이다.
- L2의 tx batch를 제공하기 위한 무허가(permissionless) access
- 네트워크의 효율성(efficiency)
- 특정 single party에 의한 통제 제거
- 악의적 공격 방어
- total validation effort와 network value의 균형
해당 목표를 구현하기 위한 모델의 party는 2개로 구성되는데, 바로 Sequencer
와 Aggregator
이다. 각각의 party가 어떤 기능을 수행하는지 확인해 본다.
Sequencer
Sequencer는 일반 유저로 부터 L2에 전송되는 tx들을 수집한다. Sequencer의 운영은 누구나 가능하도록 설계되었고, sequencer는 네트워크에 생성된 새로운 L2 배치를 선택(select)하고 사전 처리(pre-processing)하는 동시에 선택된 모든 L2 tx 데이터가 포함된 L1 tx를 L1으로 전송한다. 이러한 L2 배치는 L1쪽으로 tx을 발생 시켜야 하기 때문에 gas fee가 필요하며, 또한 sequencer가 배치를 생성하고 제안할 수 있는 권리를 얻기 위해 matic 토큰 형태로 fee 지불을 추가로 해야한다. Gas fee가 들지만 유효한 배치를 제안하는 sequencer는 transaction 요청자 또는 네트워크 사용자가 지불하는 수수료를 인센티브로 받을 수 있다.
Aggregator
Aggregator도 sequencer와 마찬가지로 permissionless 참가자이다. 그림에서 보이는 것처럼 sequencer가 제안한 배치는 L1에서 확인되는 위치에 따라 정렬되고 tx 데이터가 포함된다. 이 때 aggregator는 sequencer가 전달한 배치를 확인하고 zk proof를 생성하여 L1에 제출한다. 이 zk proof를 생성하는 것은 따로 zkProver
이며, aggregator는 이를 활용하여 zk proof를 생성하기 위한 특수 하드웨어도 보유해야 한다.
zk proof 제출은 competition이기 때문에 PoE contract는 제안된 배치 중 하나 이상을 포함하여 유효한 state로 업데이트되는, 첫번째로 도착한 aggregator의 validity proof를 유효한 것으로 받아들인다. Aggregator는 배치의 sequencer가 지불한 matic 수수료 중 일부를 얻을 수 있다. 뒤늦게 proof를 전송한 aggregator는 proof 생성 비용은 발생하지만 smart contract에서 되돌리기 때문에 대부분의 gas fee는 회수 될 수 있다.
목표 달성
이러한 sequencer와 aggregator의 구조를 통하여 처음 PoE를 만들며 목표로 한 항목들에 대해 확인해 보려 한다. 필자의 생각이므로 polygon에서 의도한 바가 아닐 수 있다.
- L2의 tx batch를 제공하기 위한 무허가(permissionless) access
- L1측으로 batch를 전송하는 sequencer의 개념을 두었고, 이를 누구나 구동할 수 있도록 만드는 아키텍처로 무허가 access를 구현하였다. 이렇게 무허가로 하는 이유로 추측되는 것은, sequencer를 운영 하면 금전적 이득을 볼 수 있는 구조이기 때문에 많은 참여자들이 sequencer를 운영 하도록 의도한 것 같고, 이는 다수의 sequencer를 두어 consensus의 안정성을 높이기 위함으로 예상된다.
- 네트워크의 효율성(efficiency)
- 철저한 분업화를 통한 네트워크의 효율성을 노린것 같다. L2 tx를 모으는 sequencer, zk proof를 생성하는 zkProver, proof를 제출하는 aggregator로 나누어서 부여된 임무만 처리하는 것으로 보이기 때문이다. 만약 이 일들을 특정 entity가 모두 수행한다면 부하가 커지고, 블록이 확정되는 시간 또한 느려지기 때문에 체인 네트워크가 느려질 수 있다. 특히나 zk proof 생성은 많은 리소스가 필요하기 때문에 따로 proof를 생성하기 위한 전문 entity가 존재 하여서 네트워크의 효율성이 더 증대될 것으로 보인다.
- 특정 single party에 의한 통제 제거
- 마찬가지로 sequencer와 aggregator의 무허가 참여로 인해 특정 single party가 점유하는 현상을 막을 수 있을 것이다.
- 악의적 공격 방어
- 이 또한 무허가 참여로 블록체인에서 공격하기 가장 쉬운 SPoF를 제거할 수 있다. Sequencer가 생성하는 배치 자체도 fee가 들기 때문에 ethereum tx gas처럼 무작정 많은 전송을 할 수 없는 구조이기 때문에 DDoS도 방지 할 수 있을 것이다.
- total validation effort와 network value의 균형
- L2 tx batch 생성, rollup을 위한 zk proof 생성 시 모두 경제적 인센티브가 존재하기 때문에 양쪽의 균형을 유지한다고 볼 수 있다.
Architecture
Polygon zkEVM의 아키텍처를 확인하기 전에 L1에 기록되는 온체인 데이터를 확인해야 한다. ZK rollup 시에 전체 state를 재구성하는데 필요한 데이터와 zk proof를 모두 L1에 기록해야 한다. 이 때 validity proof(=zk proof)를 사용하여 state 전환이 올바른지 확인하고, state 전환을 허용하기 위해 규칙이 준수되었는 지 확인하는 용도로 consensus contract(PolygonZkEVM.sol
)이 활용 된다. Consensus contract가 L1에 배포 되어 있어야 함을 전제로 아키텍처를 확인해본다.
zkEVM을 구성하는 entity는 크게 4가지로 분류할 수 있으며 각각에 대한 간략한 기능을 살펴본다.
- Consensus contract(PolygonZkEVM.sol)
- 언급한 것처럼 L1에 배포되어 있으며 sequencer로 부터 batch를 수신하고 aggregator로 부터 batch의 유효성을 검사한다. 내부에는 zk-SNARK circuit이 사용되며, validity proof를 사용하여 state 전환이 올바른지 확인한다.
- zkNode
- Synchronizer: 네트워크의 동기화 구현
- Sequencer: L2 tx의 배치 생성
- Aggregator: 배치의 zk proof 전달
- zkProver
- zk proof를 생성하는 역할이다. 모든 aggregator는 zkProver를 사용하여 transaction batch를 검증하고 validity proof를 제공해야 한다.
- Bridge
- L1과 L2의 자산 교환을 담당한다.
데이터 교환
본문 제목처럼 이번 글은 zkEVM에 대한 data transfering에 대한 주제로 시작했기에 다른것보다 이부분을 먼저 중점적으로 보려 한다. (사실 zk rollup 단을 보려면 너무 많이 걸릴거 같아서 찍먹으로..ㅎ)
Exit tree
zkEVM의 bridge smart contract는 Exit tree
라는 merkle tree를 사용한다. Exit tree는 asset transfer에 참여하는 각 네트워크에 대한 정보를 merkle root로 관리하기 위함이다. Exit tree의 리프 노드는 네트워크 외부로 전송되는 asset 정보를 기록하며, L1과 L2에 각각 tree가 존재한다.
그림에서 확인할 수 있는 것처럼 리프노드를 L1의 exit tree root, L2의 exit tree root를 가지는 Global exit tree
가 존재한다. L1 root는 L1 네트워크 state의 trust를 가지고 있으며, L2 root는 L2 네트워크 state의 trust를 가지고 있기 때문에 global exit root는 양쪽 체인의 trust를 모두 보유하고 있는 셈이다. Global exit root는 L1, L2가 상태 변화에 따른 root 변경에 영향을 받으며, 동기화가 되면 사용자는 merkle 증명을 사용해 올바른 exit leaf(asset 정보)를 가지고 있다는 사실을 입증하고 전송된 asset을 claim할 수 있다.
Exit 리프 노드는 아래의 params를 사용하여 ABI로 인코딩된 결과의 Keccak256 해시값이다.
uint8 leafType
Type 0
는 자산 정보를 기록하며Type 1
은 메시징 정보를 기록한다.
int32 OriginNetwork
: origin 자산이 속한 origin 네트워크의 IDaddress OriginAddress
leafType = 0
이면 origin 네트워크 토큰 주소가,leafType = 1
이면msg.sender
가 기록된다.
uint32 destinationNetwork
: 브리징 타겟 네트워크의 IDaddress destinationAddress
: destination 네트워크에 속해 있는 브리지 자산 수령 주소uint256 amount
: 브리징 할 토큰 amountbytes32 MetadataHash
: 메타데이터 해시값으로써, 메타데이터에는 전송된 asset 또는 message payload가 포함된다.
사용자가 네트워크 간 자산 전송을 요청하면 Bridge smart contract는 각 네트워크의 exit tree에 leaf node를 추가한다.
Asset tranfer
L1-L2간 자산이동이 실제로 일어나는 시나리오를 아래 그림으로 확인한다.
사용자가 L1에서 L2로 자산을 전송할 때 asset 정보가 포함된 leaf node가 L1 exit tree에 추가된다.
// example data of transfer
Origin network: 0 (L1)
Origin address: 0x56566...
Dest Network: 1 (L2)
Dest Address: 0x12345...
Amount: 145
Metadata: 0x0...
Exit leaf가 추가됨으로써 exit root가 변경되고, L1 exit root가 global exit tree에 적용되어 global exit root가 업데이트 된다. Destination인 L2에서는 브리지 자산을 청구하기 위해 global exit root를 merkle 증명으로 확인하는데, merkle 증명을 사용하여 L1 exit root에 의해 global exit root가 자산 정보가 실제로 존재하는지 확인 할 수 있다.
Smart contract
Polygon zkEVM에서 사용되는 contract는 다음과 같다.
- Bridge Smart contract(
PolygonZkEVMBridge.sol
) - Global exit root manager(
PolygonZkEVMGlobalExitRoot.sol
) - Consensus contract(
PolygonZkEVM.sol
)
Bridge smart contract
Bridge SC는 브리지 기능(deposit)과 claim(withdraw)기능을 수행하여서 한 네트워크에서 다른 네트워크로 자산을 보내고 청구할 수 있다. 또한 Bridge SC는 exit tree를 업데이트 한다. 사용자가 네트워크 간의 자산 전송을 요청하고 commit하면 해당 contract는 origin exit tree에 leaf node를 추가한다.
Global exit root manager
해당 SC는 global exit tree root의 업데이트를 하고, 기록된 정보들의 저장소 역할을 수행한다. L1과 L2에 각각 contract가 배포된다. (L1 - PolygonZkEVMGlobalExitRoot.sol
/ L2 - PolygonZkEVMGlobalExitRootL2.sol
)
Consensus contract
Consensus contract는 L1에 배포되며 L1으로 전송된 tx batch들 검증한다. Tx batch들이 순서화되면(sequenced) 이 배치들의 유효성을 증명하기 위해 aggregator에게 요청이 이루어지고, zk proof는 verifier.sol
에서 검증된다. Zk proof를 검증한 후에 global exit root를 업데이트하기 위해서 zkEVM exit root를 global exit root manager contract로 전송한다.
zkEVM smart contract interactions
- L1 -> zkEVM (노란색 숫자)
- 사용자가 자산 전송을 commit할 때마다 bridge SC는 내부의
Bridge
function을 호출하여 exit leaf를 L1 exit tree에 추가한다. - Leaf 추가로 업데이트 된 L1 exit tree root는 global exit root 업데이트를 위해 global exit root manager contract로 전송된다.
- Consensus contract는 global exit root manager에서 업데이트 된 global root를 검색하고 브리지된 자산의 destination 네트워크가 zkEVM과 동기화되는데 사용된다.
- 사용자가 자산 전송을 commit할 때마다 bridge SC는 내부의
- zkEVM -> L1 (초록색 숫자)
- Consensus contract는
SequenceBatch
function으로 자산 이동 정보를 transaction에 포함하는 batch 순서를 지정한다. Verify.sol
contract의VerifyBatches
function을 호출하고 배치 정보를 입력한다. 그림에는 표시되지 않았지만 aggregator는 sequenced batch에 대한 유효성 proof를 생성하고, proof는 이 단계에서 자동으로 같이 검증된다.- zkEVM exit tree는 sequenced batch가 성공적으로 검증이 되었을 때 업데이트 된다. Consensus contract는 업데이트된 zkEVM exit root를 global exit root manager로 전송하고 global root를 업데이트 한다.
- Bridge SC는 업데이트 된 global root를 검색하고
Claim
function을 사용하여 transfer를 완료한다.
- Consensus contract는
Interaction among smart contract in L2
L2 내에 있는 contract 들간의 상호작용 과정이다.
- Batch tx가 처리되면 zkEVM bridge SC는 batch 정보가 포함된 exit leaf를 L2 exit tree에 추가하고, L2 exit root를 업데이트 한다.
- Bridge SC는 L2 exit root를 L2 global exit root manager(위 interaction의 global exit root manager와 다름)로 전달하지만, L2 global exit root manager는 global root를 업데이트 하지 않는다.
- 증명 및 검증을 위해 zk circuit(zk proof 생성)은 L2 global exit root manager로부터 L2 exit root를 확인한다.
- Batch가 검증 성공 하였을 시 L2 global exit root manager가 L2 exit root를 global exit tree(in L1)에 추가한다. 결과적으로 global exit root가 업데이트 된다.
이 때 zk circuit은 L2 exit root를 L1에 기록하며, L1에 배포된 bridge SC는 Claim
function을 통하여 transfer를 마무리 할 수 있다.
Asset flow
마지막으로 zkNode 기능 (Sequencer, aggregator)이 포함된 L1->L2 / L2->L1으로의 자산 흐름에 대한 과정을 확인해본다. 앞서 설명하였던 entity들과 smart contract간의 동작을 확인할 수 있다.
L1 to L2 asset flow
- L1에서 사용자가 bridge SC의
Bridge
function을 호출한다. 브리지 요청이 유효한 경우 bridge SC는 L1 exit tree에 leaf를 추가하고 새로운 L1 exit tree root를 계산한다. - Global exit root manager는 새로운 L1 exit root를 global exit tree에 추가하고 global exit tree root를 계산한다.
- Sequencer는 global exit root manager에서 최신 root를 가져온다.
- Transaction batch 처리 시 sequencer는 L2 global exit root manager의 특수 저장소 슬롯(special storage slot)에 global exit root를 저장하여 L2 사용자가 access 할 수 있도록 한다.
- 브리징 프로세스를 완료하기 위해 사용자는 bridge SC의
Claim
function을 호출하고 올바른 exit leaf가 global exit root에 포함되었다는 사실을 증명하기 위해 merkle proof를 제공한다. - Bridge SC는 L2 global exit root manager의 global exit root를 검색하고 사용자의 merkle proof를 검증한다. 검증이 유효하면 브리징 프로세스가 성공하는 것이고 아니면 실패한다.
L2 to L1 asset flow
- 사용자는 L2에서 bridge SC의
Bridge
function을 호출한다. 브리지 요청이 유효한 경우 bridge SC는 L2 exit tree에 leaf를 추가하고 새로운 L2 exit tree root를 계산한다. - L2 global exit root manager는 새로운 L2 exit root를 global exit tree에 추가하고 global exit tree root를 계산한다.
- Aggregator는 sequenced batch(사용자가 보낸 transaction이 포함된 batch) 실행 시 계산 무결성을 증명하는 zk proof를 생성한다.
- 검증 목적을 위해 aggregator는 새로운 L2 exit tree root로 이어지는 모든 batch 정보와 함께 zk proof를 consensus contract 로 전송한다.
- Consensus contract는 수신된 zk proof의 유효성을 확인하는
VerifyBatches
function을 호출하고, 증명이 유효한 경우 global exit tree를 업데이트 하기 위해 새로운 L2 exit root를 global exit root manager로 전송한다. - L1 네트워크에서 브리징 프로세스를 완료하기 위해 사용자는 bridge SC의
Claim
function을 호출하고 global exit root 계산에 올바른 exit leaf가 포함되었다는 사실에 대한 merkle proof를 제공한다. - Bridge SC는 L1 global exit root manager의 global exit root를 검색하고 사용자의 merkle proof를 검증한다. 검증이 유효하면 브리징 프로세스가 성공하는 것이고 아니면 실패한다.
Conclusion
Polygon에서 ZK rollup을 사용하면서 EVM 까지 동작할 수 있도록 만든 Polygon zkEVM의 데이터 교환 방법에 대해 알아보았다. 아직 zk rollup을 제대로 다뤄보지 않아 L1-L2 간 rollup 시의 자산 흐름, tx 처리에 대해 궁금한 점이 많았는데 zkEVM에서 제공하는 docs를 통해 '아 이런식으로 구현할 수 있겠구나' 하는 시나리오 파악을 조금 더 구체적으로 할 수 있었다. 자산 교환 자체는 일반적인 contract를 사용한 lock/mint 방식을 사용한 브리지 방식을 차용한 것으로 보이며, zk rollup이 존재함으로써 생기는 state root 관리에 대한 contract interaction 설계가 추가 된것 같다. L1-L2 간 교환 페이지도 제공하니 ETH가 남아돌 떄(!) 한번 테스트도 해봐야겠다.
데이터 교환 방식에 대해 확인 했으니 zkEVM에서 어떻게 zk rollup을 구사하면서 EVM 동작까지 시킬 수 있는 지 확인하는 과정이 남아있다. ZK rollup에 대한 지식을 조금 더 습득하기 위해서는 내부 코드를 보고 이해를 해야 할텐데 시간도 안나고 빡센 분야라 손이 잘 안가게 된다. 다음번에(시간 날 때) 확인해 보자.
참고
https://wiki.polygon.technology/docs/zkevm/architecture/
https://ethresear.ch/t/proof-of-efficiency-a-new-consensus-mechanism-for-zk-rollups/11988
'Blockchain > Polygon' 카테고리의 다른 글
Polygon PoS 기본 개념 (0) | 2023.06.20 |
---|