<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tony Olendo</title>
    <description>The latest articles on Forem by Tony Olendo (@tonyolendo).</description>
    <link>https://forem.com/tonyolendo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F614105%2Fdafa47be-bdd0-4b9c-b23d-994ba9917df2.jpg</url>
      <title>Forem: Tony Olendo</title>
      <link>https://forem.com/tonyolendo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tonyolendo"/>
    <language>en</language>
    <item>
      <title>Permit2 Frontend Guide</title>
      <dc:creator>Tony Olendo</dc:creator>
      <pubDate>Tue, 12 Dec 2023 02:51:46 +0000</pubDate>
      <link>https://forem.com/tonyolendo/permit2-frontend-guide-2m49</link>
      <guid>https://forem.com/tonyolendo/permit2-frontend-guide-2m49</guid>
      <description>&lt;p&gt;What if I told you never have to do an “Approve” transaction again?! Ok, maybe not never, but fewer times than you currently have to do? What if you can reduce the number of times you have to trust some random DeFi smart contract or that you’ll spend less time on revoke.cash when you hear about yet another hack! Well, Permit2 is a DeFi UX primitive that’s simplifies token approvals, safely. In this guide, I’ll walk you through a Permit2 frontend dApp that makes token approvals a lot easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Background Lesson
&lt;/h2&gt;

&lt;p&gt;Uniswap Labs developed Permit2 to allow token approvals to be shared across different applications by unifying ERC20 and NFT swapping in a single swap router. That’s a bit of a mouthful, but let’s say dApp A integrates with Permit2 and a user approved Permit2 to swap USDC for them; dApp B doesn’t have to do a new approval. All that dApp B has to do is check if there’s an existing approval, and if there is one, they can simply ask the user to sign an off-chain message allowing them to spend that approval, and dappB can transfer USDC directly if they submit the off-chain permit message alongside the transfer request. It really is that easy!&lt;/p&gt;

&lt;p&gt;The traditional token approval process requires users to trust a protocol or dapp and then approve that protocol. If that protocol is compromised, then the user's tokens may be lost. The current process goes as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User sends an approve() transaction authorizing a protocol or dapp to transfer their tokens&lt;/li&gt;
&lt;li&gt;The Dapp can now transfer tokens on behalf of the user&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeegy7vc5n8082e0mpxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeegy7vc5n8082e0mpxg.png" alt="Traditional ERC20 Token Approval"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, haters will say EIP-2612 solves this problem already, and while the token approval process is similar to Permit2, there are some subtle differences. EIP-2612 adds three new functions to the ERC-20 token standard: permit(), nonces(), and DOMAIN_SEPARATOR() to combine the consumption of token approvals and other standard ERC20 functions such as transfers. You can read more about &lt;a href="https://eips.ethereum.org/EIPS/eip-2612" rel="noopener noreferrer"&gt;EIP 2612 here&lt;/a&gt;. EIP-2612 adoption has been stymied because it can only work for new or upgradeable tokens.&lt;/p&gt;

&lt;p&gt;Permit2, however, works with existing ERC20 tokens; no upgrades are required, and new dApps or protocols can write Permit2 convenience functions or simply use the Permit2 canonical contract to permission approvals and transfer tokens directly and safely.&lt;/p&gt;

&lt;p&gt;With Permit2 however, a user will have to approve the canonical Permit2 contract that lives at this &lt;a href="https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3" rel="noopener noreferrer"&gt;address&lt;/a&gt; across multiple chains, namely mainnet Ethereum, Goerli, Polygon, Optimism, Arbitrum, and Celo. After which any integrating protocol or dapp can submit a users’s Permit2 msg and signature and have tokens transferred seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsd1ongtox4g33aituy8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsd1ongtox4g33aituy8d.png" alt="Permit2 Token Approval"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/teeolendo/permit2-uniswap" rel="noopener noreferrer"&gt;link&lt;/a&gt; to the repo I use in this guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;p&gt;In other Permit2 guides, the writers assume that there’s an intermediate protocol that sits between Alice and the Permit2 canonical contract; for the purpose of this article, we’ll assume the underlying dapp or protocol is represented by an address and the dApp will communicate with the canonical Permit2 contract directly, this is a frontend guide after all. For some background, I’m using &lt;a href="https://github.com/sozonome/nextarter-chakra" rel="noopener noreferrer"&gt;this&lt;/a&gt; frontend template that’s not Web3 enabled, we’ll install a few dependencies that work with the Permit2 SDK, out of the box. So let’s get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Next.JS
&lt;/h2&gt;

&lt;p&gt;You can choose to start a new Next.JS implementation but I used this template to get me up and running a little bit faster so feel free to start one of your own or do something else.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo clone sozonome/nextarter-chakra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Install the Permit2 SDK
&lt;/h2&gt;

