From be62ee80cb01041860d4d273368ba97d743c75ab Mon Sep 17 00:00:00 2001 From: Kirk Haines Date: Mon, 4 Mar 2024 19:35:14 -0700 Subject: [PATCH] Bugfixes and enhance zkEVM demo (#34) --- content/module-2/4-topos-zkevm-demo.md | 82 ++++++++++++++++++-------- src/components/GitHubCodeBlock.tsx | 37 +++++++++--- 2 files changed, 87 insertions(+), 32 deletions(-) diff --git a/content/module-2/4-topos-zkevm-demo.md b/content/module-2/4-topos-zkevm-demo.md index c558a6c..ab5a994 100644 --- a/content/module-2/4-topos-zkevm-demo.md +++ b/content/module-2/4-topos-zkevm-demo.md @@ -30,23 +30,34 @@ Depending on your NodeJS environment and preferences, there are several ways to Our recommended way is to install the CLI using `npm`: -```bash + +``` $ npm install -g @topos-protocol/topos-zkevm-demo ``` + + + If you are a `yarn` user, you can install the CLI using `yarn`: -```bash + +``` $ yarn global add @topos-protocol/topos-zkevm-demo ``` + + + Alternatively, you can install and run via `npx`: -```bash + +``` $ npx @topos-protocol/topos-zkevm-demo ``` + + @@ -67,9 +78,11 @@ Topos zkEVM Demo is built on top of two projects: Both of these will be installed for you. -```bash + +``` $ topos-zkevm-demo install ``` + Running the topos-zkevm-demo install command @@ -84,9 +97,12 @@ $ topos-zkevm-demo install The demo utilizes Erigon, which is an implementation of Ethereum, to provide a local development chain. To start it, run: -```bash + +``` $ topos-zkevm-demo start ``` + + @@ -98,20 +114,19 @@ Optionally, you can replace the contract and the script with your own. When you are ready to execute the demo script, run: -```bash + +``` $ topos-zkevm-demo execute ``` + The command will output whatever is logged in the demo script, which by default is the address of the deployed contract, the hashes of the two transactions that were sent, as well as the block that included them (by default, the script will have the two transactions included in the same block). For example: -```bash -$ topos-zkevm-demo execute -``` - -Outputs: + ``` +$ topos-zkevm-demo execute > demo > hardhat run scripts/demo.ts @@ -124,6 +139,7 @@ Ketchup transaction: 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2 Mustard transaction: 0x5d98aba30400f5f0cc9c0f2d34f9f4280ec1fca88b177b3c2251ad1ea31a9af3 (inserted in block 4) ``` + Running the topos-zkevm-demo execute command @@ -133,7 +149,7 @@ From now on, the rest of the demo scenario will be divided into two roles: the ` Don't close or clear the terminal window where you ran the `execute` command, as you will need the output of the script to proceed with the next steps. - + ### [Prover] Generate a merkle proof @@ -141,7 +157,7 @@ As a prover, your intention is the following: from the two transactions that are To achieve this, we need to send two proofs to the `verifier`: -- a **merkle proof**: an inclusion proof of your transaction's receipt in the transaction's block's receipt trie +- a **merkle proof**: an inclusion proof of your transaction's receipt in the transaction's block receipt trie - a **zk-proof**: a zero-knowledge (zk) validity proof that ensures that the state transition of the block is computationally valid By verifying the _merkle proof_, the `verifier` can verify that your transaction is part of a greater set of transactions (a set that remains unknown to the `verifier`), and by verifying the `zk-proof`, the `verifier` can ensure that this greater set of transactions is computationally valid. Altogether, the verifier will verify that your transaction is part of a valid block, hence is a valid transaction. @@ -152,13 +168,16 @@ Note: The merkle proof is based on a transaction's receipt instead of the transa Let's start by generating the merkle proof for your transaction. The `tx_hash` should be a transaction hash, such as the `Ketchup transaction` hash that was output by the `execute` command. -```bash + +``` $ topos-zkevm-demo generate merkle-proof ``` + For example: -```bash + +``` $ topos-zkevm-demo generate merkle-proof 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 node dist/main generate merkle-proof 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 @@ -170,6 +189,7 @@ node dist/main generate merkle-proof 0x785102ca9881b284588452cd90685d2c713cf61f6 0xf851a02d247ca1770e3221e8aecf9d04fc9b6f7ff07361715c71ef8703bf24c7905d4580808080808080a0cfa9df4025f175e0c4338efc950dc2e30214a08e8ba6940226a97fd977b156b08080808080808080,0xf9011130b9010d02f90109018301155cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0 ``` + Running the topos-zkevm-demo generate merkle proof @@ -186,18 +206,22 @@ Note: When copying the merkle proof, make sure to copy the whole list. From the number of the block which includes your two transactions (reminder: the block number is output by the [execute](#3-execute-the-demo-script) command), you can generate a zk-proof of the block: -```bash + +``` $ topos-zkevm-demo generate zk-proof ``` + For example: -```bash + +``` $ topos-zkevm-demo generate zk-proof 4 Proving block 4... Successfully generated proof for block 4! (proof available at DEMO_ROOT/topos-zkevm-demo/zero-bin/proofs/b00004.zkproof)! ``` + Running the topos-zkevm-demo generate zk proof @@ -217,9 +241,11 @@ You will start by verifying the provided merkle proof. To do this, you will execute the following command: -```bash + +``` $ topos-zkevm-demo verify merkle-proof ``` + You might have seen that when we use the command `verify merkle-proof`, it asks for a `receipt_trie_root` which we haven't talked about yet. Let's clear that up: a merkle proof is basically a way to show that a specific piece of data (the leaf) is part of a larger database (the trie) by using a series of steps (a path) that lead to a single, final piece of information (the trie root). This path is made up of several pieces of data (nodes or hashes) that, when put together in a certain way, create a unique identifier (hash) that matches the trie root. This match proves that the data we started with is definitely in the database. To check if this is true (to verify a merkle proof), you need three things: the starting piece of data (the leaf), the series of steps (the proof), and the final piece of information (the trie root). @@ -229,19 +255,23 @@ The `verify merkle-proof` command internally computes the right leaf for you, fr So, first thing first, you need to retrieve the receipt trie root: -```bash + +``` $ topos-zkevm-demo util get-receipt-trie-root ``` + For example: -```bash + +``` $ topos-zkevm-demo util get-receipt-trie-root 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 > get-receipt-trie-root > hardhat get-receipt-trie-root 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 0x11ef2192f0c9aa092d69b9acf82085f384f172188cc321da94566dc9d33a3b18 ``` + Internally, the `util get-receipt-trie-root` command fetches the block which includes the passed transaction hash, and outputs the receipt trie root from its header. @@ -251,7 +281,8 @@ Now, you can verify the merkle proof. For example: -```bash + +``` $ topos-zkevm-demo verify merkle-proof 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 0xf851a02d247ca1770e3221e8aecf9d04fc9b6f7ff07361715c71ef8703bf24c7905d4580808080808080a0cfa9df4025f175e0c4338efc950dc2e30214a08e8ba6940226a97fd977b156b08080808080808080,0xf9011130b9010d02f90109018301155cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0 0x11ef2192f0c9aa092d69b9acf82085f384f172188cc321da94566dc9d33a3b18 Verifying merkle-proof for transaction: 0x785102ca9881b284588452cd90685d2c713cf61f6e4f3fcc8451bb6f2a571130 @@ -262,6 +293,7 @@ Verifying merkle-proof for transaction: 0x785102ca9881b284588452cd90685d2c713cf6 ✅ Merkle proof has been verified ``` + Running the topos-zkevm-demo verify merkle proof @@ -272,18 +304,22 @@ Verifying merkle-proof for transaction: 0x785102ca9881b284588452cd90685d2c713cf6 Now that you have verified that the provided transaction is indeed part of a state transition (a block), you can verify that it is valid by verifying the block's zk-proof: -```bash + +``` $ topos-zkevm-demo verify zk-proof ``` + For example: -```bash + +``` $ topos-zkevm-demo verify zk-proof DEMO_ROOT/topos-zkevm-demo/zero-bin/proofs/b00004.zkproof Verifying zk-proof: DEMO_ROOT/topos-zkevm-demo/zero-bin/proofs/b00004.zkproof ✅ DEMO_ROOT/topos-zkevm-demo/zero-bin/proofs/b00004.zkproof has been verified ``` + Running the topos-zkevm-demo verify zk proof diff --git a/src/components/GitHubCodeBlock.tsx b/src/components/GitHubCodeBlock.tsx index 76d6003..5631e9d 100644 --- a/src/components/GitHubCodeBlock.tsx +++ b/src/components/GitHubCodeBlock.tsx @@ -27,7 +27,7 @@ interface GitHubCodeBlockProps { highlights: string; // The lines from the fetched file to highlight. '3..5', '6, 9, 11', etc. nofetch: boolean; // If true, the code will not be fetched from GitHub. link: string; // The link to display. This overrides the default, which is to construct it from the github information. - nocopy: boolean; // An optional line or range of lines that will not be copied to the clipboard when the copy button is pressed. + nocopy: boolean|string; // An optional line or range of lines that will not be copied to the clipboard when the copy button is pressed. copytrim: string; // An optional regular expression that will be used to trim the code before it ia copied. separator: string; // A line or lines that will be followed by a visible separator line. nolinenumbers: boolean; // If true, line numbers will not be displayed. @@ -48,15 +48,24 @@ const trimCopiedCode = (code, separators_array, copytrim) => { code = code.replace(re, ''); } - if (separators_array(0)) { - code = code.split('\n').slice(0, separators_array(0)); - } + // if (separators_array(0)) { + // code = code.split('\n').slice(0, separators_array(0)); + // } return code; }; -const copyToClipboard = (str, separators_array, copytrim) => { - const codeToCopy = trimCopiedCode(str, separators_array, copytrim); +const copyToClipboard = (str, separators_array, copytrim, nocopy) => { + if (nocopy == true) { + return; + } + + let codeToCopy = trimCopiedCode(str, separators_array, copytrim); + + if (nocopy) { + codeToCopy = invertedTrimCode(codeToCopy, nocopy); + } + if (navigator.clipboard) { navigator.clipboard.writeText(codeToCopy).then( function () { @@ -133,6 +142,15 @@ const trimCode = (code, lines) => { .join('\n'); }; +const invertedTrimCode = (code, lines) => { + const excludedLines = calculateLines(lines); + + return code + .split('\n') + .filter((_, i) => !excludedLines(i)) + .join('\n'); +} + export const GitHubCodeBlock: React.FC< PropsWithChildren > = ({ @@ -168,7 +186,8 @@ export const GitHubCodeBlock: React.FC< /^
/,
         ''
       )
-      .replace(/<\/code><\/pre><\/div>$/, '') || '';
+      .replace(/<\/code><\/pre><\/div>$/, '')
+      .replaceAll(/</g,'<') || '';
 
   const [code, setCode] = useState(
     !nofetch && org && repo && path ? '' : childrenCode
@@ -267,10 +286,10 @@ export const GitHubCodeBlock: React.FC<
         
{`${language}`}
- {!nocopy && ( + {nocopy != true && (