<?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: teddav</title>
    <description>The latest articles on Forem by teddav (@teddav).</description>
    <link>https://forem.com/teddav</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%2F1028797%2F55b4bac1-682e-4b67-8286-6455a36d24a6.jpeg</url>
      <title>Forem: teddav</title>
      <link>https://forem.com/teddav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/teddav"/>
    <language>en</language>
    <item>
      <title>From 0 to Bi(ge)nius: field extensions</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Fri, 14 Feb 2025 14:15:06 +0000</pubDate>
      <link>https://forem.com/teddav/from-0-to-bigenius-basic-maths-270p</link>
      <guid>https://forem.com/teddav/from-0-to-bigenius-basic-maths-270p</guid>
      <description>&lt;p&gt;We dive into “small field”, “field extension”, “binary field” and "field extension tower".&lt;/p&gt;

&lt;p&gt;Because this article contains a lot of LaTeX, for better rendering you'll find it here: &lt;a href="https://hackmd.io/@teddav/ry9wppnK1x" rel="noopener noreferrer"&gt;https://hackmd.io/@teddav/ry9wppnK1x&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tornado Cash with Halo2</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Fri, 09 Feb 2024 06:12:12 +0000</pubDate>
      <link>https://forem.com/teddav/tornado-cash-with-halo2-62b</link>
      <guid>https://forem.com/teddav/tornado-cash-with-halo2-62b</guid>
      <description>&lt;p&gt;tl; dr: You already heard of Tornado Cash? And Halo2? Great! Here we’re going to mix those 2 and re-write the Tornado Cash circuits from Circom to Halo2.&lt;br&gt;&lt;br&gt;
Here's the code: &lt;a href="https://github.com/teddav/tornado-halo2/" rel="noopener noreferrer"&gt;https://github.com/teddav/tornado-halo2/&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Ok, let’s have a bit of a better intro…&lt;/p&gt;

&lt;p&gt;“Zero Knowledge” is definitely a scary word (or 2 words)! When I started learning about it a few months ago I couldn’t understand anything 🤯&lt;/p&gt;

&lt;p&gt;Recently I started to learn about Halo2, and after reading a bit of code and &lt;a href="https://zcash.github.io/halo2/index.html" rel="noopener noreferrer"&gt;a few&lt;/a&gt;   &lt;a href="https://erroldrummond.gitbook.io/halo2-tutorial/" rel="noopener noreferrer"&gt;tutorials&lt;/a&gt; I tried to write my own circuit but was completely stuck: I had no idea how to do it...&lt;/p&gt;

&lt;p&gt;That’s why I decided to write this article: to learn how to write a circuit, and teach some other people at the same time. Hopefully you’ll learn something from it.&lt;/p&gt;

&lt;p&gt;This article may need to be corrected, or some things I’m saying might be completely wrong. If so: please message me so I can fix it (and improve myself at the same time 😄).&lt;/p&gt;

&lt;p&gt;Let’s review where I am when starting this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read a few Halo2 tutorials&lt;/li&gt;
&lt;li&gt;I think I understand what Chips and Circuits are, I have no idea what Layouter and Regions are for&lt;/li&gt;
&lt;li&gt;I don’t know how to write my own circuit&lt;/li&gt;
&lt;li&gt;I definitely don’t understand how things work “underneath”. Like how the proof is generated from the “halo2 board”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is “part 1”. We’re going to start easy with an implementation as simple as possible, and the next parts will improve on it. I haven’t written part 2 (or 3, or…) yet, so if you’re here a few weeks/months from now and they are not published, it means I gave up 🥲 so you’re allowed to send me a twitter message and tell me you’re disappointed.&lt;/p&gt;

&lt;p&gt;Here’s our plan for today:&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;i’ll give you a quick reminder on how tornado cash works&lt;/li&gt;
&lt;li&gt;what is halo2?&lt;/li&gt;
&lt;li&gt;how are we going to design our circuits&lt;/li&gt;
&lt;li&gt;
let’s code

&lt;ul&gt;
&lt;li&gt;Hash&lt;/li&gt;
&lt;li&gt;Merkle&lt;/li&gt;
&lt;li&gt;
Tornado circuit
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Tornado Cash core
&lt;/h2&gt;

&lt;p&gt;If you’re here, you probably already know what Tornado Cash is. If not → &lt;a href="https://letmegooglethat.com/?q=tornado+cash" rel="noopener noreferrer"&gt;What is Tornado Cash?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are going to rewrite the “original” Tornado. Not &lt;a href="https://github.com/tornadocash/tornado-nova" rel="noopener noreferrer"&gt;Tornado Nova&lt;/a&gt;. Nova is a newer version which is really interesting too but more complicated, so won’t look into it for now.&lt;/p&gt;

&lt;p&gt;This is the repo we’re going to look at: &lt;a href="https://github.com/tornadocash/tornado-core" rel="noopener noreferrer"&gt;Tornado core&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tornado has 2 parts: circuits and smart contracts. We’ll only focus on the circuits here (though we might take a quick peek at the contracts for general understanding).&lt;/p&gt;

&lt;p&gt;Circuits were written with &lt;a href="https://iden3.io/circom" rel="noopener noreferrer"&gt;Circom&lt;/a&gt; and that’s what we’re going to change. We’ll rewrite those circuits with &lt;a href="https://github.com/privacy-scaling-explorations/halo2" rel="noopener noreferrer"&gt;Halo2&lt;/a&gt;, the &lt;a href="https://pse.dev/" rel="noopener noreferrer"&gt;PSE&lt;/a&gt; implementation (the KZG one, i’ll tell you more about it in the next section).&lt;/p&gt;

&lt;p&gt;Ok thanks, but… how does it work? It’s actually really easy…&lt;/p&gt;
&lt;h3&gt;
  
  
  The “private” numbers
&lt;/h3&gt;

&lt;p&gt;Everything is secured by only 2 numbers called a &lt;code&gt;secret&lt;/code&gt; and a &lt;code&gt;nullifier&lt;/code&gt;. That’s it.&lt;/p&gt;

&lt;p&gt;Those 2 numbers alone are &lt;strong&gt;the only things keeping you from stealing the millions of ethers deposited in the tornado pools&lt;/strong&gt; 😱&lt;/p&gt;