&lt;p&gt;The first step is to install &lt;a href="https://github.com/Uniswap/permit2-sdk" rel="noopener noreferrer"&gt;Permit2 SDK&lt;/a&gt;, which provides a few helpful functions that allow anyone to get started as quickly as possible. The only caveat is that the Permit2 SDK only works with the Ethers 5.7.2. Fun times, I know! Because of the joys dependency graphs, we’ll restrict ourselves to using this for now but it’s not required, you can make the various contract calls independently, that would just be outside the scope of this guide.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @uniswap/permit2-sdk ethers@5.7.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We also add ethers js 5.7.2 as a SDK dependency. We’ll need it later on to pass providers to the SDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a few state variables
&lt;/h2&gt;

&lt;p&gt;Because we are building a frontend using React, we can add a few state variables that we can use to control the state of the frontend.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [account, setAccount] = useState&amp;lt;string&amp;gt;('')
const [spender, setSpender] = useState&amp;lt;string&amp;gt;('')
const [provider, setProvider] = useState&amp;lt;ethers.providers.Web3Provider&amp;gt;()
const token = '0x4f34BF3352A701AEc924CE34d6CfC373eABb186c'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;account&lt;/code&gt; variable stores the currently connected address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spender&lt;/code&gt; is a convenience function that we use to pull an additional address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provider&lt;/code&gt; holds the Ethers provider that we need to use to build a signer and also interact with the Permit2 SDK&lt;/li&gt;
&lt;li&gt;Token represents the Polygon Ecosystem Token on Goerli. This will be the main token contract that we will be interacting with.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Connect Wallet Feature&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next, we’ll add a Connect Wallet feature to the dApp that will toggle the state depending on if a wallet is connected.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Flex
  direction="column"
  alignItems="center"
  justifyContent="center"
  minHeight="70vh"
  gap={4}
  mb={8}
  w="full"
&amp;gt;
     &amp;lt;Text mb={4}&amp;gt;Welcome&amp;lt;/Text&amp;gt;
     {account ? (
       &amp;lt;&amp;gt;
         &amp;lt;Button onClick={handleApprove} mb={4}&amp;gt;
           Authorize Permit2
         &amp;lt;/Button&amp;gt;
         &amp;lt;Button onClick={handlePermit}&amp;gt;Permit&amp;lt;/Button&amp;gt;
         &amp;lt;Text mb={4}&amp;gt;Account: {account}&amp;lt;/Text&amp;gt;
       &amp;lt;/&amp;gt;
     ) : (
       &amp;lt;Button onClick={connectWallet}&amp;gt;Connect Wallet&amp;lt;/Button&amp;gt;
     )}
 &amp;lt;/Flex&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once we have the frontend elements, we can add the Connect Wallet function to connect to the user’s wallet.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const connectWallet = useCallback(async () =&amp;gt; {
   try {
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     const address = await (window as any).ethereum.request({
       method: 'eth_requestAccounts',
     })
     setProvider(
       new ethers.providers.Web3Provider(
         // eslint-disable-next-line @typescript-eslint/no-explicit-any
         (window as any).ethereum
       )
     )
     setAccount(address[0])
     setSpender(address[1])
   } catch (e) {
     // eslint-disable-next-line no-console
     console.error(e)
   }
 }, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code block connects to the &lt;code&gt;window.ethereum&lt;/code&gt; object which returns an array of addresses that the user has enabled.&lt;/p&gt;

&lt;p&gt;NOTE: This guide assumes at least two connected Ethereum addresses, the second address is not required for Permit2 to work, it just allows us to mock a protocol address.&lt;/p&gt;

&lt;p&gt;If you have configured everything correctly, once you connect your wallet, your frontend should look like the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwcfbc1l5k2ri5wyng83d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwcfbc1l5k2ri5wyng83d.png" alt="Connected Wallet State"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Approve Permit2
&lt;/h2&gt;

&lt;p&gt;This isn’t a required step to use Permit2, but it helps to ensure that a user has approved the Permit2 canonical contract to spend tokens.&lt;/p&gt;

&lt;p&gt;Let’s add a button to enable approvals&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Button onClick={handleApprove} mb={4}&amp;gt;
   Authorize Permit2
&amp;lt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And the logic for the Approval is fairly straightforward. First, we can now import from the Permit2 SDK library.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
 AllowanceProvider,
 PERMIT2_ADDRESS,
 MaxAllowanceTransferAmount,
 AllowanceTransfer,
} from '@uniswap/Permit2-sdk'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;handleApprove&lt;/code&gt; function assigns a signer, which will prompt the user to sign the approval message and then submit a transaction. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleApprove = useCallback(async () =&amp;gt; {
   try {
     const signer = provider!.getSigner(account)
     const permit2ContractAbi = [
       'function approve(address spender,uint amount)',
     ]
     const permit2Contract = new Contract(token, permit2ContractAbi, signer)
     const tx = await permit2Contract.approve(
       PERMIT2_ADDRESS,
       MaxAllowanceTransferAmount
     )
     await tx.wait()
   } catch (e) {
     // eslint-disable-next-line no-console
     console.error(e)
   }
 }, [account, provider])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Permit2 Config
