<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Ruthu Rao</title>
        <link>https://paragraph.com/@ruthu</link>
        <description>undefined</description>
        <lastBuildDate>Fri, 16 Oct 2026 16:46:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Ruthu Rao</title>
            <url>https://storage.googleapis.com/papyrus_images/7dceadedd368a10fcc8c4c76c5082b2591e3e6a41488f1ee6fe03cfe648d94e7.jpg</url>
            <link>https://paragraph.com/@ruthu</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Route2 Web3 week 6-8]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week-6-8</link>
            <guid>8gKPd4PDK1yb5asE2Q2c</guid>
            <pubDate>Mon, 03 Apr 2023 19:39:47 GMT</pubDate>
            <description><![CDATA[Hey everyone! It&apos;s been a while, and it has been a roller coaster ride indeed. The past few weeks at EIF were the build phase, and it was all about implementing the different aspects of my project based on Wallet Security using MPC (multi-party computation) and ZKP (zero-knowledge proofs). It proposes a key recovery system using multi-party computation and zero-knowledge proofs to provide wallet security. The past few weeks were all about implementing Lagrange Interpolation or Gaussian e...]]></description>
            <content:encoded><![CDATA[<p>Hey everyone! It&apos;s been a while, and it has been a roller coaster ride indeed.</p><p>The past few weeks at EIF were the build phase, and it was all about implementing the different aspects of my project based on Wallet Security using MPC (multi-party computation) and ZKP (zero-knowledge proofs). It proposes a key recovery system using multi-party computation and zero-knowledge proofs to provide wallet security.</p><p>The past few weeks were all about implementing Lagrange Interpolation or Gaussian elimination in circom. Some of the things you need to know while working with circom is that it&apos;s restrictive, doesn&apos;t accept numbers beyond circom&apos;s range, it mods the negative values, and working with lots of constraints requires an understanding of how circuits work and of course how ZKP works. Overall, working with circom was a lot of fun and sleepless nights, but I wouldn&apos;t want it any other way.</p><p>The secret is split into shares in Shamir&apos;s Secret Sharing using polynomial interpolation. This polynomial interpolation can be accomplished using two methods: Lagrange interpolation and Gaussian elimination.</p><p>Lagrange interpolation is a method for constructing a polynomial of degree N-1 from a set of N elements. These N points correlate to N shares of the secret in Shamir&apos;s Secret Sharing. The Lagrange interpolation formula enables us to compute the value of the polynomial at any point, including zero, giving us the secret value. This is how the shares can be used to reconstruct the initial secret.</p><p>Gaussian elimination, on the other hand, is a method for resolving linear equation systems. In the setting of Shamir&apos;s Secret Sharing, we can represent each share as a linear equation and solve for the coefficients of the polynomial that corresponds to the secret using Gaussian elimination. We can reconstruct the secret using Lagrange interpolation once we have the polynomial values.</p><p>Both Lagrange interpolation and Gaussian elimination are used in Shamir&apos;s Secret Sharing to ensure that each share has an equal contribution to the reconstruction of the secret. These methods are also used to prevent any individual share from revealing any information about the secret, as each share only reveals information about a portion of the polynomial.</p><p>I got to integrate protocols like Push Protocol for notifications and Metamask Snaps for custom wallets.</p><p>The next few days were a deep dive into different cryptography algorithms, and I learned about different ways to implement MPC.</p><ul><li><p>Secret Sharing is a method in which a secret value is divided into multiple shares and distributed among the parties. Only by combining their interests can the parties reconstruct the secret.</p></li><li><p>Garbled Circuits: In this method, a circuit is built with encrypted inputs and garbled gates, so that the output of each gate is determined solely by the inputs to that gate. The parties then evaluate the jumbled circuit together to acquire the final output.</p></li><li><p>Homomorphic Encryption: This method enables computation on encrypted data without the need to decrypt it. The parties encrypt their inputs before performing operations on the encrypted data jointly to acquire the final result.</p></li><li><p>Oblivious Transfer: This method enables one party to transfer a value to another party while remaining unaware of the value or the recipient. The recipient can choose from a number of values without revealing which one they selected.</p></li><li><p>Secure Function Evaluation: This method involves estimating a function on the private inputs of multiple parties while keeping those inputs hidden from each other. To acquire the final output, the parties jointly evaluate the function using their private inputs and a shared randomness.</p></li></ul><p>The last few days have been about integrating the contract with the front end and setting everything up, as well as finding the right encryption method for passing my keys. Overall, this is still a work in progress, and I have many more features in mind.</p><p>Although this fellowship is coming to an end, the building never stops, and I will continue to blog about my journey. Keep building, folks! :)</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
        <item>
            <title><![CDATA[Route2 Web3: week5]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week5</link>
            <guid>XHEY4JydRPsSsgoSOwNO</guid>
            <pubDate>Mon, 13 Mar 2023 15:05:43 GMT</pubDate>
            <description><![CDATA[This week began with the build phase at EIF, and I worked on getting the project proposal ready. I was very interested in implementing something related to cryptography, so I came up with the idea of using MPC (Multiparty Computation) and ZK (Zero Knowledge) protocols. Before proceeding with this idea, I decided to revise my cryptography basics and deep dive into MPC to improve my understanding of it. If you’re wondering what MPC is, MPC stands for Multiparty Computation. Multiparty computati...]]></description>
            <content:encoded><![CDATA[<p>This week began with the build phase at EIF, and I worked on getting the project proposal ready. I was very interested in implementing something related to cryptography, so I came up with the idea of using MPC (Multiparty Computation) and ZK (Zero Knowledge) protocols. Before proceeding with this idea, I decided to revise my cryptography basics and deep dive into MPC to improve my understanding of it.</p><p>If you’re wondering what MPC is, MPC stands for Multiparty Computation.</p><p><strong><em>Multiparty computation</em></strong> (MPC) is a branch of cryptography that allows multiple parties to jointly compute a function over their private inputs without revealing those inputs to each other. In other words, it allows computation on data without requiring the data to be revealed to any single participant or central authority.</p><p>MPC algorithms ensure that each participant can obtain the computation&apos;s result without knowing the other parties&apos; data. This is accomplished through the use of cryptographic protocols such as secret sharing, homomorphic encryption, and garbled circuit</p><p>MPC paper I referred to :</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eprint.iacr.org/2020/300.pdf">https://eprint.iacr.org/2020/300.pdf</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7aaa1492461ab0edf82942991c4ac4278a3aa26c1721623c32bbdb38b10d793e.png" alt="UserFlow" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">UserFlow</figcaption></figure><h3 id="h-" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0"></h3><p><strong><em>Shamir&apos;s Secret Sharing</em></strong> is a cryptographic algorithm that divides a secret into multiple shares and distributes them among participants. This allows the secret to be rebuilt only if a large enough number of shares are combined, but not if only a few shares are available.</p><p>Adi Shamir created the algorithm in 1979, and it is based on polynomial interpolation. The secret is first encoded as a polynomial constant term, and then a number of random points on the polynomial are generated and distributed among the participants. Any subset of the participants can combine their shares to reconstruct the polynomial and thereby recover the secret. This can be proven using Zero-Knowledge.</p><p><strong><em>Zero-Knowledge-Proof</em></strong> (ZKP) is a cryptographic protocol that allows one party to prove to another that a particular statement is true without revealing any additional information other than the validity of the statement itself.</p><p>In a zero-knowledge proof, the party making the proof (known as the prover) can persuade the other party (known as the verifier) that a particular statement is true without revealing how they know it is true. The verifier is convinced that the statement is true because the proof is constructed in such a way that someone unfamiliar with the statement would be extremely unlikely to create a convincing proof of its truth.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/RuthuRao/status/1520014511654072320?s=20">https://twitter.com/RuthuRao/status/1520014511654072320?s=20</a></p><p>Writing these proofs in Circom has been a challenging but absolutely interesting experience. Circom is both a programming language and a toolset for building zero-knowledge proofs (ZKPs), which allows developers to design and compile circuits capable of generating ZKPs. These circuits can represent any computation that can be expressed as a directed acyclic graph (DAG), including arithmetic operations, Boolean logic, and more complex computations.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/RuthuRao/status/1633830388815790092?s=20">https://twitter.com/RuthuRao/status/1633830388815790092?s=20</a></p><p>Some of the objectives:</p><ul><li><p>Users can recover their account with just a part of their private key due to MPC.</p></li><li><p>The other parts of the key is stored at different locations and the location is secured via ZKP.</p></li><li><p>Allows for Secret key distribution among the user’s trusted accounts.</p></li><li><p>Allows users to recover keys without compromising security or privacy.</p></li><li><p>Prevents loss of funds due to lost or forgotten keys.</p></li><li><p>Provides an additional layer of security for cryptocurrency wallets.</p></li><li><p>Identity of the parties involved and the data they hold is unknown.</p></li></ul><p>This project solves the problem of users permanently losing access to their funds due to lost or forgotten private keys.</p><p>One of the main challenges of using cryptocurrencies is the risk of losing access to funds due to lost or stolen private keys. Private keys are used to access and manage cryptocurrency funds, and if they are lost or stolen, the user may permanently lose access to their funds. Key recovery wallets with MPC and ZKP solve this problem by offering a highly secure way to recover lost or stolen private keys.</p><p>Multiple parties can work together using MPC to reconstruct a user&apos;s private key without any one party having access to the full key. ZKP can be used to verify the correctness of the reconstructed key without revealing any additional information about the key itself.</p><p>This project proposes a key recovery system using multi-party computation and zero-knowledge proofs to provide wallet security. Unlike existing projects, this system allows wallet owners to recover keys without compromising their security or privacy. The existing projects use centralised servers to store the private keys, with this approach the private keys are only revealed if user’s authorised using ZKP.</p><p>Keep an eye out in the coming weeks! You&apos;ve made it to the end; please send me any articles related to the content above.</p><p>Keep building</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
        <item>
            <title><![CDATA[Route2 Web3: week4]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week4</link>
            <guid>435CUZhXcAXJg5ZhVBhz</guid>
            <pubDate>Fri, 03 Mar 2023 08:06:43 GMT</pubDate>
            <description><![CDATA[This week was all about understanding how multisigs and SVG NFTs work. https://github.com/route-2/challenge-5-multisig Learnt about meta transactions and off-chain signature-based shared wallet amongst different signers.//generates a unique hash for each transaction, function getTransactionHash(uint256 _nonce, address to, uint256 value, bytes memory data) public view returns (bytes32) { return keccak256(abi.encodePacked(address(this), chainId, _nonce, to, value, data)); } // executing a trans...]]></description>
            <content:encoded><![CDATA[<p>This week was all about understanding how multisigs and SVG NFTs work.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/route-2/challenge-5-multisig">https://github.com/route-2/challenge-5-multisig</a></p><p>Learnt about meta transactions and off-chain signature-based shared wallet amongst different signers.</p><pre data-type="codeBlock" text="//generates a unique hash for each transaction,
 function getTransactionHash(uint256 _nonce, address to, uint256 value, bytes memory data) public view returns (bytes32) {
        return keccak256(abi.encodePacked(address(this), chainId, _nonce, to, value, data));
    }

     // executing a transaction
    function executeTransaction(address payable to, uint256 value, bytes memory data, bytes[] memory signatures)
        public
        returns (bytes memory)
    {
        require(isOwner[msg.sender], &quot;executeTransaction: only owners can execute&quot;);
        bytes32 _hash =  getTransactionHash(nonce, to, value, data);
        nonce++;
        uint256 validSignatures;
        address duplicateGuard;
        for (uint i = 0; i &lt; signatures.length; i++) {
            address recovered = recover(_hash, signatures[i]);
            require(recovered &gt; duplicateGuard, &quot;executeTransaction: duplicate or unordered signatures&quot;);
            duplicateGuard = recovered;
            if(isOwner[recovered]){
              validSignatures++;
            }
        }
"><code><span class="hljs-comment">//generates a unique hash for each transaction,</span>
 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTransactionHash</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _nonce, <span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint256</span> value, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> data</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes32</span></span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">keccak256</span>(<span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>), chainId, _nonce, to, value, data));
    }

     <span class="hljs-comment">// executing a transaction</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">executeTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> to, <span class="hljs-keyword">uint256</span> value, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> data, <span class="hljs-keyword">bytes</span>[] <span class="hljs-keyword">memory</span> signatures</span>)
        <span class="hljs-title"><span class="hljs-keyword">public</span></span>
        <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span></span>)
    </span>{
        <span class="hljs-built_in">require</span>(isOwner[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>], <span class="hljs-string">"executeTransaction: only owners can execute"</span>);
        <span class="hljs-keyword">bytes32</span> _hash <span class="hljs-operator">=</span>  getTransactionHash(nonce, to, value, data);
        nonce<span class="hljs-operator">+</span><span class="hljs-operator">+</span>;
        <span class="hljs-keyword">uint256</span> validSignatures;
        <span class="hljs-keyword">address</span> duplicateGuard;
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">uint</span> i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> signatures.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
            <span class="hljs-keyword">address</span> recovered <span class="hljs-operator">=</span> recover(_hash, signatures[i]);
            <span class="hljs-built_in">require</span>(recovered <span class="hljs-operator">></span> duplicateGuard, <span class="hljs-string">"executeTransaction: duplicate or unordered signatures"</span>);
            duplicateGuard <span class="hljs-operator">=</span> recovered;
            <span class="hljs-keyword">if</span>(isOwner[recovered]){
              validSignatures<span class="hljs-operator">+</span><span class="hljs-operator">+</span>;
            }
        }
</code></pre><p>Typically, we process transactions directly on-chain, but this being a shared wallet with multiple addresses, we use Off-Chain Signature-Based Multi-Sig-Wallet.</p><p>Once the packed hash(packed hash (bytes32) is a way to represent a specific function call with its parameters as a single hash value) is generated, it can be signed by one of the signers associated with the Multisig wallet. This signature serves as a proof that the signer has authorised the execution of the corresponding function call with the specified parameters. The signature is then added to an array of signatures (bytes[] memory signatures), which contains all the signatures collected so far for the current transaction.</p><p>The user first creates a transaction that contains the necessary function call data and other parameters to carry out the desired action on the blockchain in to execute a meta transaction with an off-chain multisig wallet. The transaction is then encoded using a particular encoding technique, such as abi.encodePacked, into a packed hash (bytes32).</p><p>This packed hash is then signed by one of the signers associated with the multisig wallet using their private key. The signature is added to an array of signatures (bytes[] memory signatures), which is passed on along with the packed hash.</p><pre data-type="codeBlock" text="//Off-Chain code for getting the TX
const getSortedSigList = async (allSigs, newHash) =&gt; {
    console.log(&quot;allSigs&quot;, allSigs);

    const sigList = [];
    for (const s in allSigs) {
      console.log(&quot;SIG&quot;, allSigs[s]);
      const recover = await readContracts[contractName].recover(newHash, allSigs[s]);
      sigList.push({ signature: allSigs[s], signer: recover });
    }

    sigList.sort((a, b) =&gt; {
      return ethers.BigNumber.from(a.signer).sub(ethers.BigNumber.from(b.signer));
    });
"><code><span class="hljs-comment">//Off-Chain code for getting the TX</span>
const getSortedSigList <span class="hljs-operator">=</span> async (allSigs, newHash) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
    console.log(<span class="hljs-string">"allSigs"</span>, allSigs);

    const sigList <span class="hljs-operator">=</span> [];
    <span class="hljs-keyword">for</span> (const s in allSigs) {
      console.log(<span class="hljs-string">"SIG"</span>, allSigs[s]);
      const recover <span class="hljs-operator">=</span> await readContracts[contractName].recover(newHash, allSigs[s]);
      sigList.<span class="hljs-built_in">push</span>({ signature: allSigs[s], signer: recover });
    }

    sigList.sort((a, b) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
      <span class="hljs-keyword">return</span> ethers.BigNumber.from(a.signer).sub(ethers.BigNumber.from(b.signer));
    });
</code></pre><p>The smart contract that receives the transaction validates the signatures in the array to ensure that they match the signers&apos; public keys associated with the multisig wallet. If the signatures are valid, the transaction is carried out on the blockchain as the user requested.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/route-2/challenge-7-svg">https://github.com/route-2/challenge-7-svg</a></p><p>This challenge was about creating On-Chain SVG NFTs, most of the NFTs are usually IPFS hosted i.e, only the link is stored on blockchain and the metadata is stored on IPFS.</p><p>We can see this by querying the NFT contract&apos;s tokenURI. The data in SVG NFTs is stored entirely on-chain, directly in the smart contract. Instead of a link, the tokenURI returns encoded json data that includes SVG data that can be displayed in a browser.</p><p>SVG NFTs are also seen in projects like the Bored Ape Yacht Club which uses SVG NFTs to represent unique digital apes that have become highly popular collectibles,Gaming projects, such as Axie Infinity uses SVG NFTs to represent unique in-game creatures, Digital music-related SVG NFTs,Uniswap has launched LP as SVG NFTs in v3 implementation as well.</p><pre data-type="codeBlock" text="// SVG NFT data which is dynamic as the trait type &apos;color&apos; and &apos;chubbiness&apos; changes
function tokenURI(uint256 id) public view override returns (string memory) {
      require(_exists(id), &quot;not exist&quot;);
      string memory name = string(abi.encodePacked(&apos;Loogie #&apos;,id.toString()));
      string memory description = string(abi.encodePacked(&apos;This Loogie is the color #&apos;,color[id].toColor(),&apos; with a chubbiness of &apos;,uint2str(chubbiness[id]),&apos;!!!&apos;));
      string memory image = Base64.encode(bytes(generateSVGofTokenById(id)));

      return
          string(
              abi.encodePacked(
                &apos;data:application/json;base64,&apos;,
                Base64.encode(
                    bytes(
                          abi.encodePacked(
                              &apos;{&quot;name&quot;:&quot;&apos;,
                              name,
                              &apos;&quot;, &quot;description&quot;:&quot;&apos;,
                              description,
                              &apos;&quot;, &quot;external_url&quot;:&quot;https://burnyboys.com/token/&apos;,
                              id.toString(),
                              &apos;&quot;, &quot;attributes&quot;: [{&quot;trait_type&quot;: &quot;color&quot;, &quot;value&quot;: &quot;#&apos;,
                              color[id].toColor(),
                              &apos;&quot;},{&quot;trait_type&quot;: &quot;chubbiness&quot;, &quot;value&quot;: &apos;,
                              uint2str(chubbiness[id]),
                              &apos;}], &quot;owner&quot;:&quot;&apos;,
                              (uint160(ownerOf(id))).toHexString(20),
                              &apos;&quot;, &quot;image&quot;: &quot;&apos;,
                              &apos;data:image/svg+xml;base64,&apos;,
                              image,
                              &apos;&quot;}&apos;
                          )
                        )
                    )
              )
          );
  }
"><code><span class="hljs-comment">// SVG NFT data which is dynamic as the trait type 'color' and 'chubbiness' changes</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenURI</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> id</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">override</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>) </span>{
      <span class="hljs-built_in">require</span>(_exists(id), <span class="hljs-string">"not exist"</span>);
      <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> name <span class="hljs-operator">=</span> <span class="hljs-keyword">string</span>(<span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(<span class="hljs-string">'Loogie #'</span>,id.toString()));
      <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> description <span class="hljs-operator">=</span> <span class="hljs-keyword">string</span>(<span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(<span class="hljs-string">'This Loogie is the color #'</span>,color[id].toColor(),<span class="hljs-string">' with a chubbiness of '</span>,uint2str(chubbiness[id]),<span class="hljs-string">'!!!'</span>));
      <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> image <span class="hljs-operator">=</span> Base64.encode(<span class="hljs-keyword">bytes</span>(generateSVGofTokenById(id)));

      <span class="hljs-keyword">return</span>
          <span class="hljs-keyword">string</span>(
              <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
                <span class="hljs-string">'data:application/json;base64,'</span>,
                Base64.encode(
                    <span class="hljs-keyword">bytes</span>(
                          <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
                              <span class="hljs-string">'{"name":"'</span>,
                              name,
                              <span class="hljs-string">'", "description":"'</span>,
                              description,
                              <span class="hljs-string">'", "external_url":"https://burnyboys.com/token/'</span>,
                              id.toString(),
                              <span class="hljs-string">'", "attributes": [{"trait_type": "color", "value": "#'</span>,
                              color[id].toColor(),
                              <span class="hljs-string">'"},{"trait_type": "chubbiness", "value": '</span>,
                              uint2str(chubbiness[id]),
                              <span class="hljs-string">'}], "owner":"'</span>,
                              (<span class="hljs-keyword">uint160</span>(ownerOf(id))).toHexString(<span class="hljs-number">20</span>),
                              <span class="hljs-string">'", "image": "'</span>,
                              <span class="hljs-string">'data:image/svg+xml;base64,'</span>,
                              image,
                              <span class="hljs-string">'"}'</span>
                          )
                        )
                    )
              )
          );
  }
</code></pre><p>This allows you to generate SVGs</p><pre data-type="codeBlock" text="function generateSVGofTokenById(uint256 id) internal view returns (string memory) {

    string memory svg = string(abi.encodePacked(
      &apos;&lt;svg width=&quot;400&quot; height=&quot;400&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;&apos;,
        renderTokenById(id),
      &apos;&lt;/svg&gt;&apos;
    ));

    return svg;
  }
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateSVGofTokenById</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> id</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>) </span>{

    <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> svg <span class="hljs-operator">=</span> <span class="hljs-keyword">string</span>(<span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
      <span class="hljs-string">'&#x3C;svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">'</span>,
        renderTokenById(id),
      <span class="hljs-string">'&#x3C;/svg>'</span>
    ));

    <span class="hljs-keyword">return</span> svg;
  }
</code></pre><p>That’s about it thank you you’ve reached the end :) Subscribe to get notified</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
        <item>
            <title><![CDATA[Route2 Web3: week3]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week3</link>
            <guid>97o1GMf4dAujzjRpbwKB</guid>
            <pubDate>Fri, 24 Feb 2023 17:25:22 GMT</pubDate>
            <description><![CDATA[This week was the defi week and we got to work on building a decentralised exchange and also on layer-2 solutions like state channels. https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A To get an understanding how DEX really works I went through uniswap v1,v2 and v3. The newest v3 upgrade includes concentrated liquidity,Multiple fee tiers, and Customisable trading strategies.It also includes security features such as timelocks and access controls to prevent unaut...]]></description>
            <content:encoded><![CDATA[<p>This week was the defi week and we got to work on building a decentralised exchange and also on layer-2 solutions like state channels.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A">https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A</a></p><p>To get an understanding how DEX really works I went through uniswap v1,v2 and v3. The newest v3 upgrade includes concentrated liquidity,Multiple fee tiers, and Customisable trading strategies.It also includes security features such as timelocks and access controls to prevent unauthorised access or manipulation of the contract.</p><p>Uniswap v3 has five fee tiers: 0.05%, 0.3%, 1%, 3%, and 5%.</p><p>The fee tier is determined by the distance between the two ticks that define the liquidity range of the position. Positions with a narrower tick range (closer ticks) earn a lower fee, while positions with a wider tick range (farther ticks) earn a higher fee.</p><pre data-type="codeBlock" text="// Allows a user to add liquidity to the pool by depositing an equal value of two tokens in a specific price range defined by `tickLower` and `tickUpper`
function mint(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount,
        bytes calldata data
    ) external override lock returns (uint256 amount0, uint256 amount1) {
        require(amount &gt; 0);
        (, int256 amount0Int, int256 amount1Int) = _modifyPosition(
            ModifyPositionParams({
                owner: recipient,
                tickLower: tickLower,
                tickUpper: tickUpper,
                liquidityDelta: int256(amount).toInt128()
            })
        );

        amount0 = uint256(amount0Int);
        amount1 = uint256(amount1Int);

        uint256 balance0Before;
        uint256 balance1Before;
        if (amount0 &gt; 0) balance0Before = balance0();
        if (amount1 &gt; 0) balance1Before = balance1();
        IUniswapV3MintCallback(msg.sender).uniswapV3MintCallback(amount0, amount1, data);
        if (amount0 &gt; 0) require(balance0Before.add(amount0) &lt;= balance0(), &apos;M0&apos;);
        if (amount1 &gt; 0) require(balance1Before.add(amount1) &lt;= balance1(), &apos;M1&apos;);

        emit Mint(msg.sender, recipient, tickLower, tickUpper, amount, amount0, amount1);
    }
"><code><span class="hljs-comment">// Allows a user to add liquidity to the pool by depositing an equal value of two tokens in a specific price range defined by `tickLower` and `tickUpper`</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mint</span>(<span class="hljs-params">
        <span class="hljs-keyword">address</span> recipient,
        <span class="hljs-keyword">int24</span> tickLower,
        <span class="hljs-keyword">int24</span> tickUpper,
        <span class="hljs-keyword">uint128</span> amount,
        <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">calldata</span> data
    </span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">override</span></span> <span class="hljs-title">lock</span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span> amount0, <span class="hljs-keyword">uint256</span> amount1</span>) </span>{
        <span class="hljs-built_in">require</span>(amount <span class="hljs-operator">></span> <span class="hljs-number">0</span>);
        (, <span class="hljs-keyword">int256</span> amount0Int, <span class="hljs-keyword">int256</span> amount1Int) <span class="hljs-operator">=</span> _modifyPosition(
            ModifyPositionParams({
                owner: recipient,
                tickLower: tickLower,
                tickUpper: tickUpper,
                liquidityDelta: <span class="hljs-keyword">int256</span>(amount).toInt128()
            })
        );

        amount0 <span class="hljs-operator">=</span> <span class="hljs-keyword">uint256</span>(amount0Int);
        amount1 <span class="hljs-operator">=</span> <span class="hljs-keyword">uint256</span>(amount1Int);

        <span class="hljs-keyword">uint256</span> balance0Before;
        <span class="hljs-keyword">uint256</span> balance1Before;
        <span class="hljs-keyword">if</span> (amount0 <span class="hljs-operator">></span> <span class="hljs-number">0</span>) balance0Before <span class="hljs-operator">=</span> balance0();
        <span class="hljs-keyword">if</span> (amount1 <span class="hljs-operator">></span> <span class="hljs-number">0</span>) balance1Before <span class="hljs-operator">=</span> balance1();
        IUniswapV3MintCallback(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>).uniswapV3MintCallback(amount0, amount1, data);
        <span class="hljs-keyword">if</span> (amount0 <span class="hljs-operator">></span> <span class="hljs-number">0</span>) <span class="hljs-built_in">require</span>(balance0Before.add(amount0) <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">=</span> balance0(), <span class="hljs-string">'M0'</span>);
        <span class="hljs-keyword">if</span> (amount1 <span class="hljs-operator">></span> <span class="hljs-number">0</span>) <span class="hljs-built_in">require</span>(balance1Before.add(amount1) <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">=</span> balance1(), <span class="hljs-string">'M1'</span>);

        <span class="hljs-keyword">emit</span> Mint(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, recipient, tickLower, tickUpper, amount, amount0, amount1);
    }
</code></pre><p>In the DEX challenge we understood how AMM works, considering x * y = k</p><pre data-type="codeBlock" text="(amount of ETH in DEX ) * ( amount of tokens in DEX ) = k
"><code>(amount of ETH in DEX ) * ( amount of tokens in DEX ) = k
</code></pre><p>The <code>k</code> only changes as liquidity is added.</p><p>How does AMM really work?</p><ul><li><p>Consider An AMM has a pool of two assets, such as ETH and USDT.</p></li><li><p>Each asset is assigned a weight, which determines its relative value in the pool. For example, if ETH has a weight of 0.6 and USDT has a weight of 0.4, then ETH is considered to be worth more than USDT in the pool.</p></li><li><p>The product of the two assets&apos; balances in the pool is always kept constant. So, if the pool starts with 1 ETH and 100 USDT, the product is 1*100=100.</p></li><li><p>When a trader wants to buy or sell one of the assets, they trade with the AMM instead of another person. The AMM uses the constant product formula to determine the new price of the asset being bought or sold.</p></li><li><p>For example, if a trader wants to buy 0.1 ETH with their USDT, the AMM will calculate the new balances of ETH and USDT that will keep the product constant. Let&apos;s say the new ETH balance is 1.1 and the new USDT balance is 90.91. The new price of ETH is then calculated by dividing the new USDT balance by the new ETH balance, which gives us 90.91/1.1=82.64 USDT per ETH.</p></li><li><p>The AMM charges a small fee for each trade, which is added to the liquidity pool. This incentivises liquidity providers to add funds to the pool and earn a share of the trading fees.</p></li></ul><p>The functions for swapping from each asset to the other are <code>ethToToken()</code> and <code>tokenToEth()</code>. Each of these functions calculates the resulting amount of output asset using the price function that looks at the ratio of the reserves vs the input asset.</p><p>The <code>deposit()</code> function is used to deposit ETH and a corresponding ERC20 token into liquidity pool, which creates liquidity tokens in return. It calculates the amount of tokens to deposit based on the current reserve ratio of ETH and the ERC20 token in the pool, and then transfers the tokens from the sender to the liquidity pool contract. The function also mints new liquidity tokens for the sender and updates the total liquidity of the pool.</p><p>The <code>withdraw()</code> function is used to withdraw liquidity from the liquidity pool. The function takes as input the “amount of liquidity tokens” to withdraw and returns the corresponding “amount of ETH and ERC20 tokens”. The function calculates the amounts to withdraw based on the current reserve ratios and updates the sender&apos;s liquidity balance and the total liquidity of the pool accordingly. Finally, the function transfers the ETH and ERC20 tokens to the sender&apos;s address.</p><p>The function price() first includes 0.3% fee to the input token, and the 0.1% fee charged by the DEX on trades.</p><p>Watch this video for more understanding</p><div data-type="youtube" videoId="-JhgcqvyYeM">
      <div class="youtube-player" data-id="-JhgcqvyYeM" style="background-image: url('https://i.ytimg.com/vi/-JhgcqvyYeM/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=-JhgcqvyYeM">
          <img src="{{DOMAIN}}/editor/youtube/play.png" class="play"/>
        </a>
      </div></div><pre data-type="codeBlock" text="function price(
        uint256 xInput,
        uint256 xReserves,
        uint256 yReserves
    ) public view returns (uint256 yOutput) {
        uint256 xInputWithFee = xInput.mul(997);
        uint256 numerator = xInputWithFee.mul(yReserves);
        uint256 denominator = (xReserves.mul(1000)).add(xInputWithFee);
        return (numerator / denominator);
    }
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">price</span>(<span class="hljs-params">
        <span class="hljs-keyword">uint256</span> xInput,
        <span class="hljs-keyword">uint256</span> xReserves,
        <span class="hljs-keyword">uint256</span> yReserves
    </span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span> yOutput</span>) </span>{
        <span class="hljs-keyword">uint256</span> xInputWithFee <span class="hljs-operator">=</span> xInput.mul(<span class="hljs-number">997</span>);
        <span class="hljs-keyword">uint256</span> numerator <span class="hljs-operator">=</span> xInputWithFee.mul(yReserves);
        <span class="hljs-keyword">uint256</span> denominator <span class="hljs-operator">=</span> (xReserves.mul(<span class="hljs-number">1000</span>)).add(xInputWithFee);
        <span class="hljs-keyword">return</span> (numerator <span class="hljs-operator">/</span> denominator);
    }
</code></pre><p>Challenges I faced during this challenge was to implement the AMM in code, and passing the testcases.</p><p>Before I go ahead with the state channels challenge, here’s an overview of what state channels are ? what is the need of state channels?</p><p>As said in this tweet Ethereum is not your grandpa’s database and you don’t store everything and anything onchain.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/Kautukkundan/status/1626622768249962498?s=20">https://twitter.com/Kautukkundan/status/1626622768249962498?s=20</a></p><p>A number of approaches to scaling have been developed, collectively referred to as layer-2s (L2s). One of them being the State Channels.</p><p>In State Channels users agree on the initial state and multiple transactions are done off-chain and only the final state is updated on chain, in this way we save transaction fees and also the load on network.</p><p>They enable off-chain transactions between parties in a blockchain network. They involve opening a private communication channel between two parties and executing multiple transactions off-chain without the need to record them on the blockchain immediately.</p><p>In this challenge we have a service provider , the user who is seeking service pays the service provider for the service he/she is seeking. Before seeking service the user sends in some amount to the service provider and once the user is done with seeking service i.e, wishes to update the final state, the service provider updates the final state ON-CHAIN and takes in whatever amount that was required for providing this service.</p><p>The service provider verifies the signatures before finalising the state, and the signatures are also verified off chain before providing the service using elliptic curve recover operation. We pack the message, hash it and the digest is signed which is further verified on chain by <code>splitSignature()</code> based on solidity’s format where it’s checked if computed signer matches the actual signer.</p><p>If you want to read more into it!</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.ricmoo.com/verifying-messages-in-solidity-50a94f82b2ca">https://blog.ricmoo.com/verifying-messages-in-solidity-50a94f82b2ca</a></p><p>You’ve reached the end , stay tuned for my next weeks blog :)</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
        <item>
            <title><![CDATA[Route2 Web3: week 2]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week-2</link>
            <guid>CLHmxdFnJ1arjaXxkbGe</guid>
            <pubDate>Thu, 16 Feb 2023 14:14:45 GMT</pubDate>
            <description><![CDATA[This week was yet again interesting as we got to do the Token Vendor challenge and the Dice Game. It also included research on scaling and infra where I discovered various protocols and projects working on https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A In the Token Vendor Challenge I got to learn about the approve() in ERC20 and interaction of different contracts, it was more of getting the basics right by understanding the different functions under the ERC20...]]></description>
            <content:encoded><![CDATA[<p>This week was yet again interesting as we got to do the Token Vendor challenge and the Dice Game. It also included research on scaling and infra where I discovered various protocols and projects working on</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A">https://speedrunethereum.com/builders/0xFEa64Acb621B94a6Bc9eAbc966427B0C3687B22A</a></p><p>In the Token Vendor Challenge I got to learn about the approve() in ERC20 and interaction of different contracts, it was more of getting the basics right by understanding the different functions under the ERC20 contract itself and further implementing other functions by using this contract as an instance.</p><p>A withdraw() with onlyOwner as its modifier which allows the owner to withdraw the funds from the Vendor. We had to work on the option if the users wanted to sell the tokens that they bought.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/route-2/challenge-2-token-vendor">https://github.com/route-2/challenge-2-token-vendor</a></p><p>In the Dice game we learnt about randomization in soliidty, but also about how it is easily exploitable because instead of working on building the game itself we were asked to come up with ways of exploiting it.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/route-2/challenge-3-dice-game">https://github.com/route-2/challenge-3-dice-game</a></p><p>Blockchain is transparent and deterministic, meaning that once a block has been mined and added to the blockchain, its contents, including the hash value used for randomization, are public and cannot be changed. It’s easily exploitable as we only have to work on finding a pattern and using this pattern we could drain the contract.</p><p>It’s easily predictable by attackers to find a pattern and exploit the contract. This allows the attacker to manipulate the random number to their advantage and drain the funds from the contract.</p><p>In this contract we learnt about reentrancy attacks where we manipulated the original contract in another contract by implementing logic on the existing function which in turn drained the funds of target contract.</p><p>To avoid this as developers we use oracles or trusted third party services to generate random numbers which are designed to be unpredictable.Other ways to avoid would be to implement commit-and-reveal schemes or verifiable delay functions.</p><p>Commit-and-reveal-schemes is a two phase process where the hash of the number is first submitted to the smart contract by the user in the first phase and the user reveals the original number by submitting the actual value to the smart contract. The smart contract further verifies if the actual value matches to the submitted hash, this avoids the manipulation of the random number as it’s revealed only after the first phase i.e, the commit phase.</p><pre data-type="codeBlock" text="contract CommitReveal {
  bytes32 public commitHash;
  uint public revealNumber;
  bool public revealed;
  address public player;

  // Commit a number by submitting a hash of the number
  function commit(bytes32 hash) public {
    require(player == address(0), &quot;Commitment already made&quot;);
    commitHash = hash;
    player = msg.sender;
  }

  // Reveal the original number by submitting the actual value
  function reveal(uint number) public {
    require(!revealed, &quot;Already revealed&quot;);
    require(keccak256(abi.encodePacked(number)) == commitHash, &quot;Invalid reveal&quot;);
    revealNumber = number;
    revealed = true;
  }

  // Check if the reveal phase is complete and return the random number
  function getNumber() public view returns (uint) {
    require(revealed, &quot;Not revealed yet&quot;);
    return revealNumber;
  }
}
"><code><span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">CommitReveal</span> </span>{
  <span class="hljs-keyword">bytes32</span> <span class="hljs-keyword">public</span> commitHash;
  <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> revealNumber;
  <span class="hljs-keyword">bool</span> <span class="hljs-keyword">public</span> revealed;
  <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> player;

  <span class="hljs-comment">// Commit a number by submitting a hash of the number</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">commit</span>(<span class="hljs-params"><span class="hljs-keyword">bytes32</span> hash</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
    <span class="hljs-built_in">require</span>(player <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"Commitment already made"</span>);
    commitHash <span class="hljs-operator">=</span> hash;
    player <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
  }

  <span class="hljs-comment">// Reveal the original number by submitting the actual value</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reveal</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> number</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
    <span class="hljs-built_in">require</span>(<span class="hljs-operator">!</span>revealed, <span class="hljs-string">"Already revealed"</span>);
    <span class="hljs-built_in">require</span>(<span class="hljs-built_in">keccak256</span>(<span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(number)) <span class="hljs-operator">=</span><span class="hljs-operator">=</span> commitHash, <span class="hljs-string">"Invalid reveal"</span>);
    revealNumber <span class="hljs-operator">=</span> number;
    revealed <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
  }

  <span class="hljs-comment">// Check if the reveal phase is complete and return the random number</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getNumber</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
    <span class="hljs-built_in">require</span>(revealed, <span class="hljs-string">"Not revealed yet"</span>);
    <span class="hljs-keyword">return</span> revealNumber;
  }
}
</code></pre><p>Verifiable delay functions delays the selection of a random number for a specified period of time, and in this period the contract gathers additional inputs from participants or wait for external events.This delay in generating the random number makes it difficult for someone to predict what the random number will be ahead of time.</p><pre data-type="codeBlock" text="import &quot;@pooltogether/vdf-solidity/contracts/VDF.sol&quot;;

contract RandomNumberGenerator {
  VDF private vdf;

  constructor() {
    vdf = new VDF(1000); // set the VDF difficulty to 1000
  }

  function generateRandomNumber(uint256 input) public view returns (uint256) {
    uint256 output = vdf.evaluate(input);
    return output % 100; // return a random number between 0 and 99
  }
}
"><code><span class="hljs-keyword">import</span> <span class="hljs-string">"@pooltogether/vdf-solidity/contracts/VDF.sol"</span>;

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">RandomNumberGenerator</span> </span>{
  VDF <span class="hljs-keyword">private</span> vdf;

  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
    vdf <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> VDF(<span class="hljs-number">1000</span>); <span class="hljs-comment">// set the VDF difficulty to 1000</span>
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateRandomNumber</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> input</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>) </span>{
    <span class="hljs-keyword">uint256</span> output <span class="hljs-operator">=</span> vdf.evaluate(input);
    <span class="hljs-keyword">return</span> output <span class="hljs-operator">%</span> <span class="hljs-number">100</span>; <span class="hljs-comment">// return a random number between 0 and 99</span>
  }
}
</code></pre><p>Alright that’s about it stay tuned for more!</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
        <item>
            <title><![CDATA[Route2 Web3: week1]]></title>
            <link>https://paragraph.com/@ruthu/route2-web3-week1</link>
            <guid>D8fBoNXXVAhHsPgFntRy</guid>
            <pubDate>Fri, 10 Feb 2023 15:02:24 GMT</pubDate>
            <description><![CDATA[After dabbling around for a while in web3, I finally realized that everything I thought I know about, is only on a surface level. This journey of me unlearning things and learning things from a new perspective couldn’t have been possible without the EthIndia Fellowship and being ecstatic would be an understatement. I cannot wait to see what the end of this 8 week course holds for me as it definitely did start on a great note and I have to thank my fellows, mentors and the Devfolio team for th...]]></description>
            <content:encoded><![CDATA[<p>After dabbling around for a while in web3, I finally realized that everything I thought I know about, is only on a surface level. This journey of me unlearning things and learning things from a new perspective couldn’t have been possible without the EthIndia Fellowship and being ecstatic would be an understatement. I cannot wait to see what the end of this 8 week course holds for me as it definitely did start on a great note and I have to thank my fellows, mentors and the Devfolio team for this.</p><p>One of the things I look forward to in this fellowship apart from the tasks itself is the discord server because it’s POPPING off with all these deep tech cool blogs/articles and the nerdy geek in me is overjoyed.</p><p>I’m nice I like to share :)</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/cowswap/status/1623680760522612738?s=46&amp;t=gNak7U0Y3yIPf6wX1PPfow">https://twitter.com/cowswap/status/1623680760522612738?s=46&amp;t=gNak7U0Y3yIPf6wX1PPfow</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/joenrv.eth/DdbK6GR-CkeYxHoU8sKl0AFYbGeQwZcvCM5Qvzipr0g">https://mirror.xyz/joenrv.eth/DdbK6GR-CkeYxHoU8sKl0AFYbGeQwZcvCM5Qvzipr0g</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/0x6afeB3d9E380787e7D0a17Fc3CA764Bb885014FA/D3g-4UPRLkAnug-p6AZYfjgXWo-psaTulyu3SaL35vg">https://mirror.xyz/0x6afeB3d9E380787e7D0a17Fc3CA764Bb885014FA/D3g-4UPRLkAnug-p6AZYfjgXWo-psaTulyu3SaL35vg</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56">https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56</a></p><p>As I received the SBT, I also received my tasks for the week and this week was all about getting the basics right. Here’s my beautiful SBT :D</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/assets/0xfE8321Df99317C365797c4f95C2dbd9BeEC8C694/20">https://opensea.io/assets/0xfE8321Df99317C365797c4f95C2dbd9BeEC8C694/20</a></p><p>The week started of with a <strong>simple NFT Challenge</strong> which was an introduction to ERC721 and a walk through Scaffold.eth, I have to admit it was annoying initially but not more annoying than building a ui for every contract.</p><p>We had to build a contract which let users mint an NFT, and which further helped me get an idea about how users can purchase and sell NFTS.This challenge also helped me understand scaffold.eth better and the entire structure of Hardhat.</p><p>The second challenge was a <strong>Decentralised Staking App</strong>, where users can work towards a cause to raise funds and the funds are further sent to a second contract, if they don’t cooperate it’s sent back to them. This challenge was tricky initially as I was figuring out the wireframe, but it got easier to execute once I got the hang of it .</p><p>The challenge was tricky as I had initially used a If else() statement but considering each and every contract is open source and is deployed on the blockchain, we have to abide by strict conditions, due to this some of the test cases weren’t passing and replacing that with require() solved it.</p><p>Some of the mistakes I did was to not really read through the whole thing and I attempted to do it on my own, well of course the perks were that I got to learn a lot but the cons were the test cases ;( but going through the test cases individually was a lot more learning again!!</p><p>I conveniently used that One sad modifier in other functions as well.</p><p>I don’t know who needs to hear this but you don’t have to use <strong>require()</strong> every where because it really restricts the contract, and a simple <strong>If-else</strong> really serves the purpose.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b5792b83de349eb73da44efde1bbe9b413242b76ef35d016fe8f5aa7caa5dcc0.png" alt="Here&apos;s my Proof of Work ;D" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Here&apos;s my Proof of Work ;D</figcaption></figure><p>You’ve reached the end, and you can subscribe to see my route2 web3 ;)</p>]]></content:encoded>
            <author>ruthu@newsletter.paragraph.com (Ruthu Rao)</author>
        </item>
    </channel>
</rss>