Skip to content

Latest commit

 

History

History
235 lines (168 loc) · 8.45 KB

edit-contracts.md

File metadata and controls

235 lines (168 loc) · 8.45 KB

How to edit zkEVM contracts for Kurtosis CDK

A step-by-step guide to edit the zkEVM Solidity contracts in a Polygon CDK devnet.

This document draws from the following resources:

Goals

  • Edit the Solidity code in repo zkevm-contracts in file VerifierRollupHelperMock.sol in function verifyProof.
  • Rebuild the zkevm-contracts docker image.
  • Edit this repo kurtosis-cdk to use our new build of zkevm-contracts.
  • Spin up a Polygon CDK devnet and observe our changes in the active devnet.

Set up your system

Set up your system as per instructions at Polygon CDK Kurtosis Package:

  • Install Docker and Kurtosis.
  • Run ./scripts/tool_check.sh.

If you get an error about an incorrect version of Kurtosis then install the correct version as described in Kurtosis documentation.

Spin up a Polygon CDK devnet on your local machine. The process should complete within 10 minutes.

kurtosis clean --all
kurtosis run --enclave cdk-v1 --args-file params.yml .

Feel free to follow subsequent instructions to play with your devnet.

Let's take a look at the Solidity code we want to change. Attach a shell to contracts-001 container:

kurtosis service shell cdk-v1 contracts-001

In the attached shell take a peek at the Solidity code for verifyProof:

cat zkevm-contracts/contracts/mocks/VerifierRollupHelperMock.sol

You should see

// SPDX-License-Identifier: AGPL-3.0

pragma solidity 0.8.20;

import "../interfaces/IVerifierRollup.sol";

contract VerifierRollupHelperMock is IVerifierRollup {
    function verifyProof(
        bytes32[24] calldata proof,
        uint256[1] memory pubSignals
    ) public pure override returns (bool) {
        return true;
    }
}

Exit the attached shell when you're done examining the contracts-001 container:

exit

Let's observe that proofs are passing verification as expected. Use your preferred method to view the logs for the container agglayer. For example, you could use the Docker Desktop graphical interface, or you could follow in a terminal via

kurtosis service logs cdk-v1 agglayer --follow

You should see logs like

2024-08-19 15:57:01   2024-08-19T19:57:01.917737Z  INFO agglayer_node::rpc: Successfully settled transaction 0x1935…95d1 => receipt TransactionReceipt { ... }

Tear down your devnet after you're done playing:

kurtosis clean --all

Fetch and edit the docker image zkevm-contracts

Clone the repo zkevm-contracts. Due to Docker's constraints on coyping files from the local build context, it will help us later to clone this repo into a new subdirectory docker/local-test-zkevm-contracts of the current repo kurtosis-cdk:

git clone [email protected]:0xPolygonHermez/zkevm-contracts.git docker/local-test-zkevm-contracts

Optional: add docker/local-test-zkevm-contracts to your .gitignore file in repo kurtosis-cdk to suppress git messages about the repo you just cloned.

We don't want any nasty surprises, so let's checkout the version of this repo that's currently used in kurtosis-cdk:

cd docker/local-test-zkevm-contracts
git checkout v6.0.0-rc.1-fork.9

Open the file docker/local-test-zkevm-contracts/contracts/mocks/VerifierRollupHelperMock.sol and make a silly change:

diff --git a/contracts/mocks/VerifierRollupHelperMock.sol b/contracts/mocks/VerifierRollupHelperMock.sol
index 85e6b91..20e51c4 100644
--- a/contracts/mocks/VerifierRollupHelperMock.sol
+++ b/contracts/mocks/VerifierRollupHelperMock.sol
@@ -9,6 +9,6 @@ contract VerifierRollupHelperMock is IVerifierRollup {
         bytes32[24] calldata proof,
         uint256[1] memory pubSignals
     ) public pure override returns (bool) {
-        return true;
+        return false;
     }
 }

This change causes the function verifyProof to reject any proof it's given.

Rebuild the docker image zkevm-contracts

Let's modify the repo kurtosis-cdk to build the docker image zkevm-contracts from your local file system, and then use that new image in the devnet.

You can make the following edits manually, or fetch them from the edit-contracts-demo branch of Espresso's fork of kurtosis-cdk.

Open the file docker/zkevm-contracts.Dockerfile and make the following edits:

diff --git a/docker/zkevm-contracts.Dockerfile b/docker/zkevm-contracts.Dockerfile
index 1a18e9c..531f667 100644
--- a/docker/zkevm-contracts.Dockerfile
+++ b/docker/zkevm-contracts.Dockerfile
@@ -12,10 +12,13 @@ LABEL description="Helper image to deploy zkevm contracts"
 # STEP 1: Download zkevm contracts dependencies and compile contracts.
 ARG ZKEVM_CONTRACTS_BRANCH
 WORKDIR /opt/zkevm-contracts
+
+# TEMPORARY: clone from my local storage instead of github.
+COPY local-test-zkevm-contracts .
+
 # FIX: `npm install` randomly fails with ECONNRESET and ETIMEDOUT errors by installing npm>=10.5.1.
 # https://github.com/npm/cli/releases/tag/v10.5.1
-RUN git clone --branch ${ZKEVM_CONTRACTS_BRANCH} https://github.com/0xPolygonHermez/zkevm-contracts . \
-  && npm install --global [email protected] \
+RUN npm install --global [email protected] \
   && npm install \
   && npx hardhat compile

This change tells Docker to build the image zkevm-contracts from your new local version of that repo instead of fetching it from github.

Next let's rebuild our edited docker image zkevm-contracts. Open a terminal in your repo kurtosis-cdk, move to the docker directory, and rebuild the image:

cd docker
docker build . \
 --tag local/zkevm-contracts:v6.0.0-rc.1-fork.9 \
 --build-arg ZKEVM_CONTRACTS_BRANCH=v6.0.0-rc.1-fork.9 \
 --build-arg POLYCLI_VERSION=main \
 --file zkevm-contracts.Dockerfile

Your new image should now be visible in docker. The command

docker images --filter "reference=local/zkevm-contracts"

should produce output like

REPOSITORY              TAG                    IMAGE ID       CREATED          SIZE
local/zkevm-contracts   v6.0.0-rc.1-fork.9     fbd050369e61   22 minutes ago   2.37GB

Spin up a devnet with your new docker image

Let's spin up a new Polygon CDK devnet with your edited docker image zkevm-contracts.

Point your devnet to your local docker image. Open the file params.yml and change leovct/zkevm-contracts to local/zkevm-contracts:

diff --git a/params.yml b/params.yml
index 5293da7..5e451b6 100644
--- a/params.yml
+++ b/params.yml
@@ -55,7 +55,7 @@ args:
   zkevm_da_image: 0xpolygon/cdk-data-availability:0.0.7
   # zkevm_da_image: 0xpolygon/cdk-data-availability:0.0.6

-  zkevm_contracts_image: leovct/zkevm-contracts:v6.0.0-rc.1-fork.9
+  zkevm_contracts_image: local/zkevm-contracts:v6.0.0-rc.1-fork.9

   # agglayer_image: 0xpolygon/agglayer:0.1.3
   agglayer_image: ghcr.io/agglayer/agglayer-rs:main

Optional: by default, your devnet disables fancy dashboards. If you want to view your devnet from a fancy dashboard such as Grafana then open the file params.yml and ensure that args.additional_services includes "prometheus_grafana".

Spin up your devnet! Just as before, move to the root directory of the repo kurtosis-cdk and run

kurtosis run --enclave cdk-v1 --args-file params.yml .

Let's verify that our edits to the Solidity code are live on this devnet. Just as before, attach a shell to contracts-001 container and then peek at the Solidity code for verifyProof:

kurtosis service shell cdk-v1 contracts-001

Then in the attached shell do

cat zkevm-contracts/contracts/mocks/VerifierRollupHelperMock.sol

You should see your edits in the live code: return false instead of return true.

Observe that proofs are failing verification as expected in the logs for docker container agglayer. You should see logs like

2024-08-19 15:44:21   2024-08-19T19:44:21.884754Z ERROR agglayer_node::rpc: Failed to dry-run the verify_batches_trusted_aggregator for transaction 0x161e…4e01: Contract call reverted with data: 0x09bde339, tx_hash: "0x161e…4e01"
2024-08-19 15:44:21     at crates/agglayer-node/src/rpc/mod.rs:176
2024-08-19 15:44:21

Congratulations! You successfully modified the smart contract verifier and observed your change in a live devnet! 🚀