&lt;/h2&gt;

&lt;p&gt;Now we get to the main stuff. The &lt;code&gt;handlePermit&lt;/code&gt; function processes the main Permit2 transfer. There are a few important steps that we will go through. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handlePermit = useCallback(async () =&amp;gt; {
   const processPermit = async () =&amp;gt; {
     const signer = provider!.getSigner(account)
     const allowanceProvider = new AllowanceProvider(
       provider!,
       PERMIT2_ADDRESS
     )
     // Address of the protocol contract that is being approved to spend tokens.
     const SPENDER_ADDRESS = spender
     /**
      * Get the current allowance amount, expiration, and nonce using the AllowanceProvider.
      * This is the same data that would be used to create a PermitSingle object.
      * You can check permitAmount or expiration on this data to determine whether you need to create a new permit.
      */
     const {
       // amount: permitAmount,
       // expiration,
       nonce,
     } = await allowanceProvider.getAllowanceData(
       token,
       account,
       SPENDER_ADDRESS
     )

     /**
      * Create a PermitSingle object with the maximum allowance amount, and a deadline 30 days in the future.
      */
     const permitSingle: PermitSingle = {
       details: {
         token,
         amount: MaxAllowanceTransferAmount,
         expiration: toDeadline(/* 30 days= */ 1000 * 60 * 60 * 24 * 30),
         nonce,
       },
       spender: SPENDER_ADDRESS,
       sigDeadline: toDeadline(/* 30 mins= */ 1000 * 60 * 60 * 30),
     }

     const { domain, types, values } = AllowanceTransfer.getPermitData(
       permitSingle,
       PERMIT2_ADDRESS,
       provider!.network.chainId
     )

     const signature = await signTypedData(signer, domain, types, values)

     const permitAbi = [
       'function permit(address owner, tuple(tuple(address token,uint160 amount,uint48 expiration,uint48 nonce) details, address spender,uint256 sigDeadline) permitSingle, bytes calldata signature)',
       'function transferFrom(address from, address to, uint160 amount, address token)',
     ]

     const permitContract = new Contract(PERMIT2_ADDRESS, permitAbi, signer)
     await permitContract.permit(account, permitSingle, signature)
   }
   processPermit()
 }, [account, provider, spender])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We begin by creating an AllowanceProvider object, which will contain many of the features we need for Permit2 transactions. The AllowanceProvider class is instantiated by passing a provider and the canonical PERMIT2_ADDRESS.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
       amount: permitAmount,
       expiration,
       nonce,
     } = await allowanceProvider.getAllowanceData(
       token,
       account,
       SPENDER_ADDRESS
     )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We read the current Permit2 status by querying the canonical address for the specific token approval amount, expiration and nonce. You can run checks at this stage and adapt behaviour according to your preferred business logic. From this point, we begin to see the real magic of Permit2. We are constructing a PermitSingle request, but this can be done as part of a batch using PermitBatch, this opens the door to multiple token approvals. &lt;/p&gt;

&lt;p&gt;From this stage, you need to sign the transaction details&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { domain, types, values } = AllowanceTransfer.getPermitData(
       permitSingle,
       PERMIT2_ADDRESS,
       provider!.network.chainId
     )
const signature = await signTypedData(signer, domain, types, values)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;getPermitData()&lt;/code&gt; takes the &lt;code&gt;permitSingle&lt;/code&gt; object, the canonical address and the chain ID to construct a signature. The &lt;code&gt;signTypedData()&lt;/code&gt; is a Uniswap library helper method designed to work around some limitations in wallet configurations, I’ve found it very useful when working with this version of ethers so I recommend using it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; yarn add @uniswap/conedison

import { signTypedData } from '@uniswap/conedison/provider/index'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To be clear, once you have a valid &lt;code&gt;permitSingle&lt;/code&gt; and signature, you have all you need to perform any Permit2 operation. The remainder of this guide fleshes out our use case. &lt;/p&gt;

&lt;h2&gt;
  
  
  Permit2 Transaction
&lt;/h2&gt;