&lt;p&gt;When you deposit money into Tornado, you need to generate a random secret and a random nullifier. Those numbers can go up to &lt;code&gt;21888242871839275222246405745257275088548364400416034343698204186575808495617&lt;/code&gt; (see &lt;a href="https://docs.circom.io/background/background/" rel="noopener noreferrer"&gt;here&lt;/a&gt; or &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/MerkleTreeWithHistory.sol#L20-L21" rel="noopener noreferrer"&gt;here&lt;/a&gt;)  Yes it’s a big number, it’s more than 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;22532^{253}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;253&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;p&gt;Keep those numbers written in a secured location, you’re going to need them when you want to withdraw your money.&lt;/p&gt;

&lt;p&gt;Tornado can be reduced to only 2 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;depositing&lt;/li&gt;
&lt;li&gt;withdrawing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s see them in more details.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deposit
&lt;/h3&gt;

&lt;p&gt;When you make a deposit, of course you have to send X ethers (depending on the pool) but you also have to &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/Tornado.sol#L55" rel="noopener noreferrer"&gt;send a &lt;code&gt;commitment&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This commitment is just a hash of the previous 2 numbers: &lt;code&gt;commitment = H(nullifier, secret)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tornado uses a merkle tree to &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/MerkleTreeWithHistory.sol#L68" rel="noopener noreferrer"&gt;store those commitments&lt;/a&gt;. Again, I’m sorry 🙏 but I’m too lazy to explain to you what a merkle tree is. If you don’t know → Google.&lt;/p&gt;

&lt;p&gt;A great way to see how it’s done is looking at the frontend/cli that was written by the Tornado devs. These are the tools most people used (still use?) to deposit money into Tornado.&lt;/p&gt;

&lt;p&gt;Here we have the &lt;a href="https://github.com/tornadocash/tornado-cli/blob/378ddf8b8b92a4924037d7b64a94dbfd5a7dd6e8/cli.js#L221" rel="noopener noreferrer"&gt;deposit() function&lt;/a&gt; of the cli, where the deposit is created&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deposit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createDeposit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rbigint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rbigint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the &lt;a href="https://github.com/tornadocash/tornado-cli/blob/378ddf8b8b92a4924037d7b64a94dbfd5a7dd6e8/cli.js#L164" rel="noopener noreferrer"&gt;createDeposit()&lt;/a&gt; where you can clearly see how the commitment is a hash of &lt;code&gt;nullifier + secret&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createDeposit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deposit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preimage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leInt2Buff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leInt2Buff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;
  &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commitment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pedersenHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preimage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commitmentHex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nullifierHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pedersenHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leInt2Buff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nullifierHex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nullifierHash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see how the random numbers are generated&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rbigint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nbytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;snarkjs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bigInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leBuff2int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nbytes&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbers are 31 bytes long, which means up to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;22482^{248}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;248&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, which is less than the max we saw earlier (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;22532^{253}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;253&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
). So we’re good!&lt;/p&gt;
&lt;h3&gt;
  
  
  Withdraw
&lt;/h3&gt;

&lt;p&gt;This is where it becomes interesting. How do we withdraw our money?!&lt;/p&gt;

&lt;p&gt;Obviously we’re going to use a zk proof:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to prove that we know the secret and the nullifier, but without revealing them&lt;/li&gt;
&lt;li&gt;to prove that our commitment is in the merkle tree&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Nullifier
&lt;/h4&gt;

&lt;p&gt;But what is the nullifier used for exactly?&lt;/p&gt;

&lt;p&gt;We need a way to ensure that a deposit is only withdrawn once. That’s what it’s for. When a withdrawal is made, the &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/Tornado.sol#L96" rel="noopener noreferrer"&gt;hash of the nullifier is stored in the contract&lt;/a&gt;, and therefore the commitment is “nullified”, &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/Tornado.sol#L86" rel="noopener noreferrer"&gt;it can’t be used again&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And why do we use the &lt;code&gt;nullifierHash&lt;/code&gt;: because we want to make sure the nullifier is always kept private, so we just disclose its hash as a public value. It’s just as unique, and there’s no way to reverse it.&lt;/p&gt;

&lt;p&gt;Let’s look at the &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/contracts/Tornado.sol#L76" rel="noopener noreferrer"&gt;withdraw() function&lt;/a&gt;. It takes as input the zk proof and the public inputs: root of the tree, nullifier hash, recipient, relayer, fee and refund.&lt;/p&gt;

&lt;p&gt;If we look at the &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/circuits/withdraw.circom#L30" rel="noopener noreferrer"&gt;Withdraw circuit&lt;/a&gt; you’ll see that these are the same public inputs. The private inputs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the secret&lt;/li&gt;
&lt;li&gt;the nullifier&lt;/li&gt;
&lt;li&gt;the merkle tree inputs, which are kept private so that we don’t know which leaf of the tree is being withdrawn&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  More details
&lt;/h3&gt;

&lt;p&gt;Wow… those explanations were longer than what I wanted to. At least now you should have a clear picture of how it works. I left out some features that are important but we’ll (maybe) come back to them when writing our own circuits.&lt;/p&gt;

&lt;p&gt;For now, if you want more details check those links:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/understanding-zero-knowledge-proofs-through-the-source-code-of-tornado-cash-41d335c5475f" rel="noopener noreferrer"&gt;Understanding Zero-Knowledge Proofs Through the Source Code of Tornado Cash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rareskills.io/post/how-does-tornado-cash-work" rel="noopener noreferrer"&gt;Rareskills - How Tornado Cash Works&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Halo2?
&lt;/h2&gt;

&lt;p&gt;Tornado zk circuits were written using Circom and the Groth16 proving system. You can look at the circuit compile scripts in &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/package.json#L7" rel="noopener noreferrer"&gt;package.json&lt;/a&gt; and at the &lt;a href="https://github.com/tornadocash/tornado-core/blob/1ef6a263ac6a0e476d063fcb269a9df65a1bd56a/src/cli.js#L172" rel="noopener noreferrer"&gt;generateProof&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;One of the main issues with Groth16 is that it requires a circuit-based trusted setup. Which is annoying, and reduces trust. Then &lt;strong&gt;Plonk&lt;/strong&gt; was created and allowed for a universal trusted setup. There are some limits, but basically: we do it once, and everybody can write circuits based on the same setup.&lt;/p&gt;

&lt;p&gt;That’s it, let’s keep the explanations to the minimum 😊&lt;/p&gt;

&lt;p&gt;Halo2 is a proving system &lt;a href="https://electriccoin.co/blog/explaining-halo-2/" rel="noopener noreferrer"&gt;created by Zcash&lt;/a&gt; based on top of Plonk and somehow makes it better/more efficient (I guess…). I’m not smart enough (yet 😉) to understand exactly why it’s so good, but some really smart people told me it’s good, so I’m just going to trust them.&lt;/p&gt;

&lt;p&gt;So… today we’re going to use Halo2 to rebuild Tornado Cash.&lt;/p&gt;

&lt;p&gt;As I said at the beginning, I’m actually writing this article as a way to learn Halo2. I have no idea how it works 😂 So I’m learning along the way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Circuit design
&lt;/h2&gt;

&lt;p&gt;As we just saw, the Tornado circuit is actually pretty simple. We only need 2 building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hashing&lt;/li&gt;
&lt;li&gt;merkle tree&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are what we call “chips” in Halo2, they are like classes, or the equivalent of &lt;code&gt;template&lt;/code&gt; in circom. You can reuse them when needed in other chips or circuits.&lt;/p&gt;

&lt;p&gt;Ok… before going any further I have something to disclose. A lot of the code that I’m going to show you next, I haven’t written it myself. Most of the Hash chip and the Merkle chip are “heavily inspired” (ok… mostly copied) from &lt;a href="https://github.com/summa-dev/halo2-experiments" rel="noopener noreferrer"&gt;https://github.com/summa-dev/halo2-experiments&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(which is itself “inspired” by &lt;a href="https://github.com/jtguibas/halo2-merkle-tree" rel="noopener noreferrer"&gt;https://github.com/jtguibas/halo2-merkle-tree&lt;/a&gt; 😁). So we can say thanks to &lt;a href="https://twitter.com/backaes" rel="noopener noreferrer"&gt;Enrico&lt;/a&gt;, &lt;a href="https://twitter.com/Sifnoc" rel="noopener noreferrer"&gt;Jin&lt;/a&gt; and &lt;a href="https://twitter.com/jtguibas" rel="noopener noreferrer"&gt;John&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But since I’m writing this long article to explain everything, I guess that makes up for it!&lt;/p&gt;
&lt;h3&gt;
  
  
  HashChip
&lt;/h3&gt;

&lt;p&gt;This chip takes 2 values and hashes them together.&lt;/p&gt;

&lt;p&gt;In this part1 we’re going to use a “fake” hash function, in order to make things simple. I’ll give you more details in the next part when we start coding.&lt;/p&gt;

&lt;p&gt;To be represented correctly in Halo2 we’re going to need 3 advice columns (our private values, the witness), 1 instance column (our public value, the resulting hash) and 1 selector. And we’ll use only 1 row.&lt;/p&gt;

&lt;p&gt;Let’s say we want to hash together the word “hello” and “tornado” and that the hash ends up being “thoerlnlaodo”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ferx9dy6ueqs1vy39vue5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ferx9dy6ueqs1vy39vue5.png" alt="hash chip columns" width="800" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s happening? The result of the hash is computed during proving (into “Advice 3”), but it was also passed by the prover as a public input in “Instance” (obviously the prover knows all the values, so he can compute the hash himself).  Then, the circuit applies a constraint on the values and make sure that &lt;code&gt;advice3 == instance&lt;/code&gt;. That’s how we prove that we know the 2 initial values (”hello” and “tornado”) which result in the hash “thoerlnlaodo”.&lt;/p&gt;

&lt;p&gt;In reality, strings don’t exist in circuits. Everything is a number.&lt;/p&gt;
&lt;h3&gt;
  
  
  MerkleChip
&lt;/h3&gt;

&lt;p&gt;Next we need a chip to compute/constrain our merkle tree. This chip is going to be a bit more complicated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2pc7l6svgg0l2232lk6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2pc7l6svgg0l2232lk6d.png" alt="merkle chip columns" width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We still have 3 advice columns but we need 2 rows this time.&lt;/p&gt;

&lt;p&gt;First row will take the hashes of the 2 nodes. Then the swap bit will tell us if the nodes are in the right order (left and right) or need to be swapped. On the next row, we have the nodes in the right order, so we only need to hash them. To get to the root of the tree, we just do that in a loop, and once we get to the root we compare it with the root passed as public input.&lt;/p&gt;
&lt;h3&gt;
  
  
  Circuits
&lt;/h3&gt;

&lt;p&gt;In the code you’re going to see a HashCircuit and a MerkleCircuit. These are not used for our Tornado circuit. They are just here to test and understand better how circuits work.&lt;/p&gt;

&lt;p&gt;The important part is our Tornado circuit. It’s going to take as private inputs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nullifier&lt;/li&gt;
&lt;li&gt;secret&lt;/li&gt;
&lt;li&gt;path elements&lt;/li&gt;
&lt;li&gt;path indices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The public inputs will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nullifier hash&lt;/li&gt;
&lt;li&gt;merkle root&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it, I think we’re ready to dive into the code!&lt;/p&gt;

&lt;p&gt;Just a quick summary of the relations in the circuit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fw3vbr7a3ylssdwvq44iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fw3vbr7a3ylssdwvq44iv.png" alt="circuit graph" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/teddav/tornado-halo2/tree/part1" rel="noopener noreferrer"&gt;Here’s the final code&lt;/a&gt;, so you can follow along and run it yourself.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hash
&lt;/h3&gt;

&lt;p&gt;As explained in the previous part, a Chip is like a class. There is a &lt;code&gt;Chip&lt;/code&gt; trait in &lt;code&gt;halo2_proofs::circuit&lt;/code&gt; but you don’t necessarily have to follow it, you can just write your chip the way you want it.&lt;/p&gt;

&lt;p&gt;Circuits are different. In order to generate your proof correctly, you’ll have to follow the &lt;/p&gt;

&lt;p&gt;&lt;code&gt;halo2_proofs::plonk::Circuit&lt;/code&gt; trait.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/chips/hash.rs" rel="noopener noreferrer"&gt;Our chip&lt;/a&gt; takes a “config” which means a description of the columns you’re going to use (see the table above).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HashConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Advice&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;hash_selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Our first gate
&lt;/h4&gt;

&lt;p&gt;Then we write our chip and the function &lt;code&gt;configure()&lt;/code&gt; that’s where we define our polynomial constraint.&lt;/p&gt;

&lt;p&gt;I’m still not sure what &lt;code&gt;enable_equality&lt;/code&gt; is for, but I think it enables you to setup copy constraints later in your circuit. Every example I saw of halo2 had that, so I just copied it. You’re right, it’s not that smart… 🤔 Remind me to come back to it in part 2 and give a better explanation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.create_gate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hash constraint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.query_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash_selector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.query_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nn"&gt;Rotation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.query_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nn"&gt;Rotation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.query_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nn"&gt;Rotation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;hash_result&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to understand this code, first I have to tell you how I cheated. Instead of writing an actual hash function, I wrote something really stupid. Our hash function takes 2 values and multiplies them to return a hash (remember that every value is a number). If I had to write it in python it would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, I promise in part 2 I’ll improve this. We’ll use the Poseidon hash and everything is going to look really nice 😎&lt;/p&gt;

&lt;p&gt;Let’s try to explain everything once, so it will be easier for the next gates.&lt;/p&gt;

&lt;p&gt;Currently our gate looks like this: &lt;code&gt;s * (a * b - hash_result) = 0&lt;/code&gt; which can be translated to: multiply &lt;code&gt;a&lt;/code&gt;  and &lt;code&gt;b&lt;/code&gt; and subtract &lt;code&gt;hash_result&lt;/code&gt; , if that equals 0 we’re good. Otherwise the &lt;code&gt;hash_result&lt;/code&gt;  is wrong. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;s&lt;/code&gt; is what we call a “selector”, it’s a boolean that’s going to activate or not the constraint. If it’s &lt;code&gt;0&lt;/code&gt; then the result is 0 so the constraint passes, and we don’t need to make sure &lt;code&gt;a*b = hash_result&lt;/code&gt;. If it’s &lt;code&gt;1&lt;/code&gt; then &lt;code&gt;a*b&lt;/code&gt; must equal &lt;code&gt;hash_result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to get values &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; we use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="nf"&gt;.query_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nn"&gt;Rotation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which means: get the first row (&lt;code&gt;Rotation::cur()&lt;/code&gt;) or the first advice column (&lt;code&gt;advice[0]&lt;/code&gt;). That’s how things always work in halo2: columns and rows. If you wanted to access previous or next rows you could have done &lt;code&gt;Rotation::prev()&lt;/code&gt; or &lt;code&gt;Rotation::next()&lt;/code&gt; for example.&lt;/p&gt;

&lt;h4&gt;
  
  
  Regions and Layouter
&lt;/h4&gt;

&lt;p&gt;Again, I’m going to tell you how I think of it. It might not be the best representation (but hopefully it’s not wrong…), but that’s how I understand Halo2 for now. For part 2, I’ll try to ask some other people to help me visualise it better and I’ll give you another perspective.&lt;/p&gt;

&lt;p&gt;Halo2 represents everything in a big table (like an Excel spreadsheet). You can use that table however you want, but it can quickly get messy (that’s why we have regions).&lt;/p&gt;

&lt;p&gt;Of course there is also a cost when generating the proof: each new column that you’re using is more expensive, while rows are cheaper. But remember that any new cell you’re using means more computing power.&lt;/p&gt;

&lt;p&gt;Going back to our Excel comparison, if you want to compute the sum of 5 numbers, you could write your 5 numbers in B5 to B9, and then write a “sum()” formula in C4. If you wanted to use the sum result somewhere else in the table, let’s say “F15”, so you’d just use a reference to cell C4.&lt;/p&gt;

&lt;p&gt;Halo2 works the same, you just assign values to cells, and then you reference them. To make things more efficient, everything has to be divided into regions, which are blocks of cells. So you define a new region, and in this region you automatically have access to the advice/instance columns that you pre-defined. You fill your cells and know that your constraints (that you added in &lt;code&gt;configure()&lt;/code&gt;) will be enforced.&lt;/p&gt;

&lt;p&gt;You can also add new constraints, and even constrain cells between regions! Wow that’s awesome 😍&lt;/p&gt;

&lt;p&gt;The layouter is just a helper to create regions. In the background it optimises how regions are created so that they don’t overlap, and so that the cost is as low as possible. When you want a new region, you ask the layouter for it &lt;code&gt;layouter.assign_region&lt;/code&gt; and then you can just use it without worrying about messing things up on the board.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hash it
&lt;/h4&gt;

&lt;p&gt;Now we can look at the &lt;code&gt;hash()&lt;/code&gt; function which is a bit more complicated.&lt;/p&gt;

&lt;p&gt;The function signature is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Layouter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;left_cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AssignedCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;right_cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AssignedCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AssignedCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;left&lt;/code&gt;  and &lt;code&gt;right&lt;/code&gt; could be values, and it would make the function a bit simpler. But being &lt;code&gt;AssignedCell&lt;/code&gt; makes the function more generic, and we can now use a ref to any cell on the board.&lt;/p&gt;

&lt;p&gt;First we assign a region&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.assign_region&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"hash row"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we copy the value in the left cell to our first advice column (first row)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;left_cell&lt;/span&gt;&lt;span class="nf"&gt;.copy_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"copy left input"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.config.advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;same for the right cell to second advice column and compute the hash in third advice column&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash_result_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="nf"&gt;.assign_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"output"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.config.advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;left_cell&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.cloned&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;right_cell&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.cloned&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we return a reference to the cell where the hash is computed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hash circuit
&lt;/h4&gt;

&lt;p&gt;Imagine that someone publicly revealed a hash &lt;code&gt;H&lt;/code&gt; and you want to prove that you know 2 values &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; that when hashed together will give &lt;code&gt;H&lt;/code&gt;. But of course you want to keep a and b private.&lt;/p&gt;

&lt;p&gt;For that, we look at &lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/circuits/hash.rs" rel="noopener noreferrer"&gt;the Hash circuit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It takes our 2 private inputs &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HashCircuit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And our public input is our hash &lt;code&gt;H&lt;/code&gt; = &lt;code&gt;a * b&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;public_inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;Fp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a circuit, the most interesting part happens in the &lt;code&gt;synthesize&lt;/code&gt; function. Since our &lt;code&gt;hash&lt;/code&gt; function takes cells as input, we’re going to create a temporary region that’s going to hold our &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; values, and then pass the cells to be hashed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.assign_region&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"private inputs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="nf"&gt;.assign_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"private input left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="nf"&gt;.assign_advice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"private input right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.advice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;chip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashChip&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash_result_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chip&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.namespace&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="s"&gt;"hasher"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the most important part is the last line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.constrain_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash_result_cell&lt;/span&gt;&lt;span class="nf"&gt;.cell&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s where we set our constraint. &lt;code&gt;instance&lt;/code&gt; is the column where our public inputs are. Here we make sure that the resulting hash which is in &lt;code&gt;hash_result_cell&lt;/code&gt; is equal to the hash &lt;code&gt;H&lt;/code&gt; we publicly displayed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merkle
&lt;/h3&gt;

&lt;p&gt;Now let’s go into the &lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/chips/merkle.rs#L24" rel="noopener noreferrer"&gt;MerkleChip&lt;/a&gt;. This should be faster since we already understood all the foundations.&lt;/p&gt;

&lt;p&gt;When we pass values to our &lt;code&gt;hash&lt;/code&gt; function, the order in which we pass &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; is important &lt;code&gt;H(a,b) != H(b,a)&lt;/code&gt;. Right now our current hash function is really dumb, so the order of the values &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; does not matter (we are just multiplying them). But when we will “upgrade” it and start using Poseidon it will matter.&lt;/p&gt;

&lt;p&gt;For our merkle tree we’ll pay attention to the order of the nodes (left/right). That’s why we need a &lt;code&gt;swap_bit&lt;/code&gt;: are the nodes in the correct order, or do they need to be swapped before being hashed? We also need 2 selectors to go with it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;swap_selector: check the swap bit → swap or not&lt;/li&gt;
&lt;li&gt;swap_bit_bool_selector: the swap bit should be a boolean, so this checks that the swap bit is &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Gates
&lt;/h4&gt;

&lt;p&gt;Our &lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/chips/merkle.rs#L46" rel="noopener noreferrer"&gt;first gate&lt;/a&gt; checks that the swap bit is 0 or 1. This can be re-written as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_zero_or_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/chips/merkle.rs#L55" rel="noopener noreferrer"&gt;second gate&lt;/a&gt; is more complex, but it’s not that complicated 😊 I’ll leave it to you to try to understand it. Just to make sure it’s clear:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;left[0]&lt;/code&gt; means left column, row 0&lt;/p&gt;

&lt;p&gt;&lt;code&gt;left[1]&lt;/code&gt; means left column, row 1&lt;/p&gt;

&lt;p&gt;And that’s what we’re checking&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;swap_bit&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s the actual constraint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;constraint1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;swap_bit&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;constraint2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;swap_bit&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Compute the merkle tree
&lt;/h4&gt;

&lt;p&gt;Now that our gates are in place, we need to compute the merkle tree root. In &lt;code&gt;merkle_prove_layer&lt;/code&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we assign our left and right nodes on row 0&lt;/li&gt;
&lt;li&gt;we check the swap bit&lt;/li&gt;
&lt;li&gt;on row 1 we assign left and right (in the correct order this time)&lt;/li&gt;
&lt;li&gt;we hash the nodes&lt;/li&gt;
&lt;li&gt;we return the cell where the hash result is&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;prove_tree_root&lt;/code&gt; we just loop over each layer until we reach the root.&lt;/p&gt;

&lt;p&gt;Again, there is a MerkleCircuit where you can see it in action.&lt;/p&gt;

&lt;p&gt;The most important part is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.constrain_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root_cell&lt;/span&gt;&lt;span class="nf"&gt;.cell&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s where we validate that the root we computed in the circuit is equal to the root we passed as a public input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tornado circuit
&lt;/h3&gt;

&lt;p&gt;And… finally! We arrive to our &lt;a href="https://github.com/teddav/tornado-halo2/blob/part1/src/main.rs" rel="noopener noreferrer"&gt;Tornado circuit&lt;/a&gt;. Here are the private inputs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TornadoCircuit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;nullifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;path_elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;path_indices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the public inputs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;public_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nullifier_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are not fully respecting the real &lt;a href="https://github.com/tornadocash/tornado-core/blob/master/circuits/withdraw.circom#L29" rel="noopener noreferrer"&gt;Tornado circuit&lt;/a&gt; which also takes as public input:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recipient&lt;/li&gt;
&lt;li&gt;relayer&lt;/li&gt;
&lt;li&gt;fee&lt;/li&gt;
&lt;li&gt;refund&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These values are definitely important in the zk proof and should be checked when verifying the proof, but these are useless for our current understanding of Halo2. So won’t bother using them.&lt;/p&gt;

&lt;p&gt;Here are the steps taken in the circuit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compute the nullifier hash&lt;/li&gt;
&lt;li&gt;check that it matches the public nullifier hash&lt;/li&gt;
&lt;li&gt;compute the merkle tree root&lt;/li&gt;
&lt;li&gt;check that it matches the public merkle root&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it. Really easy.&lt;/p&gt;

&lt;h4&gt;
  
  
  Range check (not)
&lt;/h4&gt;

&lt;p&gt;I haven’t set up any gate in the TornadoChip, which is a mistake because our circuit will be “under-constrained”.&lt;/p&gt;

&lt;p&gt;We should definitely range check our private inputs. Range check means checking that a value is within a certain range, so between a lower bound and an upper bound. But again, let’s keep that for “part 2”.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/tornadocash/tornado-core/blob/master/circuits/withdraw.circom#L14" rel="noopener noreferrer"&gt;range check in the original Tornado circuit&lt;/a&gt;: checking that &lt;code&gt;nullifier&lt;/code&gt; and &lt;code&gt;secret&lt;/code&gt; are less that 248 bits, which means less than 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;22482^{248}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;248&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;
&lt;h4&gt;
  
  
  Nullifier hash and commitment
&lt;/h4&gt;

&lt;p&gt;In the TornadoChip you’ll find a helper &lt;a href="https://github.com/teddav/tornado-halo2/blob/main/src/chips/tornado.rs#L54" rel="noopener noreferrer"&gt;compute_hash&lt;/a&gt; function. This makes the nullifier hash and the commitment easier to compute.&lt;/p&gt;

&lt;p&gt;This time everything should be easy to understand, so I’m not going to give too much explanations.&lt;/p&gt;

&lt;p&gt;Just a comment on the most important constraints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.constrain_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullifier_hash_cell&lt;/span&gt;&lt;span class="nf"&gt;.cell&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;layouter&lt;/span&gt;&lt;span class="nf"&gt;.constrain_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;merkle_root_cell&lt;/span&gt;&lt;span class="nf"&gt;.cell&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we make sure the nullifier hash matches the first row of our instance column (our public inputs), and then we also validate the merkle root against the second row.&lt;/p&gt;

&lt;p&gt;And just like that, we have our Halo2 Tornado Cash! 🥳🥳&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;I mentioned a lot “part 2” because I wanted to keep this first part as simple as possible. Here’s what we need to do to improve our circuit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use a real hash function → Poseidon&lt;/li&gt;
&lt;li&gt;range check the values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And to get a deeper understanding of Halo2, we could try to actually generate the proof, and generate the verifier solidity contract, so that we have a fully functioning Tornado Cash.&lt;/p&gt;

&lt;p&gt;I have no idea how to do that yet 😂&lt;/p&gt;

&lt;p&gt;PLEASE! If you have some ideas or advice, or if some parts of this article need to be improved → &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;send me a message&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>zk</category>
      <category>ethereum</category>
      <category>halo2</category>
      <category>zeroknowledge</category>
    </item>
    <item>
      <title>Foundry: add a cheatcode</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Tue, 04 Apr 2023 08:45:19 +0000</pubDate>
      <link>https://forem.com/teddav/foundry-add-a-cheatcode-5hc8</link>
      <guid>https://forem.com/teddav/foundry-add-a-cheatcode-5hc8</guid>
      <description>&lt;p&gt;We scratched the surface of &lt;a href="https://github.com/foundry-rs/foundry/" rel="noopener noreferrer"&gt;Foundry’s code&lt;/a&gt; in &lt;a href="https://dev.to/teddav/foundry-open-source-contribution-1k2d"&gt;part 1&lt;/a&gt;. Let’s go a bit deeper and try to create a new cheatcode this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we going to do?
&lt;/h2&gt;

&lt;p&gt;We’ll try to write a &lt;code&gt;getMemory(uint256 start, uint256 end)&lt;/code&gt; cheatcode. Which sounds pretty straightforward: get the current memory from index &lt;code&gt;start&lt;/code&gt; to &lt;code&gt;end&lt;/code&gt;. We’ll also add “bonus” cheatcodes that automatically format that memory, to easily be logged.&lt;/p&gt;

&lt;p&gt;You can find the PR (still in review at the time of publishing this article) &lt;a href="https://github.com/foundry-rs/foundry/pull/4664" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/teddav/foundry/commit/7277e7665a3b21d9df46eea0485a66508c4a5022" rel="noopener noreferrer"&gt;the commit I’m going to follow&lt;/a&gt; (in case the code changes before it’s merged).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this cheatcode?
&lt;/h2&gt;

&lt;p&gt;Memory is hard to get in Solidity. You can only get it in chunks of 32 bytes (with &lt;code&gt;mload&lt;/code&gt;), and sometimes it’s useful to have a better overview of the memory. That’s why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we continue, a little tip…&lt;/p&gt;

&lt;p&gt;Since my &lt;a href="https://rust-analyzer.github.io/" rel="noopener noreferrer"&gt;rust-analyzer&lt;/a&gt; config wasn’t using the &lt;code&gt;nightly&lt;/code&gt; flag, the code kept getting changed when I was saving files. I’m using VSCode and didn’t want to change my config for all my projects, so I added a &lt;code&gt;.vscode&lt;/code&gt; folder and a &lt;code&gt;settings.json&lt;/code&gt; with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rust-analyzer.rustfmt.extraArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"+nightly"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add a cheatcode
&lt;/h2&gt;

&lt;p&gt;First I modified the minimum to make sure I had the correct process. I followed the steps in &lt;a href="https://github.com/foundry-rs/foundry/blob/master/docs/dev/cheatcodes.md" rel="noopener noreferrer"&gt;Foundry’s doc&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add the function signature to the &lt;code&gt;abigen!&lt;/code&gt; macro so a new &lt;code&gt;HEVMCalls&lt;/code&gt; variant is generated&lt;/li&gt;
&lt;li&gt;implement the cheat code handler&lt;/li&gt;
&lt;li&gt;add a Solidity test for the cheatcode under &lt;code&gt;testdata/cheats&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;add the function signature to forge-std Vm interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I started by adding the function signature to &lt;code&gt;evm/src/executor/abi/mod.rs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bindings for cheatcodes&lt;/span&gt;
&lt;span class="nn"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;abigen!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;HEVM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;r#"[
            ...
            getMemory(uint256,uint256)
        ]"#&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;hevm&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;HEVMCalls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HEVM_ABI&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in &lt;code&gt;evm/src/executor/inspector/cheatcodes/util.rs&lt;/code&gt; in &lt;code&gt;apply&lt;/code&gt; function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Cheatcodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HEVMCalls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
            &lt;span class="nn"&gt;HEVMCalls&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;GetMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and our &lt;code&gt;get_memory&lt;/code&gt; function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"get_memory: {start} {end}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like in &lt;a href="https://dev.to/teddav/foundry-open-source-contribution-1k2d"&gt;part 1&lt;/a&gt;, I set up a project with a forge Test to test my changes in real time. In that project, as with any project using Foundry, you have a &lt;code&gt;lib&lt;/code&gt; directory with &lt;code&gt;forge-std&lt;/code&gt;. You’ll need to add your cheatcode there, so that it’s recognized by your test&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;my-project/lib/forge-std/src/Vm.sol&lt;/code&gt; we add the function signature&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getMemory(uint256 start, uint256 end) external;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And write our first test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity 0.8.18;
