🌐

PolygonエコシステムとEthereumの関係を整理する

2021/12/15に公開

CryptoGames.incをお手伝いさせていただいているPacyです。

(この記事はEthereumアドベントカレンダ-2021 14日目の記事です。)

先日PolygonのMirProtocol買収の発表がありましたね。

ZK rollupの課題であった署名作成速度の脅威的な改善とアルゴリズムの改善でnodeの水平スケールができるようになり、参加nodeが増えるほどスループットを増すことができるようになる、みたいなことが上記ツイートに一連でぶら下げられています。

またPolygonは来年2022年内にevm互換のZK rollup実現を目指すL2ソリューションHermezも8月に買収しています。ZK verseを謳い、ZK rollup界の雄を狙うとのことです。楽しみですね。

このように世間を賑わせているPolygonですが、自分としても昨今のgas代の高騰でEthereumメインネットが使いづらくなっている中、普段からお世話になっているものの、どういう仕組みで動いているのか、また俗にPolygonと言った場合に意図されるPolygon PoSネットワーク以外を含めたPolygonエコシステムとEthereumとの関係性を知らずに使っているなと思ったので少し調べてみました。

概要とコードリーディング

Polygonとはイーサリアムのスケーリングを目的とした一連のプロジェクトのことですが、一般にPolygonと言った場合にPolygonのPoSネットワークのことを指すこともあるので若干わかりづらい部分もあるのかなと思います。

https://blog.polygon.technology/polygon-zk-days-recap-polygon-zero-reveal-and-panel-talk-with-vitalik/

まずPolygonのPoSネットワークについて見ていきます。いくつかのレイヤーに分けられ、EthereumにPolygon PoSネットワーク上のブロックハッシュのMerkleRootを含むcheckpointを記録していくのが特徴です。

https://github.com/maticnetwork/whitepaper

L2ソリューションのアグリゲーターとなることを目指しているようで、Optimismであったり別のL2ソリューションとの連携(bridge実装など)も積極的に行なっているようです。

役割としては4層に分けられそうですが、コードのアーキテクチャとしては3層に分けられます。

  1. Staking and Plasma smart contracts on Ethereum
    https://github.com/maticnetwork/contracts
  2. Heimdall (Proof of Stake layer)
    https://github.com/maticnetwork/heimdall
  3. Bor (Block producer layer)
    https://github.com/maticnetwork/bor

BorはGo Ethereumを、HeimdallはTendermintコンセンサスエンジンを改変したものとのことです。

https://docs.polygon.technology/docs/contribute/polygon-architecture/

nodeの立ち上げはいくつか方法があるみたいですが、Heimdallのdocker-compose.ymlがあるのでそれを見るとどう動いているかのイメージがなんとなくつきます。

docker-compose.yml
services:
  rabbitmq:
    container_name: rabbitmq
    image: rabbitmq:3-alpine
    ports:
      - "5672:5672" # RabbitMQ
    restart: unless-stopped

  heimdalld:
    container_name: heimdalld
    image: 0xpolygon/heimdall:latest
    build: .
    restart: unless-stopped
    environment:
      - HEIMDALL_ETH_RPC_URL=https://goerli.infura.io/v3/[YOUR_INFURA_PROJECT_ID]
    volumes:
      - ./data:/heimdall
    ports:
      - "26656:26656" # P2P (TCP)
      - "26657:26657" # RPC (TCP)
    depends_on:
      - rabbitmq
    command:
      - start
      - --p2p.laddr=tcp://0.0.0.0:26656
      - --rpc.laddr=tcp://0.0.0.0:26657

  heimdallr:
    container_name: heimdallr
    image: 0xpolygon/heimdall:latest
    build: .
    restart: unless-stopped
    environment:
      - HEIMDALL_ETH_RPC_URL=https://goerli.infura.io/v3/[YOUR_INFURA_PROJECT_ID]
    volumes:
      - ./data:/heimdall
    ports:
      - "1317:1317" # Heimdall REST API
    depends_on:
      - heimdalld
    command:
      - rest-server
      - --laddr=tcp://0.0.0.0:1317
      - --node=tcp://heimdalld:26657

https://github.com/maticnetwork/heimdall/blob/master/docker-compose.yml

肝心のEthereumメインネットへcheckpointを打つ部分ですが、起動時にHeimdallのrabbitmqにtaskを登録しておいて、Borからrabbitmqのqueueにイベントが入ってくると実行されるフローになってそうです。

checkpoint.go
// RegisterTasks - Registers checkpoint related tasks with machinery
func (cp *CheckpointProcessor) RegisterTasks() {
	cp.Logger.Info("Registering checkpoint tasks")
	if err := cp.queueConnector.Server.RegisterTask("sendCheckpointToHeimdall", cp.sendCheckpointToHeimdall); err != nil {
		cp.Logger.Error("RegisterTasks | sendCheckpointToHeimdall", "error", err)
	}
	if err := cp.queueConnector.Server.RegisterTask("sendCheckpointToRootchain", cp.sendCheckpointToRootchain); err != nil {
		cp.Logger.Error("RegisterTasks | sendCheckpointToRootchain", "error", err)
	}
	if err := cp.queueConnector.Server.RegisterTask("sendCheckpointAckToHeimdall", cp.sendCheckpointAckToHeimdall); err != nil {
		cp.Logger.Error("RegisterTasks | sendCheckpointAckToHeimdall", "error", err)
	}
}
checkpoint.go
cp.contractConnector.SendCheckpoint(sideTxData, sigs, rootChainAddress, rootChainInstance)

https://github.com/maticnetwork/heimdall/blob/d20bc3909567f1e12c0b121091f43fd257209b92/bridge/setu/processor/checkpoint.go#L71

https://github.com/maticnetwork/heimdall/blob/d20bc3909567f1e12c0b121091f43fd257209b92/bridge/setu/processor/checkpoint.go#L526

etherscanを見たところ、rootChainは直接呼ばれておらずproxyを介して呼ばれているようです。

Polygon PoSネットワーク上の一定のブロック数ごとにcheckpointが打たれるとのことだったので時間は一定間隔ではありませんが、現状だと数十分に1回は打たれています。

https://etherscan.io/address/0x86e4dc95c7fbdbf52e33d563bbdb00823894c287

ちなみに、Polygonのエコシステムで動いているnodeやcontractと言ったモジュール群はこちらから一覧を見ることができます。

https://static.matic.network/network/mainnet/v1/index.json

また、Polygonエコシステム内の他のL2ソリューションと上記のHeimdall、Borとの関係性が気になったのでPolygon Hermezのrollupトランザクションなど見てみたのですが、特に関係はなく独立したチェーンとして動いているようでした。

ForgeBatchメソッドがrollupで呼ばれているトランザクションですね。

https://etherscan.io/address/0xa68d85df56e733a06443306a095646317b5fa633

おわりに

Polygonのエコシステムとその仕組み、Ethereumとの関係性を整理してみました。Polygonはレイヤー2のアグリゲーターを狙うというだけあってPolygon PoSネットワークだけに限らずエコシステム全体としてEthereumをwrapしていくような方向性なのかなと思っていますが、Ethereum2.0が控えていたりと今後この領域がどうなるのか楽しみです。


参考

https://defipulse.com/blog/understanding-the-polygon-scaling-suite/

https://www.theblockcrypto.com/post/126991/polygon-acquires-mir-protocol-400-million-zk-rollups

https://chasewright.com/how-to-run-a-polygon-matic-mainnet-node/

Discussion