&lt;p&gt;Once you have gotten the signature, you have the ability to perform a token transfer either via your dapp smart contract or directly interact with the canonical Permit2 address that exposes some useful functions. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const permitAbi = [
       'function permit(address owner, tuple(tuple(address token,uint160 amount,uint48 expiration,uint48 nonce) details, address spender,uint256 sigDeadline) permitSingle, bytes calldata signature)',
       'function transferFrom(address from, address to, uint160 amount, address token)',
     ]

     const permitContract = new Contract(PERMIT2_ADDRESS, permitAbi, signer)
     await permitContract.permit(account, permitSingle, signature)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Fun fact: I learned the hard way that when constructing your own ABI, a Solidity struct has to be structured as a tuple. This means you have to define the struct members as parameters of a function of the tuple and name it. The &lt;code&gt;permitSingle&lt;/code&gt; struct is a bit confusing, seeing as it’s a tuple by itself, and also has a child &lt;code&gt;details&lt;/code&gt; struct that is also represented by a tuple. Now I know some older heads are probably laughing at me at this point but this was the first time I was building an ABI manually and it was a fun rabbit hole to go down. If you don't understand what I mean with this tuple business, no worries, just read your ABIs the way you're used to. I just pull ABIs from Etherscan.&lt;/p&gt;

&lt;p&gt;From this stage, you can submit the transaction and that’s all it takes to approve and transact with Permit2. Backwards ERC-20 compatibility for the win!!&lt;/p&gt;

&lt;p&gt;I’ve included a few more convenience features on the frontend that pull a user's Permit2 token approval details so the UI is a little more feature rich than described in this guide as you can see below, nothing too fancy, just stuff that should help developers get started as soon as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15e4r90ith0v8w8nx2tn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15e4r90ith0v8w8nx2tn.png" alt="Final State of dApp"&gt;&lt;/a&gt;&lt;br&gt;
Next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I’d like to see Uniswap Labs and the ecosystem at large advocate for more Permit2 adoption; it’s great when no-brainer UX implementations like this can become more mainstream.&lt;/li&gt;
&lt;li&gt;Adding viem support to the SDK would be great.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.uniswap.org/permit2-and-universal-router" rel="noopener noreferrer"&gt;Uniswap Announcement Blog Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.uniswap.org/permit2-integration-guide" rel="noopener noreferrer"&gt;Permit2 Guide by Uniswap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2" rel="noopener noreferrer"&gt;Useful Solidity Patterns: Permit2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>The Complete Full-Stack Guide to Getting Started with Zero-Knowledge Proofs using Circom and ZK-Snarks - Part 2</title>
      <dc:creator>Tony Olendo</dc:creator>
      <pubDate>Thu, 26 Jan 2023 01:08:13 +0000</pubDate>
      <link>https://forem.com/tonyolendo/the-complete-full-stack-guide-to-getting-started-with-zero-knowledge-proofs-using-circom-and-zk-snarks-part-2-58o</link>
      <guid>https://forem.com/tonyolendo/the-complete-full-stack-guide-to-getting-started-with-zero-knowledge-proofs-using-circom-and-zk-snarks-part-2-58o</guid>
      <description>&lt;p&gt;Welcome to the second part of this series where I try to demystify zero-knowledge proofs (ZKPs) for the rest of non-math nerds . Since writing &lt;a href="https://dev.to/tonyolendo/the-complete-full-stack-guide-to-getting-started-with-zero-knowledge-proofs-using-circom-and-zk-snarks-part-1-53gi"&gt;part 1&lt;/a&gt;, my thoughts on the subject have evolved. I’m more drawn to answering the following questions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can anyone be a ZK developer?&lt;/li&gt;
&lt;li&gt;Is there a simple path that we can define for anyone to get started in writing ZK circuits?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The simple answer to all the questions above is yes! Most assuredly, yes. How? Just learn &lt;a href="https://iden3.io/circom" rel="noopener noreferrer"&gt;Circom&lt;/a&gt; and you’ll be well on your way.&lt;/p&gt;

&lt;p&gt;What is Circom? Circom is a circuit programming language and a compiler that allows programmers to design and create their own arithmetic circuits for Zero Knowledge Proofs. In other words, it makes it easier for any developer to get started writing ZKPs. Later we’ll look at some key Circom features and the most crucial piece of Circom, understanding polynomial constraints, but let’s start by understanding arithmetic circuits and why they are so important to Circom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arithmetic Circuits
&lt;/h2&gt;

&lt;p&gt;Most programming languages today are based on a Turing Machine, which is the foundation of computer science today given their ability to compute any function. On the other hand, an arithmetic circuit is a set of gates with separate inputs for each number that must be processed. The gates are connected so as to carry out an arithmetic action and the outputs of the gate circuit are the digits of the result (addition, subtraction, multiplication, or division).&lt;/p&gt;