import "forge-std/Test.sol";

contract MemoryTest is Test {
    function testBasicLog() public {
        vm.getMemory(2, 5);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test passes, no errors, and we get our log printed to the console:&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;get_memory: 2, 5”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We are good to continue! 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s write our cheatcode
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Access the memory
&lt;/h3&gt;

&lt;p&gt;Cheatcodes are called in the &lt;code&gt;apply_cheatcode&lt;/code&gt; function in &lt;code&gt;evm/src/executor/inspector/cheatcodes/mod.rs&lt;/code&gt; which itself is called in the &lt;code&gt;call&lt;/code&gt; function in the same file. Those 2 functions are implementations of the &lt;code&gt;Cheatcodes&lt;/code&gt; struct.&lt;/p&gt;

&lt;p&gt;Unfortunately we cannot access the memory directly from the cheatcode. The parameters of the &lt;code&gt;call&lt;/code&gt; function are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;CallInputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;is_static&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Gas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the memory is only accessible from the &lt;code&gt;Interpreter&lt;/code&gt;, which is a parameter of &lt;code&gt;step&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Interpreter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we’ll have to store the memory somewhere for it to be accessible in our cheatcode. I decided to add a &lt;code&gt;memory&lt;/code&gt; field on the &lt;code&gt;Cheatcodes&lt;/code&gt; struct&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Cheatcodes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="cd"&gt;/// Current's call memory&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And copy the memory to it in &lt;code&gt;fn step()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Interpreter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interpreter&lt;/span&gt;&lt;span class="py"&gt;.memory&lt;/span&gt;&lt;span class="nf"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now access the memory from our &lt;code&gt;fn get_memory()&lt;/code&gt; function!&lt;/p&gt;

&lt;h3&gt;
  
  
  Return our memory slice
&lt;/h3&gt;

&lt;p&gt;Now that we have access to the memory the rest is easy. We get the requested part from it and return it. The parameters of our &lt;code&gt;getMemory(uint256,uint256)&lt;/code&gt; function are passed as &lt;code&gt;U256&lt;/code&gt;. We just convert them to &lt;code&gt;usize&lt;/code&gt;, get our memory slice and return it as &lt;code&gt;Bytes&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;HEVMCalls&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;GetMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_usize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_usize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="py"&gt;.memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To help us with the &lt;code&gt;Bytes&lt;/code&gt; encoding, &lt;code&gt;ethers-rs&lt;/code&gt; has an &lt;code&gt;encode()&lt;/code&gt; function where you pass a Vector of &lt;code&gt;Token&lt;/code&gt; and it formats the data properly.&lt;/p&gt;

&lt;p&gt;The actual code I wrote was a bit longer because I added some error handling and some extra cheatcodes, but if we just wanted to implement the &lt;code&gt;getMemory&lt;/code&gt; cheatcode, we would be done.&lt;/p&gt;

&lt;p&gt;I’ll give some more details at the end of the article. For now let’s finish our “simple” cheatcode with unit tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit tests
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;testdata/cheats&lt;/code&gt; we first add the function signature for our cheatcode to &lt;code&gt;Cheats.sol&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we can create a new test file &lt;code&gt;GetMemory.t.sol&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How are tests run?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was trying to understand how tests are run when executing &lt;code&gt;cargo test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From what I understood, what matters to us is in &lt;code&gt;forge/tests/it/cheats.rs&lt;/code&gt;. You can see the test that is going to test all cheatcodes: &lt;code&gt;test_cheats_local&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Something a bit annoying when running tests: it logs info for all the tests that should be run, not only the only running. So you have to search through the logs to find your test. If anyone knows how to avoid that, please message me 🙏&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nb"&gt;test &lt;/span&gt;test_cheats_local &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--show-output&lt;/span&gt;
or
&lt;span class="nv"&gt;$ &lt;/span&gt;cargo watch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="s2"&gt;"test test_cheats_local -- --show-output"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Our test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is what &lt;code&gt;GetMemory.t.sol&lt;/code&gt; looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: Unlicense
pragma solidity &amp;gt;=0.8.0;

import "ds-test/test.sol";
import "./Cheats.sol";

contract GetMemoryTest is DSTest {
    Cheats constant vm = Cheats(HEVM_ADDRESS);

    function testGetMemory() public {
        assertEq(vm.getMemory(0, 31), abi.encodePacked(bytes32(0)));

        assembly {
            mstore(0, 0x4141414141414141414141414141414141414141414141414141414141414141)
            mstore(0x20, 0xbabababababababababababababababababababababababababababababababa)
        }
        bytes memory mem1 = vm.getMemory(0, 12);
        bytes memory mem2 = vm.getMemory(0x20, 0x3f);

        assertEq(mem1.length, 13);
        assertEq(mem2.length, 32);

        assertEq(mem1, hex"41414141414141414141414141");
        assertEq(mem2, hex"babababababababababababababababababababababababababababababababa");

        bytes memory mem3 = vm.getMemory(0x60, 0x7f);
        assertEq(mem3.length, 32);
        assertEq(mem3, abi.encodePacked(bytes32(0)));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done! 🎉 If you wanted to implement your own cheatcode you would be done since everything is working as expected. But before I sent it to review I decided to add a little extra work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;error handling&lt;/li&gt;
&lt;li&gt;“bonus” cheatcodes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overtime
&lt;/h2&gt;

&lt;p&gt;The goal of the cheatcode is to make it easy to inspect the memory. Receiving the entire memory as bytes is already helpful, but why not format it as a nice string with indexes? So I added a &lt;code&gt;getMemoryFormattedAsString&lt;/code&gt; and &lt;code&gt;getMemoryFormatted&lt;/code&gt; cheatcodes. The first one returns a long string ready to be printed with &lt;code&gt;console.log&lt;/code&gt;, and the second one returns a &lt;code&gt;FormattedMemory&lt;/code&gt; struct, so you have a bit more control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct FormattedMemory {
    string header;
    string[] words;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might be useless, I don’t know… we’ll see if people end up using those or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error handling
&lt;/h3&gt;

&lt;p&gt;I had a hard time understanding how to return errors properly from the cheatcode. I struggled a bit with the &lt;code&gt;Bytes&lt;/code&gt; formatting and the fact that &lt;code&gt;apply()&lt;/code&gt; in utils is supposed to return &lt;code&gt;Option&amp;lt;Result&amp;lt;Bytes, Bytes&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When running my tests I would get &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cheatcode was unhandled. This is a bug.&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;or &lt;code&gt;The application panicked (crashed). This is a bug. Consider reporting it at https://github.com/foundry-rs/foundry&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To make it easier, I created a &lt;code&gt;check_format_memory_inputs&lt;/code&gt;. Annoyingly, I couldn’t figure out how to have a nice error handling using &lt;code&gt;?&lt;/code&gt; so I add to use a &lt;code&gt;match&lt;/code&gt; statement to propagate the error correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;HEVMCalls&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;GetMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;check_format_memory_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="py"&gt;.memory&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="py"&gt;.memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error getMemory: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;check_format_memory_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;memory_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;try_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"start parameter: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;try_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"end parameter: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalid parameters: start ({}) must be &amp;lt;= end ({})"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory_length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"invalid parameters: end ({}). Max memory offset: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;memory_length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Future improvements
&lt;/h2&gt;

&lt;p&gt;You can see the entire implementation after which this article was written in &lt;a href="https://github.com/teddav/foundry/commit/7277e7665a3b21d9df46eea0485a66508c4a5022" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This cheatcode was meant to be a first “dirty” version. It’s not ideal because it modifies the same memory you’re trying to inspect. The memory is modified 3 times:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when calling the cheatcode (to store the arguments of the call)&lt;/li&gt;
&lt;li&gt;when returning: the string or bytes are added to memory&lt;/li&gt;
&lt;li&gt;when using &lt;code&gt;console.log&lt;/code&gt; again it needs to add the data to memory before logging it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ideally we would want to log directly the memory without modifying it. I’ll try to prepare a 2nd version soon! Why not write another article about it to close this series. We’ll see…&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn!
&lt;/h2&gt;

&lt;p&gt;Now that you finished this article, it’s your turn to think of a useful cheatcode and implement it. If it’s useful for you, it might be useful for others. You can go ask beforehand on the &lt;a href="https://t.me/foundry_rs" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt; if anyone is interested.&lt;/p&gt;

&lt;p&gt;Follow me on Twitter: &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;0xteddav&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can message me there if you have any question, or if I made a mistake somewhere.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>solidity</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Solving the Ethernaut with Yul</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Sat, 04 Mar 2023 11:23:46 +0000</pubDate>
      <link>https://forem.com/teddav/solving-the-ethernaut-with-yul-2a4h</link>
      <guid>https://forem.com/teddav/solving-the-ethernaut-with-yul-2a4h</guid>
      <description>&lt;p&gt;After learning the basics of Solidity assembly in &lt;a href="https://dev.to/teddav/playing-with-yul-assembly-1i5h"&gt;Part 1: Playing with Yul&lt;/a&gt; let’s now dive deeper! 💪&lt;/p&gt;

&lt;p&gt;We’re going to solve the &lt;a href="https://ethernaut.openzeppelin.com/" rel="noopener noreferrer"&gt;Ethernaut challenges&lt;/a&gt;, written by Openzeppelin, entirely in assembly. We’ll use some more advanced assembly and also learn about Ethereum security exploits. On top of that we’ll use &lt;a href="https://github.com/foundry-rs/foundry/" rel="noopener noreferrer"&gt;Foundry&lt;/a&gt;, built by Paradigm, to run our scripts, tests, and deploy to Goerli testnet.&lt;/p&gt;

&lt;p&gt;Hopefully you’ll learn a lot going through this article!&lt;/p&gt;

&lt;p&gt;The idea is that you should try the challenges yourself, one by one, and after each challenge go checkout my repo to understand the Yul version. You’ll see that throughout the challenges, the same assembly techniques are used over and over so it might be a bit boring after a while.&lt;/p&gt;

&lt;p&gt;This article is not meant to be read alone. I just wrote here some explanations of the code for some difficult parts. So your first step should be to go to my &lt;a href="https://github.com/teddav/ethernaut-yul" rel="noopener noreferrer"&gt;Ethernaut-yul repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will not give detailed explanations on how to solve each challenge. Most challenges are pretty basic, and you’ll find a lot of explanations if you search online. This tutorial is mostly focused on Assembly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.evm.codes/" rel="noopener noreferrer"&gt;evm.codes&lt;/a&gt; is a great website if you don’t understand what some opcodes do.&lt;/p&gt;

&lt;p&gt;Just like with Part 1, if you have any questions, or issues understanding what I wrote, or if you just wanna chat → message me on &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;Twitter 0xteddav&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First: setup the repo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/teddav/ethernaut-yul" rel="noopener noreferrer"&gt;This repo&lt;/a&gt; is a mix of &lt;a href="https://github.com/foundry-rs/foundry/" rel="noopener noreferrer"&gt;Foundry&lt;/a&gt; and &lt;a href="https://hardhat.org/" rel="noopener noreferrer"&gt;Hardhat&lt;/a&gt;, so it can also be a good boilerplate for your future projects (you’re welcome 😁).&lt;/p&gt;

&lt;p&gt;Install Foundry: &lt;a href="https://github.com/foundry-rs/foundry/#installation" rel="noopener noreferrer"&gt;https://github.com/foundry-rs/foundry/#installation&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Then run &lt;code&gt;yarn&lt;/code&gt; to install the dependencies in package.json&lt;/p&gt;

&lt;p&gt;And copy &lt;code&gt;.env.tmpl&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; and enter the correct values for your private key and the RPC you’re going to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Levels
&lt;/h2&gt;

&lt;p&gt;Each level is solved by a &lt;code&gt;forge script&lt;/code&gt;. You’ll find all scripts in &lt;code&gt;script/foundry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You’ll find a template in &lt;code&gt;Level.s.sol&lt;/code&gt; that you can copy/paste. You’ll just need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;specify the address of the level&lt;/li&gt;
&lt;li&gt;the network you’re playing on (either “local” or “goerli”)&lt;/li&gt;
&lt;li&gt;change the interface of the level you’re playing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re running the levels locally, you have to run anvil (or hardhat node) as fork of Goerli&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;anvil &lt;span class="nt"&gt;-f&lt;/span&gt; https://rpc.ankr.com/eth_goerli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can run the script with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;forge script ./script/foundry/XX_LevelName.s.sol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you’re ready to actually send the transactions on-chain, you “execute” the broadcast by adding &lt;code&gt;—-broadcast&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;forge script ./script/foundry/XX_LevelName.s.sol &lt;span class="nt"&gt;--broadcast&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each script has a &lt;code&gt;baseVersion()&lt;/code&gt; where the level is solved with Solidity, and the same code is re-written in Yul in the &lt;code&gt;yulVersion()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;When a contract needs to be deployed, I usually wrote the Solidity version, commented it out and re-wrote the Yul version underneath.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;test&lt;/code&gt; directory you’ll find some forge tests I wrote while working on some levels, so sometimes you can see what my thinking process was. You can run those tests with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;forge &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-vvvvv&lt;/span&gt; &lt;span class="nt"&gt;--mt&lt;/span&gt; testNameOfTheTest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s now detail how I solved some of the levels!&lt;/p&gt;

&lt;h3&gt;
  
  
  HelloEthernaut
&lt;/h3&gt;

&lt;p&gt;Didn’t use Yul for this level as it was just used to setup everything. I might come back to it if anyone is interested. It could be fun to parse the string response in assembly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fallback
&lt;/h3&gt;

&lt;p&gt;Let’s start with the basics. We need to call &lt;code&gt;contribute()&lt;/code&gt; with a value of &lt;code&gt;1&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let dest := sload(instance.slot)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We load the address of the instance which is in the &lt;code&gt;instance&lt;/code&gt; variable. We could figure out the storage slot of &lt;code&gt;instance&lt;/code&gt; ourselves (you’ll have to go down the chain of the parent contracts we are inheriting from, which is annoying…), but in Yul we can easily get that value with &lt;code&gt;.slot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s detail how we call an external function with Yul. We’ll use that same pattern a lot throughout the challenges&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(0, "contribute()")
mstore(0, keccak256(0, 12))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To call a function we need its “selector”. You can read more about it in the &lt;a href="https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector" rel="noopener noreferrer"&gt;Solidity doc&lt;/a&gt;. In Solidity we would do: &lt;code&gt;bytes4(keccak256(abi.encodePacked("contribute()")))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;First we store in memory at &lt;code&gt;0&lt;/code&gt; the signature of the function we want to call: &lt;code&gt;contribute()&lt;/code&gt;(notice that the length is &lt;code&gt;12&lt;/code&gt;). Our memory looks like this&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0x00&lt;/th&gt;
&lt;th&gt;0x636f6e7472696275746528290000000000000000000000000000000000000000&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x20&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000080&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(if you don’t understand what “636f6e747269627574652829” is, lookup “string to hexadecimal” on Google 😁)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then we hash that signature with &lt;code&gt;keccak256(0, 12)&lt;/code&gt; and store the result at &lt;code&gt;0&lt;/code&gt; in memory. This will overwrite the previous value, but we don’t care because we won’t need it anymore. Our memory is now&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0x00&lt;/th&gt;
&lt;th&gt;0xd7bb99ba2c5adddd21e5297f8f4a22a22e4de232bc63ec1e2ec542e79805202e&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x20&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000080&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The function selector for &lt;code&gt;contribute()&lt;/code&gt; will be the first 4 bytes of that: &lt;code&gt;0xd7bb99ba&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we execute our &lt;code&gt;call&lt;/code&gt;. Go check &lt;a href="https://www.evm.codes/#f1" rel="noopener noreferrer"&gt;evm.codes&lt;/a&gt; for details on the parameters of the CALL opcode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let success := call(gas(), dest, 1, 0, 4, 0, 0)
if iszero(success) {
    revert(0, 0)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dest&lt;/code&gt; is the address of the contract we’re calling. We pass it a value of &lt;code&gt;1&lt;/code&gt;, then we tell it to get the data from memory starting at &lt;code&gt;0&lt;/code&gt; up until &lt;code&gt;4&lt;/code&gt; (our function selector), and then we don’t expect a return value so we pass &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt;. &lt;code&gt;success&lt;/code&gt; will be either 0 or 1 depending on the result of the call. So we check with &lt;code&gt;iszero&lt;/code&gt; and if the call failed, we revert.&lt;/p&gt;

&lt;p&gt;We just made our first external call. That was easy! 🎉&lt;/p&gt;

&lt;p&gt;Let’s do another example: a &lt;code&gt;view&lt;/code&gt; call. Further down the code you’ll find&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(0, "owner()")
mstore(0, keccak256(0, 7))
success := staticcall(gas(), dest, 0, 4, 0, 0x20)
if iszero(success) {
    revert(0, 0)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we call &lt;code&gt;owner()&lt;/code&gt; on the instance, but this time we expect a result. The result will be stored in memory at &lt;code&gt;0&lt;/code&gt; and will be 32 bytes long (&lt;code&gt;0x20&lt;/code&gt;). We use &lt;code&gt;staticcall&lt;/code&gt; because this is a &lt;code&gt;view&lt;/code&gt; function and will not modify the state. More details… &lt;a href="https://docs.soliditylang.org/en/v0.8.19/contracts.html#view-functions" rel="noopener noreferrer"&gt;in the doc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then we load the returned value and check if it matches our &lt;code&gt;player&lt;/code&gt;. Otherwise we revert&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let owner := mload(0)
if iszero(eq(owner, sload(player.slot))) {
    revert(0, 0)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CoinFlip
&lt;/h3&gt;

&lt;p&gt;This level couldn’t be solved with a Foundry script because each call to &lt;code&gt;exploit()&lt;/code&gt; needs to be sent in a separate transaction. So you’ll find the solver in a Hardhat script in &lt;code&gt;script/hardhat/3_CoinFlip.ts&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Telephone
&lt;/h3&gt;

&lt;p&gt;This level introduces a new pattern: deploying a contract.&lt;/p&gt;

&lt;p&gt;You need to understand the difference between “creation code” (or “init code”) and “runtime code”. You can find explanations &lt;a href="https://docs.soliditylang.org/en/v0.8.19/units-and-global-variables.html#type-information" rel="noopener noreferrer"&gt;in the doc&lt;/a&gt; or &lt;a href="https://leftasexercise.com/2021/09/05/a-deep-dive-into-solidity-contract-creation-and-the-init-code/" rel="noopener noreferrer"&gt;in this article&lt;/a&gt;, or on &lt;a href="https://ethereum.stackexchange.com/questions/76334/what-is-the-difference-between-bytecode-init-code-deployed-bytecode-creation" rel="noopener noreferrer"&gt;Stackoverflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We want to deploy our &lt;code&gt;TelephoneExploit&lt;/code&gt; contract. The contructor takes 1 argument &lt;code&gt;address _telephone&lt;/code&gt;. The steps are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store the init code in memory&lt;/li&gt;
&lt;li&gt;add the constructor parameter&lt;/li&gt;
&lt;li&gt;call CREATE opcode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can only access the creation code in Solidity. So we’ll have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytes memory creationCode = type(TelephoneExploit).creationCode;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes everything easier for us because it automatically stores the code to memory. You should remember how &lt;code&gt;bytes&lt;/code&gt; are stored in memory. Let’s assume that there is nothing else in memory (which should be the case since there is no other instruction), so our memory should start at &lt;code&gt;0x80&lt;/code&gt;. Here’s what it should look like&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0x80&lt;/th&gt;
&lt;th&gt;size of the code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0xa0&lt;/td&gt;
&lt;td&gt;the code of TelephoneExploit…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xc0&lt;/td&gt;
&lt;td&gt;the code of TelephoneExploit…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xe0&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since &lt;code&gt;creationCode&lt;/code&gt; is the address in memory where the data starts. Since we assumed that the data was stored at &lt;code&gt;0x80&lt;/code&gt; we would have &lt;code&gt;creationCode == 0x80&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;if we do &lt;code&gt;mload(creationCode)&lt;/code&gt; (which is equal to &lt;code&gt;mload(0x80)&lt;/code&gt;) this will return the size of the TelephoneExploit contract. Then the actual code starts 32 bytes later so we do &lt;code&gt;add(creationCode, 0x20)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let contractSize := mload(creationCode)
let contractOffset := add(creationCode, 0x20)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just need to store the constructor argument. This is stored at the end of the contract code. Since we know the size of the contract, we just add it to the start of the contract’s code. The address for &lt;code&gt;_telephone&lt;/code&gt; should be the address of &lt;code&gt;instance&lt;/code&gt; so we use &lt;code&gt;sload(instance.slot)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let offsetConstructorArg := add(contractOffset, contractSize)
mstore(offsetConstructorArg, sload(instance.slot))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we just have to use CREATE and our contract is deployed! 🎉&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let telephoneExploit := create(0, contractOffset, mload(creationCode))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also noticed the &lt;code&gt;getOwner()&lt;/code&gt; function. Our first function in Yul. Pretty cool!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getOwner(_contract) -&amp;gt; _owner {
    mstore(0, "owner()")
    mstore(0, keccak256(0, 7))
    let success := staticcall(gas(), _contract, 0, 4, 0, 0x20)
    if iszero(success) {
        revert(0, 0)
    }
    _owner := mload(0)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Unfortunately, Yul functions are only usable in the same &lt;code&gt;assembly&lt;/code&gt; block they were defined in.&lt;/strong&gt; So we’ll not be using them too much because we will have to re-write them anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token
&lt;/h3&gt;

&lt;p&gt;Let’s see how we can call a function with a parameter, and get a result back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(0, "balanceOf(address)")
mstore(0, keccak256(0, 18))
mstore(0x4, sload(player.slot))
pop(staticcall(gas(), token, 0, 0x24, 0, 0x20))
let startBalance := mload(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you’ve seen before: we get the selector for &lt;code&gt;balanceOf(address)&lt;/code&gt; but this time we are going to add an argument. We do &lt;code&gt;mstore(0x4, sload(player.slot))&lt;/code&gt;. We store the address of the player at offset &lt;code&gt;4&lt;/code&gt;. Therefore, the first 4 bytes will the function selector, and the next 32 bytes will represent the address. For example let’s say the address is 0x7c019b7834722f69771cd4e821afc8e717baaab5&lt;/p&gt;

&lt;p&gt;The data will be: &lt;code&gt;0x70a082310000000000000000000000007c019b7834722f69771cd4e821afc8e717baaab5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And its length is 36 bytes (&lt;code&gt;0x24&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Notice that we use &lt;code&gt;pop&lt;/code&gt; because we don’t want to check if the call succeeded or not. If it didn’t succeed, the transaction will revert anyway at some point and we’ll fail the challenge. But in production you should always check if the call succeeded or not!&lt;/p&gt;

&lt;h3&gt;
  
  
  King
&lt;/h3&gt;

&lt;p&gt;Let’s try something new: revert with a string. Check &lt;code&gt;contracts/9_King.sol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You’ll find &lt;a href="https://docs.soliditylang.org/en/v0.8.18/control-structures.html#revert" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://blog.soliditylang.org/2021/04/21/custom-errors/" rel="noopener noreferrer"&gt;here&lt;/a&gt; explanations on how errors work in Solidity. Just like functions, errors have selectors too. The selector for an error string is &lt;code&gt;Error(string)&lt;/code&gt;. So we’ll need to have it, store it in memory and then store our string. Easy!&lt;/p&gt;

&lt;p&gt;Store the selector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(ptr, "Error(string)")
mstore(ptr, keccak256(ptr, 13))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store the string&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(add(ptr, 4), 0x20)
mstore(add(add(ptr, 4), 0x20), 9)
mstore(add(add(ptr, 4), 0x40), "not owner")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember how string are handled by the EVM (just like &lt;code&gt;bytes&lt;/code&gt;): first the offset, then the length of the string and finally the string itself. And then we revert with the data we just stored: &lt;code&gt;revert(ptr, 0x64)&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reentrancy
&lt;/h3&gt;

&lt;p&gt;I’m not going to do too much explanation, as it’s the same process as before, but here just notice that we have to store more than 1 parameters for the &lt;code&gt;exploit()&lt;/code&gt; function. If we tried to store them at memory &lt;code&gt;0&lt;/code&gt; we would overwrite the free memory pointer at 0x40 which will lead to dangerous behaviour and probably fail our transaction. So instead we store our data in memory where we have space available → where the free memory pointer points us to.&lt;/p&gt;

&lt;p&gt;Note that in the previous level (King), when we stored our error string, we did overwrite the free memory pointer. But we didn’t care since we stopped the execution and reverted right after.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;In this level we need a &lt;code&gt;bytes16&lt;/code&gt; but you know that values are stored on 32 bytes in the EVM so we need a bitmask to erase some of the bytes. &lt;code&gt;bytes&lt;/code&gt; are &lt;a href="https://docs.soliditylang.org/en/v0.8.19/internals/layout_in_storage.html#bytes-and-string" rel="noopener noreferrer"&gt;stored in the higher-order bytes&lt;/a&gt; (left aligned). So if we want the first 16 bytes we need to create a mask that looks like this &lt;code&gt;0xffffffffffffffffffffffffffffffff00000000000000000000000000000000&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let mask := shl(128, sub(exp(2, 128), 1))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is &lt;code&gt;2**128 - 1 &amp;lt;&amp;lt; 128&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we just need to apply our mask: &lt;code&gt;let key := and(data2, mask)&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Preservation
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;contracts/16_Preservation.sol&lt;/code&gt; we have a bitmask for an address. An address in Ethereum is 20 bytes (160 bits) so our mask will be &lt;code&gt;2 ** 160 - 1&lt;/code&gt; → &lt;code&gt;sub(exp(2, 160), 1)&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Recovery
&lt;/h3&gt;

&lt;p&gt;We compute the address where the contract will be deployed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), address(instance), nonce)))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll find some explanations on this &lt;a href="https://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://ethereum.stackexchange.com/questions/24248/how-to-calculate-an-ethereum-contracts-address-during-its-creation-using-the-so" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Foundry there is a convenient cheatcode for that: &lt;a href="https://book.getfoundry.sh/reference/forge-std/compute-create-address#computecreateaddress" rel="noopener noreferrer"&gt;computeCreateAddress&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MagicNumber
&lt;/h3&gt;

&lt;p&gt;Here you can clearly see the difference between creation code and runtime code that we talked about previously. The runtime code is the code that will be returned by the constructor of the contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(bytes memory bytecode) {
    assembly {
        return(add(bytecode, 0x20), mload(bytecode))
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pass in &lt;code&gt;bytecode&lt;/code&gt; what we eventually want the runtime code to be, and we just need to return it from the constructor. Our runtime code will be &lt;code&gt;602a60005260206000f3&lt;/code&gt; which is translated to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PUSH1 42
PUSH1 0
MSTORE
PUSH1 32
PUSH1 0
RETURN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Puzzle Wallet
&lt;/h3&gt;

&lt;p&gt;Wow! This one is a bit more advanced. More external calls than usual, and a lot of bytes encoding 😱 So i’ll try to give you some explanations.&lt;/p&gt;

&lt;p&gt;Let's think about what we want to encode:&lt;/p&gt;

&lt;p&gt;→ call &lt;code&gt;multicall(bytes[])&lt;/code&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a call to &lt;code&gt;deposit()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;another call to &lt;code&gt;multicall(bytes[])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;a subcall to &lt;code&gt;deposit()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;So what is our call data going to look like?&lt;/p&gt;

&lt;p&gt;In Solidity, bytes are encoded in three parts in calldata:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An offset where the length of the bytes can be found.&lt;/li&gt;
&lt;li&gt;At the offset specified in step 1, the length of the bytes is stored.&lt;/li&gt;
&lt;li&gt;Then, to the offset from step 1, we add 0x20 and that’s where the actual bytes are stored.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This encoding is used to allow the EVM to efficiently read the length of the bytes being passed as arguments in a function call, without needing to parse the entire data.&lt;/p&gt;

&lt;p&gt;A quick example as a reminder?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myFunction(uint256 myUint, bytes memory myBytes, uint256 myOtherUint) public {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say we want to call this function with the following values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;myUint&lt;/code&gt;: &lt;code&gt;123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;myBytes&lt;/code&gt;: &lt;code&gt;0xabcdef&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;myOtherUint&lt;/code&gt;: &lt;code&gt;456&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how the calldata would be encoded:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The function selector: &lt;code&gt;bytes4(keccak256(abi.encodePacked("myFunction(uint256,bytes,uint256)")))&lt;/code&gt; → &lt;code&gt;0xe329087e&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The first parameter (&lt;code&gt;myUint&lt;/code&gt;): &lt;code&gt;000000000000000000000000000000000000000000000000000000000000007b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The second parameter (&lt;code&gt;myBytes&lt;/code&gt;):

&lt;ol&gt;
&lt;li&gt;The offset where we'll find the length: &lt;code&gt;0000000000000000000000000000000000000000000000000000000000000060&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;At that offset, the length of the bytes: &lt;code&gt;0000000000000000000000000000000000000000000000000000000000000003&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;At offset + 0x20, the actual bytes: &lt;code&gt;abcdef0000000000000000000000000000000000000000000000000000000000&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;The third parameter (&lt;code&gt;myOtherUint&lt;/code&gt;): &lt;code&gt;00000000000000000000000000000000000000000000000000000000000001c8&lt;/code&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Putting it all together, the resulting calldata would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xe329087e
000000000000000000000000000000000000000000000000000000000000007b
0000000000000000000000000000000000000000000000000000000000000060
00000000000000000000000000000000000000000000000000000000000001c8
0000000000000000000000000000000000000000000000000000000000000003
abcdef0000000000000000000000000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to the more complex stuff: our &lt;code&gt;multicall(bytes[])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s start with the first &lt;code&gt;deposit()&lt;/code&gt; call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function multicall(bytes[] calldata data) external {}
function deposit() external {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function selector for &lt;code&gt;multicall(bytes[])&lt;/code&gt;: &lt;code&gt;bytes4(keccak256(abi.encodePacked("multicall(bytes[])")))&lt;/code&gt; → &lt;code&gt;0xac9650d8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The function selector for &lt;code&gt;deposit()&lt;/code&gt;: &lt;code&gt;bytes4(keccak256(abi.encodePacked("deposit()")))&lt;/code&gt; → &lt;code&gt;0xd0e30db0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For arrays, calldata encoding is similar to &lt;code&gt;bytes&lt;/code&gt; except we first need to store the length of the array. So our calldata will look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function selector&lt;/li&gt;
&lt;li&gt;offset where we'll find the length of the array&lt;/li&gt;
&lt;li&gt;length of array&lt;/li&gt;
&lt;li&gt;list of offsets where the data will be found for each element&lt;/li&gt;
&lt;li&gt;data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our &lt;code&gt;multicall(bytes[])&lt;/code&gt; with &lt;code&gt;deposit()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xac9650d8
0000000000000000000000000000000000000000000000000000000000000020 offset
0000000000000000000000000000000000000000000000000000000000000001 length of array
0000000000000000000000000000000000000000000000000000000000000020 offset of first element of array
0000000000000000000000000000000000000000000000000000000000000004 length of data -&amp;gt; 4 bytes, which is the length of the function selector
d0e30db000000000000000000000000000000000000000000000000000000000 data -&amp;gt; the function selector of `deposit()`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, our calldata with everything&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0x00&lt;/th&gt;
&lt;th&gt;0xac9650d8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x00&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x20&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000040&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x60&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x80&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xa0&lt;/td&gt;
&lt;td&gt;d0e30db000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xc0&lt;/td&gt;
&lt;td&gt;00000000000000000000000000000000000000000000000000000000000000a4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xe0&lt;/td&gt;
&lt;td&gt;ac9650d800000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x100&lt;/td&gt;
&lt;td&gt;0000002000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x120&lt;/td&gt;
&lt;td&gt;0000000100000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x140&lt;/td&gt;
&lt;td&gt;0000002000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0xac9650d8
0000000000000000000000000000000000000000000000000000000000000020 offset of array length
0000000000000000000000000000000000000000000000000000000000000002 length of array -&amp;gt; 2
0000000000000000000000000000000000000000000000000000000000000040 offset of 1st element of array: `deposit()` call
0000000000000000000000000000000000000000000000000000000000000080 offset of 2nd element: `multicall(bytes[])` call

0000000000000000000000000000000000000000000000000000000000000004 first element. This is the call to deposit(). We already covered it.
d0e30db000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000a4 second element. This is the inner multicall(). The data size is 0xa4 -&amp;gt; 164 bytes
ac9650d800000000000000000000000000000000000000000000000000000000
0000002000000000000000000000000000000000000000000000000000000000
0000000100000000000000000000000000000000000000000000000000000000
0000002000000000000000000000000000000000000000000000000000000000
00000004d0e30db0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let separate the data of the second call. This is just another call to &lt;code&gt;multicall(bytes[])&lt;/code&gt; so it’s easy to understand&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ac9650d8
0000000000000000000000000000000000000000000000000000000000000020 offset
0000000000000000000000000000000000000000000000000000000000000001 length
0000000000000000000000000000000000000000000000000000000000000020 offset of element 1
0000000000000000000000000000000000000000000000000000000000000004 length of data
d0e30db000000000000000000000000000000000000000000000000000000000 data -&amp;gt; function selector for `deposit()`
00000000000000000000000000000000000000000000000000000000         -&amp;gt; this is just some padding to make sure we have a multiple of 32 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Motorbike
&lt;/h3&gt;

&lt;p&gt;Just a comment on this level: when we load the exploitSelector, we do not apply a mask to it. We dont really care because when we pass it, we specify that the length of is 4 bytes. The rest will be ignored. But remember that if you actually send that transaction, &lt;strong&gt;it will be more expensive&lt;/strong&gt;, because you’re sending more bytes. And calldata bytes are expensive!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(add(fmp, 0x24), 0x40)
mstore(add(fmp, 0x44), 4) // &amp;lt;--- here we specify: "only read the next 4 bytes" (the selector for `exploit()`)
mstore(add(fmp, 0x64), exploitSelector) // &amp;lt;-- but here we store the entire hash, not only the 4-bytes selector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DoubleEntryPoint
&lt;/h3&gt;

&lt;p&gt;Another bitmask to get only the 4 bytes of the selector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let selectorMask := shl(224, sub(exp(2, 32), 1))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you open &lt;code&gt;contracts/26_DoubleEntryPoint.sol&lt;/code&gt; the signature of the function is &lt;code&gt;function handleTransaction(address user, bytes calldata msgData) external&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;msgData&lt;/code&gt; is in calldata. It was not copied to memory, so we cannot use &lt;code&gt;mload&lt;/code&gt;. We need to use &lt;code&gt;calldataload&lt;/code&gt; instead to load the data.&lt;/p&gt;

&lt;p&gt;We can easily compute ourselves the offset where we’ll find the data, but there is an easier way: &lt;code&gt;.offset&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;First we get the function selector by applying the &lt;code&gt;selectorMask&lt;/code&gt; bitmask.&lt;/p&gt;

&lt;p&gt;Then we need to get the 3rd parameter: remember, the function is &lt;code&gt;delegateTransfer(address to, uint256 value, address origSender)&lt;/code&gt; and we only want &lt;code&gt;origSender&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let msgSelector := and(calldataload(msgData.offset), selectorMask)
let origSender := calldataload(add(msgData.offset, 0x44))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GoodSamaritan
&lt;/h3&gt;

&lt;p&gt;Here we revert with a Solidity custom error. Nothing special, it works just like function selectors&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mstore(0, "NotEnoughBalance()")
mstore(0, keccak256(0, 18))
revert(0, 4)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GateKeeper 3
&lt;/h3&gt;

&lt;p&gt;With that last one, since we have a lot of external functions to call, let’s write some Yul functions. You might have already seen on Telephone level that I already experimented with functions in the tests (check in &lt;code&gt;test/foundry/4_Telephone.t.sol&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We need to make a few calls to &lt;code&gt;gatekeeper&lt;/code&gt; contract: &lt;code&gt;construct0r()&lt;/code&gt;, &lt;code&gt;createTrick()&lt;/code&gt;, &lt;code&gt;getAllowance(uint256)&lt;/code&gt; and &lt;code&gt;enter()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can easily write a function that just hashes the function signature for us and stores the selector. But, as you know, you need the length of the function signature. So let’s first write a function to get a string’s length&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getStrLen(_str) -&amp;gt; _length {
    for {
        let i := 0
    } lt(i, 0x20) {
        i := add(i, 1)
    } {
        if iszero(byte(i, _str)) {
            break
        }
        _length := add(_length, 1)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy! We just pass a string as input, it loops over it as long as there is a char. If it finds a &lt;code&gt;0&lt;/code&gt; it means we’re at the end of the string, so we return the length. Be careful: it only works as long as the string is less that 32 bytes, but it’s all good for us here since all our function signatures are less that 32 characters.&lt;/p&gt;

&lt;p&gt;Next we can hash that string and store the result in memory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function hashSelector(_sig) {
    mstore(0, _sig)
    mstore(0, keccak256(0, getStrLen(_sig)))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, pretty simple. Finally we can just make our call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function callExternal(_address, _sig, _param) {
    hashSelector(_sig)
    let calldataLen := 4

    if iszero(iszero(_param)) {
        mstore(4, _param)
        calldataLen := 0x24
    }

    let _success := call(gas(), _address, 0, 0, calldataLen, 0, 0)
    if iszero(_success) {
        revert(0, 0)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;getAllowance&lt;/code&gt; takes a parameter, we added an if statement to store that parameter and increase the size of the calldata that will be sent.&lt;/p&gt;

&lt;p&gt;🔥 By the way, funny thing about that level. While solving it I discovered a small bug in Foundry for which I &lt;a href="https://github.com/foundry-rs/foundry/issues/4434" rel="noopener noreferrer"&gt;opened an issue&lt;/a&gt;, and finally decided to solve it myself and &lt;a href="https://github.com/foundry-rs/foundry/pull/4469" rel="noopener noreferrer"&gt;submit a PR&lt;/a&gt;. You can read more about it &lt;a href="https://twitter.com/0xteddav/status/1631592176319700992" rel="noopener noreferrer"&gt;in my tweet&lt;/a&gt; and &lt;a href="https://dev.to/teddav/foundry-open-source-contribution-1k2d"&gt;the related article&lt;/a&gt; on &lt;a href="https://dev.to/teddav/"&gt;dev.to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And… WE ARE DONE !!! 😍&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s all! I hope you had a good time solving the Ethernaut challenges, and that you enjoyed this little walkthrough and learned a lot about assembly!&lt;/p&gt;

&lt;p&gt;Again, if you have any issues understanding, or if I made a mistake, you can contact me on Twitter: &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;0xteddav&lt;/a&gt; ❤️&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>ethereum</category>
      <category>web3</category>
      <category>security</category>
    </item>
    <item>
      <title>Foundry: open source contribution</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Thu, 02 Mar 2023 21:54:22 +0000</pubDate>
      <link>https://forem.com/teddav/foundry-open-source-contribution-1k2d</link>
      <guid>https://forem.com/teddav/foundry-open-source-contribution-1k2d</guid>
      <description>&lt;p&gt;Contributing to open source projects can be a bit scary sometimes 👻 But it’s usually not that hard!&lt;/p&gt;

&lt;p&gt;I just made my first (really small) contribution to &lt;a href="https://github.com/foundry-rs/foundry" rel="noopener noreferrer"&gt;Foundry&lt;/a&gt; (a toolkit to help develop smart contracts for Ethereum) today, and I really enjoyed it! 😍&lt;/p&gt;

&lt;p&gt;While tackling the issue I took some notes, so if you’re thinking about contributing, I’m going to walk you through what I did and hopefully you’ll see that it’s pretty easy. Obviously the bug I fixed was really simple but it helped me get into the code and I’m ready to take on some more challenging ones 💪&lt;/p&gt;

&lt;p&gt;It all started with this issue: &lt;a href="https://github.com/foundry-rs/foundry/issues/4434" rel="noopener noreferrer"&gt;https://github.com/foundry-rs/foundry/issues/4434&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There was a bug in my forge script… I didn’t have time to look into it that day, so I left the issue opened for a few days, and today I finally took the time to do it. It took me about 3 hours from the moment I cloned the repo to the moment I opened the PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Foundry repo
&lt;/h3&gt;

&lt;p&gt;First thing I did after cloning the repo was heading to the &lt;a href="https://github.com/foundry-rs/foundry/tree/master/docs/dev" rel="noopener noreferrer"&gt;dev doc&lt;/a&gt; for help.&lt;/p&gt;

&lt;p&gt;Since my PR was specifically related to &lt;code&gt;forge script&lt;/code&gt; I thought I would only install &lt;code&gt;forge&lt;/code&gt; locally with &lt;code&gt;cargo build -p ./forge --profile local&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And I ran the tests: &lt;code&gt;cargo test -p ./forge --profile local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I didn’t dig into it, but it seems like adding the &lt;code&gt;local&lt;/code&gt; profile flag makes the build take longer, so in the end I just went with &lt;code&gt;cargo build&lt;/code&gt; and built the entire project.&lt;/p&gt;

&lt;p&gt;I now have the &lt;code&gt;forge&lt;/code&gt; binary in &lt;code&gt;foundry/target/debug/forge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then I ran this command so that it would rebuild automatically when i make a change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="s"&gt;"build"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;On every change, the build takes about 15-20 seconds on my Macbook Pro M1&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reproduce the error
&lt;/h3&gt;

&lt;p&gt;I then created another directory where I setup my project for testing with the problematic script and I linked the newly built &lt;code&gt;forge&lt;/code&gt; inside this repo with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; ../foundry/target/debug/forge ./myforge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-- cache
|-- foundry.toml
|-- lib
|-- myforge -&amp;gt; ../foundry/target/debug/forge
|-- myscript.s.sol
`-- out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is &lt;code&gt;myscript.s.sol&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: UNLICENSED&lt;/span&gt;
&lt;span class="n"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="na"&gt;.18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// import "forge-std/Script.sol";&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Script&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="s"&gt;"forge-std/Script.sol"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;MyScript&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Script&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="nf"&gt;.startBroadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"broadcaster    "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="nf"&gt;.addr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"script         "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"origin         "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ContractA&lt;/span&gt; &lt;span class="n"&gt;contractA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContractA&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ContractB&lt;/span&gt; &lt;span class="n"&gt;contractB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContractB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;ContractC&lt;/span&gt; &lt;span class="n"&gt;contractC1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContractC&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contractA      "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractA&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contractB      "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractB&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contractC1     "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractC1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;contractA&lt;/span&gt;&lt;span class="nf"&gt;.test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractB&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;contractB&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;contractC1&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt; origin (end)   "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="nf"&gt;.stopBroadcast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;ContractA&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;_contractB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ContractB&lt;/span&gt; &lt;span class="n"&gt;contractB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ContractB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_contractB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ContractC&lt;/span&gt; &lt;span class="n"&gt;contractC2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContractC&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (start)  "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (start) sender       "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;contractB&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (after1) "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (after1) sender      "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;contractC2&lt;/span&gt;&lt;span class="nf"&gt;.method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (after2) "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A (after2) sender      "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;ContractB&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B          "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B sender               "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;ContractC&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C          "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="nf"&gt;.log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C sender               "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can then run this command to reproduce my issue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./myforge script ./myscript.s.sol &lt;span class="nt"&gt;--tc&lt;/span&gt; MyScript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Foundry code
&lt;/h2&gt;

&lt;p&gt;After looking at the code, trying to understand the architecture of the repo, and reading the &lt;a href="https://github.com/foundry-rs/foundry/tree/master/docs/dev" rel="noopener noreferrer"&gt;dev doc&lt;/a&gt; I understood that I need to look into &lt;code&gt;evm/src/executor/inspector/cheatcodes&lt;/code&gt;. So I started by adding some logs to understand what was going on.&lt;/p&gt;

&lt;p&gt;I added logs in &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;call_end&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;create_end&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are some examples of what it looked like&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;evm/src/executor/inspector/cheatcodes/mod.rs&lt;/code&gt; &lt;a href="https://github.com/foundry-rs/foundry/blob/master/evm/src/executor/inspector/cheatcodes/mod.rs#L450" rel="noopener noreferrer"&gt;on line 450&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;CallInputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;is_static&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Gas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.broadcast&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"call() &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;{broadcast:#?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contract: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;context: {:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="py"&gt;.contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="py"&gt;.context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"env before: {:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.env.tx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/foundry-rs/foundry/blob/master/evm/src/executor/inspector/cheatcodes/mod.rs#L730" rel="noopener noreferrer"&gt;And on line 730&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EVMData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CreateInputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;remaining_gas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Gas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retdata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Gas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;

        &lt;span class="c1"&gt;// Clean up broadcasts&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.broadcast&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"create_end() &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;{broadcast:#?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"address: {address:?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"caller {:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="py"&gt;.caller&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"env before: {:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.env.tx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"depth: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.journaled_state&lt;/span&gt;&lt;span class="nf"&gt;.depth&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.env.tx.caller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="py"&gt;.original_origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/create_end()&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I quickly noticed that there was an issue with &lt;code&gt;call_end&lt;/code&gt; and &lt;code&gt;create_end&lt;/code&gt; which are the functions being called after a contract call and after a contract creation: it would reset the &lt;code&gt;data.env.tx.caller&lt;/code&gt; which is the &lt;code&gt;tx.origin&lt;/code&gt; in the Solidity context.&lt;/p&gt;

&lt;p&gt;So the fix was pretty easy. Change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.env.tx.caller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="py"&gt;.original_origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&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 rust"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.journaled_state&lt;/span&gt;&lt;span class="nf"&gt;.depth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="py"&gt;.depth&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="py"&gt;.env.tx.caller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="py"&gt;.original_origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes sure that &lt;code&gt;tx.origin&lt;/code&gt; will be reset only when the last call is popped from the call stack and the execution returns to the &lt;code&gt;run()&lt;/code&gt; function of the &lt;code&gt;Script&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And… that’s it! We’re done 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration tests
&lt;/h2&gt;

&lt;p&gt;Now let’s add some tests.&lt;/p&gt;

&lt;p&gt;After testing on my local setup by running &lt;code&gt;forge script&lt;/code&gt; manually, it was time to add a proper integration test.&lt;/p&gt;

&lt;p&gt;Tests are located in &lt;code&gt;cli/tests/it/script.rs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To add a test, we use the &lt;code&gt;forgetest_async!&lt;/code&gt; macro. I cleaned the &lt;code&gt;Script&lt;/code&gt; that I was using and added some &lt;code&gt;require&lt;/code&gt; statements and copied it inside my integration test.&lt;/p&gt;

&lt;p&gt;I just need 1 line to make sure my script ran correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="nf"&gt;.stdout_lossy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Script ran successfully."&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;stdout_lossy()&lt;/code&gt; uses &lt;code&gt;output()&lt;/code&gt; which, &lt;a href="https://github.com/foundry-rs/foundry/blob/master/cli/test-utils/src/util.rs#L596" rel="noopener noreferrer"&gt;as the comment above says&lt;/a&gt;: “If the command failed, then this panics.”&lt;br&gt;
So the script will fail if the &lt;code&gt;Script&lt;/code&gt; fails, or if the output doesn’t contain “Script ran successfully.”&lt;/p&gt;

&lt;p&gt;Run the test with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nb"&gt;test &lt;/span&gt;assert_tx_origin_is_not_overritten &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--show-output&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, if I want it to rebuild automatically everytime I make a change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo watch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="s2"&gt;"test assert_tx_origin_is_not_overritten -- --show-output"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;assert_tx_origin_is_not_overritten&lt;/code&gt; is the name I chose for the test I wrote. You can see it on the PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s merge
&lt;/h2&gt;

&lt;p&gt;Before pushing, make sure your code is formatted correctly and doesn’t have warnings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo +nightly &lt;span class="nb"&gt;fmt&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--check&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;cargo +nightly clippy &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--all-features&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; warnings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the commands in the &lt;a href="https://github.com/foundry-rs/foundry/blob/master/CONTRIBUTING.md#resolving-an-issue" rel="noopener noreferrer"&gt;Contributing guidelines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now need to open a PR and wait for someone to review 😊&lt;br&gt;
Here it is: &lt;a href="https://github.com/foundry-rs/foundry/pull/4469" rel="noopener noreferrer"&gt;https://github.com/foundry-rs/foundry/pull/4469&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next time you have an issue with an open source project, maybe try to contribute 😁&lt;br&gt;
If you have any question, or if I made a mistake somewhere: message me &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;on Twitter 0xteddav&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>solidity</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Playing with Yul (Assembly)</title>
      <dc:creator>teddav</dc:creator>
      <pubDate>Wed, 22 Feb 2023 10:16:49 +0000</pubDate>
      <link>https://forem.com/teddav/playing-with-yul-assembly-1i5h</link>
      <guid>https://forem.com/teddav/playing-with-yul-assembly-1i5h</guid>
      <description>&lt;p&gt;&lt;em&gt;Assembly has been really hyped lately and all the cool kids seem to have started learning it. So I decided to do the same and learn what Yul is and how I can write my contracts with it. I started learning a few weeks ago and today I’m going to show you the basics so you can start enjoying it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This tutorial is a bit advanced and doesn’t start from the beginning. If you want a real intro, you can check out the amazing series by &lt;a href="https://twitter.com/noxx3xxon" rel="noopener noreferrer"&gt;@noxx3xxon&lt;/a&gt; &lt;strong&gt;&lt;a href="https://noxx.substack.com/" rel="noopener noreferrer"&gt;EVM Deep Dives: The Path to Shadowy Super Coder&lt;/a&gt;&lt;/strong&gt; where everything is really well explained. Or &lt;a href="https://jeancvllr.medium.com/solidity-tutorial-all-about-assembly-5acdfefde05c" rel="noopener noreferrer"&gt;this great tutorial&lt;/a&gt; by &lt;a href="https://twitter.com/JeanCavallera" rel="noopener noreferrer"&gt;@JeanCavallera&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Assembly/Yul
&lt;/h2&gt;

&lt;p&gt;I’m not going to go into too much details, but basically assembly (or assembler) is a low-level language, really close to what your computer can understand. It’s a sequence of instructions for your computer to execute (here: the EVM).&lt;/p&gt;

&lt;p&gt;Yul is just the name of the (almost) assembly for the EVM. I say “almost” because it’s a bit easier to write than pure assembly and it has the concept of variables, functions, for-loops, if statements, … whereas pure assembly doesn’t. So Yul makes our lives a bit easier 😊&lt;/p&gt;

&lt;p&gt;You can use Yul when you need to have more control over what your code is doing. You can do anything in Yul since you control exactly what the EVM is going to execute, while Solidity is more restrictive. And most of the time Yul is used for gas optimizations.&lt;/p&gt;

&lt;p&gt;Writing an entire contract in assembly (Yul) wouldn’t make sense usually, but that’s what we are going to do here so that you can understand better how it works and how the EVM works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The base contract
&lt;/h2&gt;

&lt;p&gt;As I already said, I’ll try to explain as much as possible, but I will not go over the very basics. So if you want to understand this tutorial, you’ll need a good understanding of Solidity and the EVM.&lt;/p&gt;

&lt;p&gt;Let’s begin! We’ll rewrite this (really unsafe and stupid 😄) “lottery” contract to assembly. No access control, and the functions are a bit dumb, but it will be easier to write/understand when written in assembly 😊&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract AngleExplainsBase {
    uint private secretNumber;
    mapping(address =&amp;gt;  uint) public guesses;

    bytes32 public secretWord;

    // obviously this doesn't make sense
    // but it will be fun to write it in assembly :D
    function getSecretNumber() external view returns(uint) {
        return secretNumber;
    }

    // this should only be set by an admin
    // no access control because we want to keep it simple in assembly
    function setSecretNumber(uint number) external {
        secretNumber = number;
    }

    // a user can add a guess
    function addGuess(uint _guess) external {
        guesses[msg.sender] = _guess;
    }

    // yes i know... it doesn't make sense because you can change guesses for any user
    // it's just to teach you how to parse arrays in assembly
    function addMultipleGuesses(address[] memory _users, uint[] memory _guesses) external {
        for (uint i = 0; i &amp;lt; _users.length; i++) {
            guesses[_users[i]] = _guesses[i];
        }
    }

    // this is useless since the `secretWord` is not used anywhere
    // but this will teach us how to hash a string in assembly. Really cool! :)
    function hashSecretWord(string memory _str) external {
        secretWord = keccak256(abi.encodePacked(_str));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a &lt;code&gt;secretNumber&lt;/code&gt; that is private and we have a getter for that secret number &lt;code&gt;getSecretNumber&lt;/code&gt;. Yes, it doesn't make, but if you're reading this, you should know that nothing is private on the blockchain anyway, so it doesn't really matter if we add a getter. It will just be fun to write it to assembly. Then, obviously, we have a setter &lt;code&gt;setSecretNumber&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The user can add 1 or multiple guess(es) &lt;code&gt;addGuess&lt;/code&gt; / &lt;code&gt;addMultipleGuesses&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we have an extra function &lt;code&gt;hashSecretWord&lt;/code&gt;. Let's imagine, we could use it if we decide to switch from a secret number to a secret string. Here it will help us understand more about how strings are handled in memory and we'll learn how to hash something in assembly (so cool!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Get/Set our secret number
&lt;/h2&gt;

&lt;p&gt;Throughout the code you’ll see a lot &lt;code&gt;0x20&lt;/code&gt; or multiples of it (0x40, 0x60, 0x80, 0xa0, ...). This is the hexadecimal representation of &lt;code&gt;32&lt;/code&gt; because the EVM uses 32 bytes memory slots (words). So values are always encoded in 32 bytes. (yes, you should know how to count in hexadecimal).&lt;/p&gt;

&lt;p&gt;Let’s start with &lt;code&gt;getSecretNumber&lt;/code&gt;. We will need SLOAD, MLOAD, MSTORE and RETURN opcodes for this function. Use the great &lt;a href="https://www.evm.codes/" rel="noopener noreferrer"&gt;https://www.evm.codes&lt;/a&gt; to learn more about EVM opcodes.&lt;/p&gt;

&lt;p&gt;SLOAD just retrieves a value from storage. So we use SLOAD to get the value of our secret number. Then, in an ideal world, we should be done and just be able to return that number. But the EVM is a bit more complex than that and only returns values that are stored in memory. Solidity makes it easier for us and allows us to just return a value, and we don’t care what happens under the hood, but remember that Yul is more lower level, so we need to do the hard work.&lt;/p&gt;

&lt;p&gt;First we’ll store that value to memory with MSTORE, and then we can return it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Free memory pointer&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ll use the “free memory pointer”, which is stored at 0x40 in memory.&lt;br&gt;&lt;br&gt;
&lt;code&gt;mload(0x40)&lt;/code&gt; gives us the address in memory where we are allowed to write (in order not to overwrite anything). The memory before that address is already used, so if we overwrite it we might mess up our entire transaction (or even contract 😮 if something in that memory was meant to be written to storage for example).  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We store our number there (MSTORE). And then we return it by specifying the address in memory, and the size that should be returned&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getSecretNumber() external view returns(uint) {
        assembly {
            // We get the value for secretNumber which is at slot 0
            // in Yul, you also have access to the slot number of a variable through `.slot`
                        // https://docs.soliditylang.org/en/latest/assembly.html#access-to-external-variables-functions-and-libraries
            // so we could also just write `sload(secretNumber.slot)`
            // SLOAD https://www.evm.codes/#54
            let _secretNumber := sload(0)

            // then we get the "free memory pointer"
            // that means we get the address in the memory where we can write to
            // we use the MLOAD opcode for that: https://www.evm.codes/#51
            // We get the value stored at 0x40 (64)
            // 0x40 is just a constant decided in the EVM where the address of the free memory is stored
            // see here: https://docs.soliditylang.org/en/latest/assembly.html#memory-management
            let ptr := mload(0x40)

            // we write our number at that address
            // to do that, we use the MSTORE opcode: https://www.evm.codes/#52
            // It takes 2 parameters: the address in memory where to store our value, and the value to store
            mstore(ptr, _secretNumber)

            // then we RETURN the value: https://www.evm.codes/#f3
            // we specify the address where the value is stored: `ptr`
            // and the size of the parameter returned: 32 bytes (remember values are always stored on 32 bytes)
            return(ptr, 0x20)
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I just wanted to complicate things a bit for you by using the free memory pointer. But we could write our function in a shorter way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// instead of using the free memory pointer, we could also store the value at `0`
// because the first 2 slots in memory are used as "scratch space"
// https://docs.soliditylang.org/en/latest/internals/layout_in_memory.html#layout-in-memory
// this means they are used to store temporary values, such as return values
// we would have had:
assembly {
    let _secretNumber := sload(0)
    mstore(0, _secretNumber)
    return(0, 0x20)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? You have to know that the EVM reserves the first 4 slots in memory for special purposes. Here are the slots. I added a 5th one which represents the first writable slot.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;offset&lt;/th&gt;
&lt;th&gt;value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x00 (0)&lt;/td&gt;
&lt;td&gt;scratch space, can be used for storing anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x20 (32)&lt;/td&gt;
&lt;td&gt;scratch space, can be used for storing anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40 (64)&lt;/td&gt;
&lt;td&gt;free memory pointer. Initial value is 0x80 (where starts the memory we can write to)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x60 (96)&lt;/td&gt;
&lt;td&gt;zero slot, should never be touched&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x80 (128)&lt;/td&gt;
&lt;td&gt;that’s where the memory starts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, we can use the first 2 slots to write anything. But we have to keep in mind that they can be also be overwritten at anytime.&lt;/p&gt;

&lt;p&gt;Next we’ll write &lt;code&gt;setSecretNumber&lt;/code&gt; which is a bit easier. We just need to retrieve the slot number where the value is stored, and use SSTORE to store our new value.&lt;/p&gt;

&lt;p&gt;Here we’ll just use the special &lt;code&gt;.slot&lt;/code&gt; helper that Yul offers us. It makes it easier, so we don't have to manually calculate the slot number 😄&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function setSecretNumber(uint _number) external {
        assembly {
            // We get the slot number for `secretNumber`
            let slot := secretNumber.slot

            // We use SSTORE to store the new value
            // https://www.evm.codes/#51
            sstore(slot, _number)
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add guesses
&lt;/h2&gt;

&lt;p&gt;We now need to allow a user to add a guess. But &lt;code&gt;guesses&lt;/code&gt; is a mapping, so it complicates things. We first need to compute the value of the storage slot where the &lt;code&gt;guess&lt;/code&gt; is going to be stored, and then we can store it with SSTORE&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How mappings work&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;To write a value to a mapping: we concatenate the key and the slot number of the mapping, and hash that (for more details: &lt;a href="https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays" rel="noopener noreferrer"&gt;https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays&lt;/a&gt;). Here our mapping &lt;code&gt;guesses&lt;/code&gt; is at storage slot 1.&lt;br&gt;&lt;br&gt;
So in Solidity we would get the storage slot by doing &lt;code&gt;keccak256(abi.encode(msg.sender, 1))&lt;/code&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To hash something in Yul, we have to store it to memory first. It’s not possible otherwise, keccak256() only looks in memory.&lt;/p&gt;

&lt;p&gt;Here are the steps to get our slot number&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get the msg.sender address&lt;/li&gt;
&lt;li&gt;get the slot number of the mapping&lt;/li&gt;
&lt;li&gt;store both of them in memory (in order and next to each other)&lt;/li&gt;
&lt;li&gt;compute the hash
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function addGuess(uint _guess) external {
        assembly {
            // first we compute the slot where we will store the value
            // https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays
            // we have: keccak256(abi.encode(_user, 1)) where 1 is the slot number for `guesses`
            let ptr := mload(0x40)

            // we store the address of msg.sender at `ptr` address
                        // CALLER opcode: https://www.evm.codes/#33
            mstore(ptr, caller())

            // then right after that, we store the slot number for `guesses`
            mstore(add(ptr, 0x20), guesses.slot)

            // the 2 previous MSTORE are equivalent to abi.encode(msg.sender, 1)

            // then we just compute the hash of the msg.Sender and guesses.slot
            // they are currently stored at `ptr` and use 2 slots (2x 32bytes -&amp;gt; 0x40)
            let slot := keccak256(ptr, 0x40)

            // we now only need to store the value at that slot
            sstore(slot, _guess)
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the address of the msg.sender in assembly we use the CALLER opcode.&lt;/p&gt;

&lt;p&gt;We use the free memory pointer to know where to write our values. Then we store the msg.sender (caller()).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add(ptr, 0x20)&lt;/code&gt; gives us the memory address 32 bytes after, which means "the next memory slot". That's where we'll store our second value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operations in Assembly
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In Assembly we can't do simple operations (+ - * /), they just don’t exist ☹️&lt;br&gt;&lt;br&gt;
We need to use specific opcodes for that. Here we use ADD to add 32 bytes to the address of &lt;code&gt;ptr&lt;/code&gt;&lt;br&gt;&lt;br&gt;
This is equivalent to: ptr = ptr + 32  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we hash all of that. The second argument of &lt;code&gt;keccak256&lt;/code&gt; is the size of the data to be hashed. Here it's 2 memory slots, so 2*32=64 (0x40 in hexadecimal)&lt;/p&gt;

&lt;h2&gt;
  
  
  Hash some strings
&lt;/h2&gt;

&lt;p&gt;We are going to take a quick break from our main functions and focus and the most useless function (but most fun) of our Solidity contract: &lt;code&gt;hashSecretWord&lt;/code&gt;. We'll even go as far as writing it 2 times with 2 different techniques to get the &lt;code&gt;_str&lt;/code&gt; parameter’s value. We’ll use the CALLDATA opcodes, to help you understand how &lt;code&gt;calldata&lt;/code&gt; works and how to manipulate the calldata (you're welcome!).&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-value types
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;First, a little lesson about non-value types: one of the complicated parts I noticed when first learning Yul was when dealing with non-value types (array, mapping, bytes or string). But they are actually not that hard to understand, you just have to understand how the EVM deals with them and stores them in memory.&lt;br&gt;&lt;br&gt;
It goes like this: those values are usually stored in 2 parts: first their length, and then the actual value. Imagine you pass the string “angle” as a parameter. It will be stored like “5angle” so the EVM knows it’s supposed to read the next 5 characters.&lt;br&gt;&lt;br&gt;
It will actually look a bit different, since the EVM works in 32 bytes memory slots, it will look more like: &lt;code&gt;0000000000000000000000000000000000000000000000000000000000000005616e676c65000000000000000000000000000000000000000000000000000000&lt;/code&gt;&lt;br&gt;&lt;br&gt;
notice the &lt;code&gt;5&lt;/code&gt; and then the word &lt;code&gt;angle&lt;/code&gt; written in hexadecimal (&lt;code&gt;616e676c65&lt;/code&gt;)  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, back to our code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// computes the keccak256 hash of a string and stores it in a state variable
function hashSecretWord1(string memory _str) external view returns(bytes32) {
    assembly {
        // in assembly `_str` is just a pointer to the string
        // it represents the address in memory where the data for our string starts
        // at `_str` we have the length of the string
        // at `_str` + 32 -&amp;gt; we have the string itself

        // here we get the size of the string
        let strSize := mload(_str)

        // here we add 32 to that address, so that we have the address of the string itself
        let strAddr := add(_str, 32)

        // we then pass the address of the string, and its size. This will hash our string
        let hash := keccak256(strAddr, strSize)

        // we store the hash value at slot 0 in memory
        // just like we explained before, this is used as temporary storage (scratch space)
        // no need to get the free memory pointer, it is faster (and cheaper) to use `0`
        mstore(0, hash)

        // we return what is stored at slot 0 (our hash) and the length of the hash (32)
        return (0, 32)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;_str&lt;/code&gt; is a pointer to the slot in memory where the length of the string is stored, and then (at the next slot) the string itself starts. So we just need to retrieve that size, then we can just hash the string directly since it's already in memory and we know its address. Easy!&lt;/p&gt;

&lt;p&gt;To make it even easier, let me show you what the memory looks like at the start of our function. Let’s say we passed the string “stablecoin”&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;offset&lt;/th&gt;
&lt;th&gt;value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x00 (0)&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x20 (32)&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40 (64)&lt;/td&gt;
&lt;td&gt;0xc0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x60 (96)&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x80 (128)&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xa0 (160)&lt;/td&gt;
&lt;td&gt;stablecoin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xc0 (192)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The length of our string is written at 0x80, and our word is written at 0xa0. The free memory pointer points to the next available memory space: 0xc0.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;_str&lt;/code&gt; is equal to 0x80 (where our string is stored).&lt;/p&gt;

&lt;p&gt;But you may ask: How was it stored in memory in the first place? There was no MSTORE to write to memory, so why isn’t the memory empty?&lt;/p&gt;

&lt;p&gt;The EVM (magically) placed it there because we asked it to do so. When? Here: &lt;code&gt;string memory _str&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By specifying &lt;code&gt;memory&lt;/code&gt; in the parameter, we asked the EVM to prepare our memory and place our parameter there. That's why using &lt;code&gt;calldata&lt;/code&gt; is cheaper, there is no writing to memory 😉&lt;/p&gt;

&lt;h3&gt;
  
  
  Second string hashing technique
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// this is the same as `hashSecretWord1` but using a different technique
// here we use specific opcodes to manipulate calldata instead of using the parameters of the function
// instead of returning the hash, we'll assign it to storage variable `secretWord`
function hashSecretWord2(string calldata) external {
    assembly {
        // the calldata represents the entire data passed to a contract when calling a function
        // the first 4 bytes always represent the signature of the function, and the rest are the parameters
        // here we can skip the signature because we are already in the function, so the signature obviously represent the current function
        // we can use CALLDATALOAD to load 32 bytes from the calldata.
        // we use calldataload(4) to skip the signature bytes. This will therefore load the 1st parameter
        // when using non-value types (array, mapping, bytes, string) the first parameter is going to be the offset where the parameter starts
        // at that offset, we'll find the length of the parameter, and then the value

        // this is the offset in `calldata` where our string starts
        // here we use calldataload(4) -&amp;gt; loads the offset where the string starts
        // -&amp;gt; we add 4 to that offset to take into account the signature bytes
        // https://www.evm.codes/#35
        let strOffset := add(4, calldataload(4))

        // we use calldataload() again with the offset we just computed, this gives us the length of the string (the value stored at the offset)
        let strSize := calldataload(strOffset)

        // we load the free memory pointer
        let ptr := mload(0x40)

        // we copy the value of our string into that free memory
        // CALLDATACOPY https://www.evm.codes/#37
        // the string starts at the next memory slot, so we add 0x20 to it
        calldatacopy(ptr, add(strOffset, 0x20), strSize)

        // then we compute the hash of that string
        // remember, the string is now stored at `ptr`
        let hash := keccak256(ptr, strSize)

        // and we store it to storage
        sstore(secretWord.slot, hash)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don’t even need a name for our parameter since we’re not going to use it explicitly.  And notice that this time we don’t need it in “memory", so we specify “calldata” so that it won’t be copied.&lt;/p&gt;

&lt;p&gt;The CALLDATALOAD opcode loads 32 bytes from the calldata starting at the offset specified. We use it here to load values 1 by 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  More non-value types
&lt;/h3&gt;

&lt;p&gt;I need to add something to the previous explanation about non-value types. The calldata is just a bit more complicated than what I previously told you. Focus! This is not easy.&lt;/p&gt;

&lt;p&gt;Let’s give an example of what the memory would look like for a function with 3 parameters:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function myToken(string memory name, uint randomValue, address[] memory _addresses)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;we pass the following (pseudo random) parameters 🙂&lt;/p&gt;

&lt;p&gt;“angle”, 7, ["0x31429d1856aD1377A8A0079410B297e1a9e214c2", "0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8"]&lt;/p&gt;

&lt;p&gt;What the calldata looks like &lt;code&gt;050eed260000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005616e676c65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c20000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s split that in 32 bytes words to have a better view.&lt;/p&gt;

&lt;p&gt;First we have the function signature: 050eed26, and then the parameters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;offset (from 1st param)&lt;/th&gt;
&lt;th&gt;offset (calldata)&lt;/th&gt;
&lt;th&gt;value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x00 (0)&lt;/td&gt;
&lt;td&gt;0x04 (4)&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000060&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x20 (32)&lt;/td&gt;
&lt;td&gt;0x24 (36)&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000007&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x40 (64)&lt;/td&gt;
&lt;td&gt;0x44 (68)&lt;/td&gt;
&lt;td&gt;00000000000000000000000000000000000000000000000000000000000000a0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x60 (96)&lt;/td&gt;
&lt;td&gt;0x64 (100)&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000005&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x80 (128)&lt;/td&gt;
&lt;td&gt;0x84 (132)&lt;/td&gt;
&lt;td&gt;616e676c65000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xa0 (160)&lt;/td&gt;
&lt;td&gt;0xa4 (164)&lt;/td&gt;
&lt;td&gt;0000000000000000000000000000000000000000000000000000000000000002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xc0 (192)&lt;/td&gt;
&lt;td&gt;0xc4 (196)&lt;/td&gt;
&lt;td&gt;00000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xe0 (224)&lt;/td&gt;
&lt;td&gt;0xe4 (228)&lt;/td&gt;
&lt;td&gt;0000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I used &lt;a href="https://abi.hashex.org/" rel="noopener noreferrer"&gt;https://abi.hashex.org/&lt;/a&gt; to easily encode the calldata.&lt;/p&gt;

&lt;p&gt;We have our 3 function parameters, in order, but encoded in a special way.&lt;/p&gt;

&lt;p&gt;I started the numbering at 0, but we’ll have to remember to add 4 to the offset to account for function signature.&lt;/p&gt;

&lt;p&gt;For value types, the value is the value of the parameter. See at 0x20, we have &lt;code&gt;7&lt;/code&gt; which is the value we passed for &lt;code&gt;randomValue&lt;/code&gt;. But for non-value types, we actually get the offset where the data starts. See at 0x00 we have 0x60. If we check at 0x60, we have 5: the length of the string, and right after, at 0x80 we have the string "angle".&lt;/p&gt;

&lt;p&gt;The last parameter starts at 0x40, again this is the offset. So let’s check at 0xa0, we have 2 (the length of our array), and then the 2 values at 0xc0 and 0xe0.&lt;/p&gt;

&lt;p&gt;Nice! We finally know how the EVM understands all the “weird” types we can pass to it! 🔥&lt;/p&gt;

&lt;p&gt;Back to our calldata then.&lt;/p&gt;

&lt;p&gt;Let’s just explain this line better &lt;code&gt;let strOffset := add(4, calldataload(4))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We use CALLDATALOAD to get the first parameter (at offset 4, remember the function signature…).&lt;/p&gt;

&lt;p&gt;This returns the offset where the length of the string is stored. For example, if we take the previous example, we would get 0x60 (the value stored at 0x04 in calldata). If we add 4 to it, we get 0x64, which is the address where we get our string in the calldata.&lt;/p&gt;

&lt;p&gt;Then we use CALLDATACOPY to copy the string to memory. We hash it and store it. And we’re done 😎&lt;/p&gt;

&lt;p&gt;Yes this was a quick explanation for a complicated code, but with everything I explained to you until now, you should be able to understand it. If not, hit me up on Twitter &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;@0xteddav&lt;/a&gt; and i’ll help you.&lt;/p&gt;

&lt;h3&gt;
  
  
  addMultipleGuesses: use all our Yul knowledge
&lt;/h3&gt;

&lt;p&gt;Lastly, let’s reuse everything we just learned to loop through 2 arrays in assembly and store values to a mapping in storage! wow 🤯&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function addMultipleGuesses(address[] memory _users, uint[] memory _guesses) external {
        assembly {
            // remember: `_users` is the address in memory where the parameter starts
            // This is where the size of the array is stored. And then 32 bytes after, we have the values of the array
            // so here we load what's at address `_users` -&amp;gt; which is the size of the array `_users`
            let usersSize := mload(_users)

            // same for `_guesses`
            let guessesSize := mload(_guesses)

            // we check that both arrays are the same size
            // check EQ, ISZERO and REVERT opcodes on https://www.evm.codes/
            if iszero(eq(usersSize, guessesSize)) { revert(0, 0) }

            // we use a for-loop to loop through the items
            for { let i := 0 } lt(i, usersSize) { i := add(i, 1) } {
                // to get the ith value from the array we multiply i by 32 (0x20) and add it to `_users`
                // we always have to add 1 to i first, because remember that `_users` is the size of the array, the values start 32 bytes after
                // we could also do it this way (maybe it makes more sense):
                // let userAddress := mload(add(add(_users, 0x20), mul(0x20, i)))
                let userAddress := mload(add(_users, mul(0x20, add(i, 1))))
                let userBalance := mload(add(_guesses, mul(0x20, add(i, 1))))

                // we use the 0 memory slot as temporary storage to compute our hash
                // we store the address there
                mstore(0, userAddress)
                // then the slot number for `guesses`
                mstore(0x20, guesses.slot)
                // we compute the storage slot number
                let slot := keccak256(0, 0x40)
                // and store our value to it
                sstore(slot, userBalance)
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope the comments are clear enough. I’ll just add a few explanations.&lt;/p&gt;

&lt;p&gt;To check that both arrays are the same size, we use ISZERO and EQ opcodes. eq() takes 2 numbers as parameters and returns 1 if they are equal, 0 if not equal. Then we simply use iszero() to check the returned value from eq(). If they are not equal, we revert.&lt;/p&gt;

&lt;p&gt;iszero(eq(a, b)) is equivalent to &lt;code&gt;a != b&lt;/code&gt; in Solidity&lt;/p&gt;

&lt;p&gt;Finally the for-loop: the line to get the value from the parameter is a bit complicated. Let’s explain this one:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let userAddress := mload(add(_users, mul(0x20, add(i, 1))))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So remember that our users’ addresses (&lt;code&gt;_users&lt;/code&gt;) are written to memory by the EVM.&lt;/p&gt;

&lt;p&gt;The variable &lt;code&gt;_users&lt;/code&gt; is the address in memory where the length of the array is stored. So to get to the first value of the array we have to add 32 to it.&lt;/p&gt;

&lt;p&gt;Since we are in a for-loop, every iteration we need to add 32.&lt;/p&gt;

&lt;p&gt;So to get the current value we have 32*i + 32 → 32 * (i + 1) → which in assembly is &lt;code&gt;mul(0x20, add(i, 1))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To make it easier (and more gas efficient), we could have started the loop at i=1 to avoid all the &lt;code&gt;add(i, 1)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  You made it!
&lt;/h2&gt;

&lt;p&gt;So that’s it, we are done! We wrote an entire contract in assembly, and even did a bit of extra work (just for fun!).&lt;/p&gt;

&lt;p&gt;You can find the entire code used in that thread in this &lt;a href="https://gist.github.com/teddav/e5c77d36d76567631ba5898a64a79079" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt;. So that if you’re too lazy to re-write it, you can just copy it.&lt;/p&gt;

&lt;p&gt;If you have any question, hit me up on &lt;a href="https://twitter.com/0xteddav" rel="noopener noreferrer"&gt;Twitter @0xteddav&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know what you want me to write about next. Should I go deeper? Or write on another subject?&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