&lt;p&gt;For ZK cryptographic processing, arithmetic circuits are preferred over Turing Machines for a number of reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficiency: Circuits are generally more time and space efficient as compared to Turing machines because circuits are comprised of a fixed set of gates.&lt;/li&gt;
&lt;li&gt;Verifiability: Circuits are better suited at proving a ZKPs’ computation is correct compared to Turing Machines.&lt;/li&gt;
&lt;li&gt;Compactness: Circuits are better suited to representing ZKPs’ complex and large computations by using a relatively small number of gates with reduced space requirements as compared to Turing Machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Polynomial Constraints
&lt;/h2&gt;

&lt;p&gt;A huge limitation I’ve seen most new Circom developers struggle with is how to express conditional statements as polynomial constraints. This is the most significant difference any programmer needs to understand when writing Circom circuits. But what are Polynomial constraints and how do they work?&lt;/p&gt;

&lt;p&gt;In Part 1 of this series, we converted the expression&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (x &amp;lt; 5) y = 7 else: y = 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = 7 * (x &amp;lt; 5) + 9 * (x &amp;gt;= 5);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple expression of a conditional statement as a quadratic equation and this goes to the heart of a key feature of Circom. In order to write circuits, one needs to understand polynomial constraints. A polynomial constraint is a mathematical statement that involves polynomials and sets limits on the values that the variables in the polynomial can take. For example, the polynomial "3x^2 + 2x + 1" is made up of the variables x and x^2, the coefficients 3 and 2, and the constant term 1. A polynomial is an expression made up of variables and coefficients, arranged according to certain rules of exponents. &lt;/p&gt;

&lt;p&gt;In a polynomial constraint, the variables in the polynomial are subject to certain conditions or limits. These conditions can be equalities (e.g., "x^2 + y^2 = 1") or inequalities (e.g., "x^2 + y^2 &amp;lt; 1"). Polynomial constraints are often used in optimization problems, where the goal is to find the values of the variables that maximize or minimize a given function subject to certain constraints. For example, consider the optimization problem of finding the minimum value of the polynomial "x^2 + y^2" subject to the constraint "x + y = 1."&lt;/p&gt;

&lt;p&gt;In this case, the constraint limits the values that x and y can take, as they must add up to 1. The solution to this problem would be x=y=0.5, which is the point at which the polynomial "x^2 + y^2" is minimized.&lt;/p&gt;

&lt;p&gt;We’ll delve deeper into constraint generation in Circom and how they function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key features of Circom
&lt;/h2&gt;

&lt;p&gt;Circuits in general are composed of a couple of core features, inputs, wires, and an output. Circom requires developers to express their computations in the form of arithmetic circuits and a few Circom features parallel these traditional circuit setups: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signals (inputs)&lt;/li&gt;
&lt;li&gt;Constraints (wires)&lt;/li&gt;
&lt;li&gt;Output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s introduce a simple circuit that we can use to demonstrate some key Circom features&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
pragma circom 2.0.0; 

template Factor () {  
   signal input a;  
   signal input b;  
   signal output c;  

   // Constraints
   c &amp;lt;== a * b;  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The circuit above multiples a and b and outputs the value as c. Let’s delve into a few of the features of the Circom language seen here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pragma
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line above is the version pragma and it specifies what compiler version the circuit is compatible with. If you don’t specify a pragma version, then the latest compiler version will be used and a warning will be shown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;template Factor () {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A template is used to generate circuits, think of them as objects that receive inputs, process computations and produce outputs. They are defined by instantiation and can be reused.&lt;/p&gt;

&lt;p&gt;A quick note on Templates, they are composable, meaning they can be reused to build bigger more complex circuits. A template is instantiated using the keyword component. So for instance, if we are to reuse our example circuit above, we would instantiate this as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;component multiplier = Factor ()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we’d then pass signals using the in keyword and output the computation using the out keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;signal intermediary // holds a temporary value
component multiplier = Factor()
multiplier.a ⇐ 8;
multiplier.b ⇐ 32;
intermediary ⇐ multiplier.c;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we introduce a temporary signal that will hold the value of the computation and we assign input and output values. Template reuse is a huge part of Circom and the Circom library continues to grow. I’d recommend reading through the various libraries to understand more about Circom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signals
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;signal input a;  
signal input b;  
signal output c;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Going back to the analogy of electrical circuits, in Circom, signals can be thought of as the basic units of information that travel through a circuit. Signals power computations meaning that regular mathematical operations can be performed using signals.&lt;/p&gt;

&lt;p&gt;Signals are private by default but they can hold input, output or intermediary values. Intermediary signals hold values inside of a circuit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constraints
&lt;/h3&gt;

&lt;p&gt;So everything we’ve done so far has been “wax-on, wax-off” (am I dating myself using this Karate Kid reference? maybe), we can now bring all this together. In Circom, everything comes down to writing constraints. Constraints can only be quadratic equations. Simply put, they should take the form of X + Y * Z = 0. I’m deliberately not going to delve any deeper into this for now but we can demonstrate this further by looking at how this works.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the XOR gate template from CircomLib&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0;


template XOR() { 
   signal input a;
   signal input b;
   signal output out;

   out &amp;lt;== a + b - 2*a*b; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This XOR template evaluates to true if only one input is true, take not of how the out signal is assigned &lt;code&gt;out &amp;lt;== a + b - 2*a*b&lt;/code&gt; which essentially constrains the circuit to a given quadratic computation. &lt;/p&gt;

&lt;p&gt;In Circom, constraints can be applied using the &lt;code&gt;===&lt;/code&gt; or the &lt;code&gt;&amp;lt;==&lt;/code&gt; operator. The former is an equality operator. Using the &lt;code&gt;===&lt;/code&gt;operator in the form of &lt;code&gt;a * 1 + b === 0&lt;/code&gt; is sufficient for the compiler to generate constraints and for your circuit to work.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;==&lt;/code&gt; allows you to combine signal assignment and constraint generation in one go, improving the readability of your code. A lot of Circom libraries use this convention.&lt;/p&gt;

&lt;p&gt;Now, there is a &lt;code&gt;&amp;lt;--&lt;/code&gt; operator that can be used for signal assignment but (shameless name drop here) I work at Polygon and as such I get the chance to interface with Jordi Baylina who created Circom and his advice is to me, which I pass on to you, is to always use double equals. This ensures that you’re always writing quadratic equations and generating constraints. If you somehow manage to write a circuit without constraints, the compiler will not play nice.&lt;/p&gt;

&lt;p&gt;So when in doubt, do what Jordi said, always use double equals unless you absolutely know why you’re using something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So we have reviewed a few features of Circom and the underlying paradigms required to write Zero-Knowledge Circuits in Circom. I think anyone can be a ZK developer using Circom and in the next part, we’ll delve into a sample circuit that highlights how to write polynomials constraints, the Rank 1 Constrain System, a Powers of Tau ceremony and eventually generate a Solidity file that you can deploy on-chain and build a full stack Dapp around. Exciting stuff!!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Complete Full-Stack Guide to Getting Started with Zero-Knowledge Proofs using Circom and ZK-Snarks - Part 1</title>
      <dc:creator>Tony Olendo</dc:creator>
      <pubDate>Tue, 27 Sep 2022 22:44:27 +0000</pubDate>
      <link>https://forem.com/tonyolendo/the-complete-full-stack-guide-to-getting-started-with-zero-knowledge-proofs-using-circom-and-zk-snarks-part-1-53gi</link>
      <guid>https://forem.com/tonyolendo/the-complete-full-stack-guide-to-getting-started-with-zero-knowledge-proofs-using-circom-and-zk-snarks-part-1-53gi</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Zero-knowledge Proofs (ZKP) have picked up a whole ton of interest in the last couple of years. We are super early in ZKP applications and yet we are already met with exciting use-cases that will only continue to grow in order to provide privacy-saving mechanisms for our digital lives. This guide is targeted at software developers who are ZKP curious by clarifying what ZKPs are while using the least math possible and still explaining how it works and how teams can get started with their ZKP projects. Needless to say, a lot more further reading is required to get fully up to speed with ZKPs but the goal here is to show you how you can use Circom to get started and shed some light on some known unknowns on your ZK journey. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://iden3.io/circom"&gt;Circom&lt;/a&gt;, is a circuit programming language and a compiler that allows programmers to design and create their own arithmetic circuits for ZKP. We’ll discuss common pitfalls in using Circom, the most important paradigm to have when developing in Circom and ways you can write and extend your own Circom circuits using existing Circom libraries.&lt;/p&gt;

&lt;p&gt;This guide will gloss over very key points about ZKPs in order to get readers coding with Circom as soon as possible. The “Further Reading'' section will provide useful links. &lt;/p&gt;

&lt;p&gt;This article is broken down into 4 sections, we will cover only section 1 and 2 in this instalment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are Zero-Knowledge Proofs and how do they intersect with Web3 (Theory)&lt;/li&gt;
&lt;li&gt;Key Paradigms (Theory)&lt;/li&gt;
&lt;li&gt;Circom and Solidity (Coding)&lt;/li&gt;
&lt;li&gt;Full-stack React application using Next.js (Coding)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What are Zero-Knowledge Proofs and How Do They Intersect with Web3
&lt;/h1&gt;

&lt;p&gt;Zero-Knowledge Proofs can simply be defined as the ability to prove you know something without revealing what you know. Think, for example, that you have to prove to a travel website, say an airline, that you are indeed a citizen of a given country without having to show them your passport and that the website will verifiably know that what you are saying is true. Sounds wild? I know but this ZKP accuracy and reliability is really high. This, and many other scenarios, are why ZKPs are all the rage right now. ZKP’s privacy-preserving properties are changing the fundamentals of how the Web works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components of a ZKP
&lt;/h2&gt;

&lt;p&gt;ZKPs can either be interactive—where a prover convinces a specific verifier but needs to repeat this process for each individual verifier—or non-interactive—where a prover generates a proof that can be verified by anyone using the same proof.&lt;/p&gt;

&lt;p&gt;The three fundamental characteristics that define a ZKP include: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Completeness: if the statement is true, an honest verifier will be convinced of this fact by an honest prover.&lt;/li&gt;
&lt;li&gt;Soundness: if the statement is false, no cheating prover can convince an honest verifier that it is true, except with some small probability.&lt;/li&gt;
&lt;li&gt;Zero-knowledge: if the statement is true, no verifier learns anything other than the fact that the statement is true. In other words, just knowing the statement (not the secret) is sufficient to imagine a scenario showing that the prover knows the secret.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;: ZKPs don’t necessarily equate to privacy, they equate to honest computation. The honest computation can be the foundation of a privacy tool, product or protocol. ZKP is a cryptographic standard not a privacy panacea in and of itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  History of ZKPs
&lt;/h2&gt;

&lt;p&gt;In 1985, an MIT paper by Shafi Goldwasser and Silvio Micali titled “The Knowledge Complexity of Interactive Proof-Systems” introduced the concept of ZKP which defined protocols in which interactive proofs that involve two kinds of entities: a prover and a verifier, interact over a number of rounds by sending messages. &lt;/p&gt;

&lt;p&gt;Prior to their paper, there was a lot of focus on interactive proof systems and the concept of Soundness, where a malicious prover attempts to trick a verifier. The concept of Soundness in which a mathematical statement is defined as sound if and only if every formula that can be proved in the system is logically valid with respect to the semantics of the system. Goldwasser, Micali and Rackoff changed the fundamentals of interactive proofs by asking “what if you don’t trust the verifier?” They asked, how much extra information is the verifier going to learn during the course of this proof, beyond the mere fact that the statement is true?&lt;/p&gt;

&lt;p&gt;By limiting this exposure of information, their proposed proving system provided the least amount of information to either party. While the approach was novel, a key limitation of this system was the requirement for interactivity. This meant that both prover and verifier had to send each other multiple messages of varying mathematical complexity in order to complete the verification process.&lt;/p&gt;

&lt;p&gt;What has since emerged are a number of proving systems, like STARKs, SNARKs, BulletProofs etc that, broadly speaking, remove the need for interaction between prover and verifier by using a secret key.  These proving systems have different benefits, drawbacks and value propositions but you can find out more about them &lt;a href="https://zkp.science/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applications in Web3
&lt;/h2&gt;

&lt;p&gt;There are a number of exciting applications of ZKPs in Blockchain technology. I’ll highlight two that relate to technology that I interact with in my role at Polygon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;zkEVM: The zkEVM wars are upon us and Vitalik’s &lt;a href="https://vitalik.ca/general/2022/08/04/zkevm.html"&gt;blog post&lt;/a&gt; defines the parameters of different zkEVM types. The endgame for zkEVM is providing a scaling solution for Ethereum. You can learn more about Polygon zkEVM &lt;a href="https://blog.polygon.technology/polygon-zkevm-within-vitaliks-framework-gaining-clarity-and-looking-ahead/?utm_source=Twitter-Main&amp;amp;utm_medium=Tweet&amp;amp;utm_campaign=zkEVM-Clarity"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Polygon ID:  Self-Sovereign Identity (SSI) is an exciting development of the internet that seeks to provide an identity layer to the internet. The core contention being that the internet should end with you, not your IP address. &lt;a href="https://polygon.technology/polygon-id/"&gt;Polygon ID&lt;/a&gt; is a blockchain-native identity system with programmable privacy that empowers people and enables the creation of trusted interactions with web3 services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Key Paradigms
&lt;/h1&gt;

&lt;p&gt;This guide is intended to provide hands-on instructions on getting started with Circom and we will be focusing on using the Snark tool that uses zk-SNARK under the hood but we have to define what zk-SNARKS are.&lt;/p&gt;

&lt;h2&gt;
  
  
  zk-SNARKS
&lt;/h2&gt;

&lt;p&gt;zk-SNARK stands for “Zero-Knowledge Succinct Non-Interactive Argument of Knowledge”, let’s break this down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“zk”: Zero-Knowledge, this was defined above&lt;/li&gt;
&lt;li&gt;“Succinct”: the proof that is generated is short. This is ideal because it means that our proofs can be stored on a blockchain, inside of a single transaction. This is particularly useful if we are looking at different applications of ZK such as Polygon ID.&lt;/li&gt;
&lt;li&gt;“Non-interactive”: This non-interactive component allows the verification to occur without having to send messages between the prover and the verifier. Gross oversimplification but think of this as a driving license being verified without having to hit the DMV’s API.&lt;/li&gt;
&lt;li&gt;“Argument” :  we don’t quite use mathematical proofs but we do provide a form of them for ZKPs to work&lt;/li&gt;
&lt;li&gt;“Knowledge”: the information that the prover has&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;zk-SNARKs are just one protocol that has various proving systems. I’d recommend further reading on ZK proving systems such as &lt;a href="http://www.zeroknowledgeblog.com/index.php/the-pinocchio-protocol"&gt;Pinocchio&lt;/a&gt;, &lt;a href="http://www.zeroknowledgeblog.com/index.php/groth16"&gt;Groth16&lt;/a&gt;, &lt;a href="https://vitalik.ca/general/2019/09/22/plonk.html"&gt;Plonk&lt;/a&gt;, &lt;a href="https://blog.polygon.technology/introducing-plonky2/"&gt;Plonky2&lt;/a&gt;. Also, the guide “Why and How zk-SNARK Works: Definitive Explanation” is seminal text in understanding zk-SNARKs. &lt;/p&gt;

&lt;p&gt;There is a general criticism of zk-SNARKS that in the generation of it’s key, there is still a requirement of a trusted setup in order to generate a witness, we’ll delve more into that in the coding section of this guide.&lt;/p&gt;

&lt;h1&gt;
  
  
  Arithmetic and ZKPs
&lt;/h1&gt;

&lt;p&gt;If I was to choose the most crucial piece in understanding ZKP, it would be this, how do you convert your computations into algebraic expressions? This is by far the part of Circom that gives new developers the most grief. Let me attempt to break it down for you.&lt;/p&gt;

&lt;p&gt;The goal of ZK is to verify computations and according to Kineret Segal &amp;amp; Shir Peled &lt;a href="https://medium.com/starkware/arithmetization-i-15c046390862"&gt;here&lt;/a&gt;, the first step “... is the translation (often referred to as ‘reduction’) of the problem of verifying a computation to the problem of checking that a certain polynomial, which can be evaluated efficiently on the verifier’s side (this is the ‘succinctly’ part), is of low degree.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.khanacademy.org/math/algebra-home/alg-polynomials"&gt;Polynomials&lt;/a&gt; are fundamental to understanding ZKPs given that we can present a polynomial with arguments that essentially verifies the computation. There are entire domains of study dedicated to explaining ZK math, such as the absolutely awesome &lt;a href="https://zkhack.dev/whiteboard/"&gt;ZK Hack Whiteboard Series&lt;/a&gt; which I highly recommend. This guide is purposefully light on this subject.&lt;/p&gt;

&lt;p&gt;In its most simplest form, the biggest change a developer needs to make is learning how to write traditional control structures as quadratic constraints. To borrow from Vitalik’s &lt;a href="https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649"&gt;example&lt;/a&gt;, we can see how this changes in arithmetic circuit programming.&lt;/p&gt;

&lt;p&gt;Traditional control structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if x &amp;lt; 5: y = 7; else: y = 9) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To Quadratic Control Structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = 7 * (x &amp;lt; 5) + 9 * (x &amp;gt;= 5);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key to understanding how to shift in thinking is by noting how the value of y changes in both statements depending on the value of x. This is the main difference in arithmetic circuit programming, well, this and understanding logic gates but if it still doesn’t make sense, don’t worry. In the next section, we delve into a Circom example that illustrates this difference even better.&lt;/p&gt;

&lt;p&gt;In the next section, we’ll get up and running with Circom and get you writing your first ZKP Dapp. I hope this theory section provides sufficient clarity about ZKPs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Further Reading
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://zkhack.dev/whiteboard/"&gt;ZK Hack Whiteboard Series&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649"&gt;Quadratic Arithmetic Programs: from Zero to Hero&lt;/a&gt;&lt;br&gt;
&lt;a href="https://arxiv.org/pdf/1906.07221.pdf"&gt;Why and How zk-SNARK Works: Definitive Explanation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>circom</category>
      <category>zeroknowledge</category>
      <category>zksnarks</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
