<?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>DEV Community: sydneylai</title>
    <description>The latest articles on DEV Community by sydneylai (@sydneylai).</description>
    <link>https://dev.to/sydneylai</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%2F176573%2F1e525880-f5df-4ed3-8dd3-841c085dba6d.png</url>
      <title>DEV Community: sydneylai</title>
      <link>https://dev.to/sydneylai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sydneylai"/>
    <language>en</language>
    <item>
      <title>exploring business models for open-source projects</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Fri, 26 May 2023 17:56:22 +0000</pubDate>
      <link>https://dev.to/sydneylai/exploring-business-models-for-open-source-projects-4n9m</link>
      <guid>https://dev.to/sydneylai/exploring-business-models-for-open-source-projects-4n9m</guid>
      <description>&lt;p&gt;I'm on this journey to build a profitable open-source project (OSS). In my career I’ve worked as a developer advocate and helping devs navigate how to optimize their productivity with useful developer tools. I also deeply align with the vision of democratizing access to toolings to provide optionality for builders. &lt;/p&gt;

&lt;p&gt;I’ve seen role models in OSS and am on a journey to deconstruct their business models and see how this can be applied to open-source projects. For a few years I’ve been actively contributing to community-owned projects and toolings. If we take a look at the industry leaders: &lt;/p&gt;

&lt;p&gt;Red Hat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;owned by IBM&lt;/li&gt;
&lt;li&gt;Est. Revenue in fiscal year 2019 (before acquired by IBM) ~ $3.4B in revenue&lt;/li&gt;
&lt;li&gt;business model: enterprise solutions on LinuxOS, apps and services on OSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MongoDB (Database): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OSS NoSQL database&lt;/li&gt;
&lt;li&gt;business model: commercial licenses, enterprise support, and cloud-based services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker (Containerization): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool to build, package, and distribute applications using containers&lt;/li&gt;
&lt;li&gt;business model: commercial offerings (Docker Enterprise) for enterprise-grade container management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My experience having been involved in Yearn, token swaps (ie SushiSwap) and Gitcoin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business model: transaction fees (requires volume and velocity), TVL portfolio growth&lt;/li&gt;
&lt;li&gt;most of these OSS projects are funded by community money or Foundation grants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next step is exploring productizing AI-enabled products that improves the pain-points for devs or technical consumers. I’ve worked at companies where AI-assisted dev tools were greatly frowned upon. The 3 leading models for me are subscription plans, enterprise edition and building out a marketplace. The marketplace will be the long-term vision as the cold start problem then really requires momentum to overcome. &lt;/p&gt;

&lt;p&gt;Revenue models for open-source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;commercial licenses&lt;/li&gt;
&lt;li&gt;subscription plans ←&lt;/li&gt;
&lt;li&gt;enterprise edition ←&lt;/li&gt;
&lt;li&gt;support and maintenance&lt;/li&gt;
&lt;li&gt;consulting and professional services&lt;/li&gt;
&lt;li&gt;Cloud hosting&lt;/li&gt;
&lt;li&gt;marketplace ←&lt;/li&gt;
&lt;li&gt;data services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any suggestions or want to share your own journey building revenue-generating OSS, would love to start a conversation. My next steps are iterating on product and adoption, based on user-feedback on nascent AI developer experiences.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>opensource</category>
      <category>openai</category>
    </item>
    <item>
      <title>Anyone currently using AI-assisted indexing to build their "second brain"?</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Tue, 23 May 2023 18:33:27 +0000</pubDate>
      <link>https://dev.to/sydneylai/anyone-currently-using-ai-assisted-indexing-to-build-their-second-brain-kf0</link>
      <guid>https://dev.to/sydneylai/anyone-currently-using-ai-assisted-indexing-to-build-their-second-brain-kf0</guid>
      <description>&lt;h3&gt;
  
  
  1. How are you currently using AI-assisted indexing to build your information storage and retrieval?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2. Are we moving beyond input-oriented Notion documenting?
&lt;/h3&gt;

&lt;p&gt;As a self-proclaimed builder and lifelong learner, I often find myself juggling multiple projects and striving for continuous improvement. Our brains are not naturally wired for long-term storage and recall, which is why exploring methods that optimize our learning process becomes crucial. I recently have been experimenting with combining the PARA method and AI-assisted tools which is designed to help create a “second brain” for effective recall and organization.&lt;/p&gt;

&lt;p&gt;I did a quick search for “if i had a second brain” and found 20 million results on Reddit and 135 million on Google, it's clear there’s a user-base actively seeking ways to enhance their cognitive abilities and productivity. The PARA method, developed by Tiago Forte, provides a framework for organizing information into four categories: Projects, Areas, Resources, and Archives, enabling efficient knowledge structuring and retrieval. It’s like a kanban board for current knowledge acquisition vs long term storage knowledge indexing.&lt;/p&gt;

&lt;p&gt;It’s taxing for us to max-out our bandwidth with memory-intensive knowledge storing. Whereas we can recall a database of information to make more informed strategic decisions.&lt;br&gt;&lt;br&gt;
Alongside the PARA method, I’m exploring AI-assisted screen recording, specifically with a focus on encryption and secure data storage, as an added layer of recall. What’s top of mind for me is how AI-assisted apps handle encryption and security. &lt;/p&gt;

&lt;p&gt;Encryption:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementing end-to-end encryption for sensitive data protection&lt;/li&gt;
&lt;li&gt;Using strong encryption algorithms to safeguard data during storage and transmission&lt;/li&gt;
&lt;li&gt;Employing multi-factor authentication to enhance security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Secure data storage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploring privacy-focused and compliant cloud-based storage solutions&lt;/li&gt;
&lt;li&gt;Implementing robust access controls and permission settings&lt;/li&gt;
&lt;li&gt;Regularly backing up data and adopting disaster recovery measures&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. How are you using AI-assisted screen recording for enhancing productivity?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  4. What is the general consensus or your thoughts on how you’ve been incorporating AI-assisted indexing to build out your reference knowledgebase?
&lt;/h3&gt;

&lt;p&gt;Feel free to share below on how you’re currently building your second brain or coordinating your recall method. &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Your chaotic first Solidity tutorial</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Sun, 12 Feb 2023 15:24:22 +0000</pubDate>
      <link>https://dev.to/sydneylai/your-chaotic-first-solidity-tutorial-19bc</link>
      <guid>https://dev.to/sydneylai/your-chaotic-first-solidity-tutorial-19bc</guid>
      <description>&lt;p&gt;I'll do my best to guide you through your first Solidity tutorial, let's dig in!&lt;/p&gt;

&lt;p&gt;To provide you some context on why Solidity: Solidity is a high-level programming language that is used to write smart contracts for the Ethereum blockchain. In this tutorial, we will be exploring the basics of Solidity and how it is used to create decentralized applications (dApps) that run on the Ethereum network.&lt;/p&gt;

&lt;p&gt;If you're new to the world of blockchain and decentralized apps, don't worry! This tutorial is designed to be beginner-friendly and will guide you through the process of learning how to write smart contracts in Solidity. Whether you're a software developer looking to learn a new programming language or someone who is simply interested in learning more about blockchain technology, this tutorial is for you.&lt;/p&gt;

&lt;p&gt;In the following tutorial, we will cover topics such as variables, functions, events, mappings, arrays, contracts, inheritance, modifiers, and Ether transactions. By the end of this tutorial, you will have a half-baked understanding of the basics of Solidity and you will have deployed your first Solidity contract. Let's get started!&lt;/p&gt;




&lt;h2&gt;
  
  
  Set-up
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install NVM
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ - install nvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you have Homebrew already installed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install nvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install version 16&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nvm install 16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir hardhat-tutorial
$ cd hardhat-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a Node. js project
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev hardhat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want the package to be a development dependency&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &amp;amp; Update Script&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;https://github.com/nvm-sh/nvm&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] &amp;amp;&amp;amp; printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] &amp;amp;&amp;amp; \. "$NVM_DIR/nvm.sh" # This loads nvm 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nano ~/.zshrc
$ source ~/.zshrc
$ npx hardhat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And choose the JS option&lt;/p&gt;

&lt;p&gt;Install Solidity in your VSCode, from the Marketplace&lt;/p&gt;




&lt;h1&gt;
  
  
  Walking through the Lock.sol file
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;constructor&lt;/strong&gt; - what you run when you deploy a contract&lt;br&gt;
&lt;strong&gt;block.timestamp&lt;/strong&gt; - returns the timestamp of the block &lt;br&gt;
&lt;strong&gt;msg.sender&lt;/strong&gt; - refers to which ever address that deploys this contract&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;withdrawl&lt;/strong&gt; - is a public function that anyone can call&lt;/p&gt;

&lt;p&gt;However line 28 you can see there is a requirement that you must be the owner to withdrawl&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;require(msg.sender == owner, "You aren't the owner");&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;




&lt;h1&gt;
  
  
  Changing wallet receive functions
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Before
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
    uint public unlockTime;
    address payable public owner;

    event Withdrawal(uint amount, uint when);

    constructor(uint _unlockTime) payable {
        require(
            block.timestamp &amp;lt; _unlockTime,
            "Unlock time should be in the future"
        );

        unlockTime = _unlockTime;
        owner = payable(msg.sender);
    }

    function withdraw() public {
        // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
        // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

        require(block.timestamp &amp;gt;= unlockTime, "You can't withdraw yet");
        require(msg.sender == owner, "You aren't the owner");

        emit Withdrawal(address(this).balance, block.timestamp);

        owner.transfer(address(this).balance);
    }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  After
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
    uint public unlockTime;
    address payable public owner;
    address payable public receiver;

    event Withdrawal(uint amount, uint when);

    constructor(uint _unlockTime, address _receiver) payable {
        require(
            block.timestamp &amp;lt; _unlockTime,
            "Unlock time should be in the future"
        );

        unlockTime = _unlockTime;
        owner = payable(msg.sender);
        receiver = payable(_receiver);
    }

    function withdraw(address to) public {
        // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
        // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

        require(block.timestamp &amp;gt;= unlockTime, "You can't withdraw yet");
        require(msg.sender == owner || msg.sender == receiver, "You aren't the owner or receiver");

        emit Withdrawal(address(this).balance, block.timestamp);

        payable(to).transfer(address(this).balance);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  1. Compile
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat compile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to compile the contract before we are able to deploy it on chain!&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Run Tests
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They all fail because we changed the constructor so now the deployment fixture no longer works!&lt;/p&gt;

&lt;h1&gt;
  
  
  Lock.js
&lt;/h1&gt;

&lt;p&gt;Get ethers to get signers&lt;/p&gt;

&lt;h2&gt;
  
  
  Before
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
  time,
  loadFixture,
} = require("@nomicfoundation/hardhat-network-helpers");
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
const { expect } = require("chai");

describe("Lock", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshot in every test.
  async function deployOneYearLockFixture() {
    const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
    const ONE_GWEI = 1_000_000_000;

    const lockedAmount = ONE_GWEI;
    const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;

    // Contracts are deployed using the first signer/account by default
    const [owner, otherAccount] = await ethers.getSigners();

    const Lock = await ethers.getContractFactory("Lock");
    const lock = await Lock.deploy(unlockTime, { value: lockedAmount });

    return { lock, unlockTime, lockedAmount, owner, otherAccount };
  }

  describe("Deployment", function () {
    it("Should set the right unlockTime", async function () {
      const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);

      expect(await lock.unlockTime()).to.equal(unlockTime);
    });

    it("Should set the right owner", async function () {
      const { lock, owner } = await loadFixture(deployOneYearLockFixture);

      expect(await lock.owner()).to.equal(owner.address);
    });

    it("Should receive and store the funds to lock", async function () {
      const { lock, lockedAmount } = await loadFixture(
        deployOneYearLockFixture
      );

      expect(await ethers.provider.getBalance(lock.address)).to.equal(
        lockedAmount
      );
    });

    it("Should fail if the unlockTime is not in the future", async function () {
      // We don't use the fixture here because we want a different deployment
      const latestTime = await time.latest();
      const Lock = await ethers.getContractFactory("Lock");
      await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
        "Unlock time should be in the future"
      );
    });
  });

  describe("Withdrawals", function () {
    describe("Validations", function () {
      it("Should revert with the right error if called too soon", async function () {
        const { lock } = await loadFixture(deployOneYearLockFixture);

        await expect(lock.withdraw()).to.be.revertedWith(
          "You can't withdraw yet"
        );
      });

      it("Should revert with the right error if called from another account", async function () {
        const { lock, unlockTime, otherAccount } = await loadFixture(
          deployOneYearLockFixture
        );

        // We can increase the time in Hardhat Network
        await time.increaseTo(unlockTime);

        // We use lock.connect() to send a transaction from another account
        await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith(
          "You aren't the owner"
        );
      });

      it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
        const { lock, unlockTime } = await loadFixture(
          deployOneYearLockFixture
        );

        // Transactions are sent using the first signer by default
        await time.increaseTo(unlockTime);

        await expect(lock.withdraw()).not.to.be.reverted;
      });
    });

    describe("Events", function () {
      it("Should emit an event on withdrawals", async function () {
        const { lock, unlockTime, lockedAmount } = await loadFixture(
          deployOneYearLockFixture
        );

        await time.increaseTo(unlockTime);

        await expect(lock.withdraw())
          .to.emit(lock, "Withdrawal")
          .withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
      });
    });

    describe("Transfers", function () {
      it("Should transfer the funds to the owner", async function () {
        const { lock, unlockTime, lockedAmount, owner } = await loadFixture(
          deployOneYearLockFixture
        );

        await time.increaseTo(unlockTime);

        await expect(lock.withdraw()).to.changeEtherBalances(
          [owner, lock],
          [lockedAmount, -lockedAmount]
        );
      });
    });
  });
});

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

&lt;/div&gt;



&lt;p&gt;Add a receiver&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [owner, otherAccount, receiver] = await ethers.getSigners();&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Get receiver address&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const lock = await Lock.deploy(unlockTime, receiver.address{ value: lockedAmount });&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Test your current status
&lt;/h2&gt;

&lt;p&gt;At this point your current js file should look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;loadFixture&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="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@nomicfoundation/hardhat-network-helpers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;anyValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@nomicfoundation/hardhat-chai-matchers/withArgs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// We define a fixture to reuse the same setup in every test.&lt;/span&gt;
  &lt;span class="c1"&gt;// We use loadFixture to run this setup once, snapshot that state,&lt;/span&gt;
  &lt;span class="c1"&gt;// and reset Hardhat Network to that snapshot in every test.&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deployOneYearLockFixture&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;ONE_YEAR_IN_SECS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;ONE_GWEI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000_000&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;lockedAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ONE_GWEI&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;unlockTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ONE_YEAR_IN_SECS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Contracts are deployed using the first signer/account by default&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;otherAccount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&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;Lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lock&lt;/span&gt;&lt;span class="dl"&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;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;otherAccount&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Deployment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should set the right unlockTime&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should set the right owner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should receive and store the funds to lock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;lockedAmount&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should fail if the unlockTime is not in the future&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// We don't use the fixture here because we want a different deployment&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&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;Lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latestTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&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="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revertedWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unlock time should be in the future&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Withdrawals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Validations&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should revert with the right error if called too soon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revertedWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You can't withdraw yet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should revert with the right error if called from another account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;otherAccount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// We can increase the time in Hardhat Network&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increaseTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// We use lock.connect() to send a transaction from another account&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;otherAccount&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revertedWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You aren't the owner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shouldn't fail if the unlockTime has arrived and the owner calls it&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Transactions are sent using the first signer by default&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increaseTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reverted&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Events&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should emit an event on withdrawals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increaseTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Withdrawal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lockedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;anyValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// We accept any value as `when` arg&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Transfers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should transfer the funds to the owner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;deployOneYearLockFixture&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increaseTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;changeEtherBalances&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lockedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lockedAmount&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="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;&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%2F9r5g0v9nztuix67xptat.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%2F9r5g0v9nztuix67xptat.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently you should be passing your first 3 tests&lt;/p&gt;

&lt;p&gt;Now we can go fix the actual tests&lt;/p&gt;

&lt;p&gt;Now add a receiver parameter&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;await expect(Lock.deploy(latestTime, receiver.address, { value: 1 })).to.be.revertedWith(&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Now define and include the signer object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      const latestTime = await time.latest();
      const Lock = await ethers.getContractFactory("Lock");
      const [owner, otherAccount, receiver] = await ethers.getSigners();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test again and at this point your fourth test should pass&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%2Fv52eza9nh7x0ei1hdfkz.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%2Fv52eza9nh7x0ei1hdfkz.png" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now include the same receiver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        const { lock, receiver } = await loadFixture(deployOneYearLockFixture);

        await expect(lock.withdraw(receiver.address)).to.be.revertedWith(
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're not withdrawing to yourself but to the receiver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await expect(lock.connect(otherAccount).withdraw(otherAccount.address)).to.be.revertedWith(

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

&lt;/div&gt;



&lt;p&gt;You are now not the owner or receiver&lt;/p&gt;

&lt;p&gt;Now update and include receivers&lt;/p&gt;

&lt;p&gt;Lock.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
  time,
  loadFixture,
} = require("@nomicfoundation/hardhat-network-helpers");
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
const { expect } = require("chai");

describe("Lock", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshot in every test.
  async function deployOneYearLockFixture() {
    const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
    const ONE_GWEI = 1_000_000_000;

    const lockedAmount = ONE_GWEI;
    const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;

    // Contracts are deployed using the first signer/account by default
    const [owner, otherAccount, receiver] = await ethers.getSigners();

    const Lock = await ethers.getContractFactory("Lock");
    const lock = await Lock.deploy(unlockTime, receiver.address, { value: lockedAmount });

    return { lock, unlockTime, receiver, lockedAmount, owner, otherAccount };
  }

  describe("Deployment", function () {
    it("Should set the right unlockTime", async function () {
      const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);

      expect(await lock.unlockTime()).to.equal(unlockTime);
    });

    it("Should set the right owner", async function () {
      const { lock, owner } = await loadFixture(deployOneYearLockFixture);

      expect(await lock.owner()).to.equal(owner.address);
    });

    it("Should receive and store the funds to lock", async function () {
      const { lock, lockedAmount } = await loadFixture(
        deployOneYearLockFixture
      );

      expect(await ethers.provider.getBalance(lock.address)).to.equal(
        lockedAmount
      );
    });

    it("Should fail if the unlockTime is not in the future", async function () {
      // We don't use the fixture here because we want a different deployment
      const latestTime = await time.latest();
      const Lock = await ethers.getContractFactory("Lock");
      const [owner, otherAccount, receiver] = await ethers.getSigners();
      await expect(Lock.deploy(latestTime, receiver.address, { value: 1 })).to.be.revertedWith(
        "Unlock time should be in the future"
      );
    });
  });

  describe("Withdrawals", function () {
    describe("Validations", function () {
      it("Should revert with the right error if called too soon", async function () {
        const { lock, receiver } = await loadFixture(deployOneYearLockFixture);

        await expect(lock.withdraw(receiver.address)).to.be.revertedWith(
          "You can't withdraw yet"
        );
      });

      it("Should revert with the right error if called from another account", async function () {
        const { lock, unlockTime, otherAccount } = await loadFixture(
          deployOneYearLockFixture
        );

        // We can increase the time in Hardhat Network
        await time.increaseTo(unlockTime);

        // We use lock.connect() to send a transaction from another account
        await expect(lock.connect(otherAccount).withdraw(otherAccount.address)).to.be.revertedWith(
          "You aren't the owner or receiver"
        );
      });

      it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
        const { lock, unlockTime, receiver } = await loadFixture(
          deployOneYearLockFixture
        );

        // Transactions are sent using the first signer by default
        await time.increaseTo(unlockTime);

        await expect(lock.withdraw(receiver.address)).not.to.be.reverted;
      });
    });

    describe("Events", function () {
      it("Should emit an event on withdrawals", async function () {
        const { lock, unlockTime, lockedAmount, receiver} = await loadFixture(
          deployOneYearLockFixture
        );

        await time.increaseTo(unlockTime);

        await expect(lock.withdraw(receiver.address))
          .to.emit(lock, "Withdrawal")
          .withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
      });
    });

    describe("Transfers", function () {
      it("Should transfer the funds to the receiver", async function () {
        const { lock, unlockTime, lockedAmount, owner, receiver } = await loadFixture(
          deployOneYearLockFixture
        );

        await time.increaseTo(unlockTime);

        await expect(lock.withdraw(receiver.address)).to.changeEtherBalances(
          [receiver, lock],
          [lockedAmount, -lockedAmount]
        );
      });
    });
  });
});

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

&lt;/div&gt;



&lt;p&gt;Lock.sol&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: UNLICENSED
pragma solidity ^0.8.9;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
    uint public unlockTime;
    address payable public owner;
    address payable public receiver;

    event Withdrawal(uint amount, uint when);

    constructor(uint _unlockTime, address _receiver) payable {
        require(
            block.timestamp &amp;lt; _unlockTime,
            "Unlock time should be in the future"
        );

        unlockTime = _unlockTime;
        owner = payable(msg.sender);
        receiver = payable(_receiver);
    }

    function withdraw(address to) public {
        // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
        // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

        require(block.timestamp &amp;gt;= unlockTime, "You can't withdraw yet");
        require(msg.sender == owner || msg.sender == receiver, "You aren't the owner or receiver");

        emit Withdrawal(address(this).balance, block.timestamp);

        payable(to).transfer(address(this).balance);
    }
}

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

&lt;/div&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%2Fc6fhmwrd8gdeicuouejn.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%2Fc6fhmwrd8gdeicuouejn.png" alt="Image description" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploy.js Original&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// We require the Hardhat Runtime Environment explicitly here. This is optional&lt;/span&gt;
&lt;span class="c1"&gt;// but useful for running the script in a standalone fashion through `node &amp;lt;script&amp;gt;`.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// You can also run a script with `npx hardhat run &amp;lt;script&amp;gt;`. If you do that, Hardhat&lt;/span&gt;
&lt;span class="c1"&gt;// will compile your contracts, add the Hardhat Runtime Environment's members to the&lt;/span&gt;
&lt;span class="c1"&gt;// global scope, and execute the script.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;currentTimestampInSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&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;ONE_YEAR_IN_SECS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;unlockTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTimestampInSeconds&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ONE_YEAR_IN_SECS&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;lockedAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&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;Lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lock&lt;/span&gt;&lt;span class="dl"&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;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`Lock with 1 ETH and unlock timestamp &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deployed to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// We recommend this pattern to be able to use async/await everywhere&lt;/span&gt;
&lt;span class="c1"&gt;// and properly handle errors.&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Has to pass as an argument to deploy it&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[owner, receiver] = await ethers.getSigners()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;And add a receiver addresss&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const lock = await Lock.deploy(unlockTime, receiver.address, { value: lockedAmount });&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// We require the Hardhat Runtime Environment explicitly here. This is optional&lt;/span&gt;
&lt;span class="c1"&gt;// but useful for running the script in a standalone fashion through `node &amp;lt;script&amp;gt;`.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// You can also run a script with `npx hardhat run &amp;lt;script&amp;gt;`. If you do that, Hardhat&lt;/span&gt;
&lt;span class="c1"&gt;// will compile your contracts, add the Hardhat Runtime Environment's members to the&lt;/span&gt;
&lt;span class="c1"&gt;// global scope, and execute the script.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&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;hre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;currentTimestampInSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&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;ONE_YEAR_IN_SECS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;unlockTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTimestampInSeconds&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ONE_YEAR_IN_SECS&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;lockedAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&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;Lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lock&lt;/span&gt;&lt;span class="dl"&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;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lockedAmount&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`Lock with 1 ETH and unlock timestamp &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;unlockTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deployed to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// We recommend this pattern to be able to use async/await everywhere&lt;/span&gt;
&lt;span class="c1"&gt;// and properly handle errors.&lt;/span&gt;
&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node scripts/deploy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need two terminals to run the node &lt;/p&gt;

&lt;p&gt;If your hardhat is not globally installed, ensure the second terminal has to be in the same folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat node --verbose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Deployed 🎉
&lt;/h1&gt;

&lt;p&gt;Deploy your tokens to the receiver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat --network localhost run scripts.deploy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fvhrba5vcarw93znsvk2e.jpg" 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%2Fvhrba5vcarw93znsvk2e.jpg" width="800" height="735"&gt;&lt;/a&gt;&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%2Fko2cn37jehcwx1ho3yrm.gif" 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%2Fko2cn37jehcwx1ho3yrm.gif" alt="Image description" width="498" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I guess you can call yourself a solidity dev now&lt;/p&gt;

&lt;p&gt;⚒️ &lt;a href="https://twitter.com/sydneylai" rel="noopener noreferrer"&gt;@sydneylai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to mentor &lt;a href="https://twitter.com/afk0b" rel="noopener noreferrer"&gt;@afk0b&lt;/a&gt; &lt;/p&gt;

</description>
      <category>leadership</category>
      <category>mentorship</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Build a Decentralized Ridesharing App - For Beginners</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Tue, 26 Apr 2022 17:16:10 +0000</pubDate>
      <link>https://dev.to/sydneylai/build-a-decentralized-ridesharing-app-for-beginners-5bff</link>
      <guid>https://dev.to/sydneylai/build-a-decentralized-ridesharing-app-for-beginners-5bff</guid>
      <description>&lt;p&gt;Author Twitter: &lt;a href="https://twitter.com/sydneylai"&gt;@sydneylai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the question I asked myself is why we don't have a decentralized Uber or ridesharing app. &lt;/p&gt;

&lt;p&gt;I realized it's pretty hard to build, so in today's lesson I'm going to showcase a beginner example of how to build a database of drivers and passengers and how to match them. &lt;/p&gt;

&lt;p&gt;MVP: Matching drivers and passengers based on their matching zip codes in their metro area. Showcase publishing and subscribing within the terminal &lt;br&gt;
Creating the json files for the passengers and drivers&lt;/p&gt;

&lt;p&gt;Idea: &lt;br&gt;
    Create a set of aggregators in the middle between the publishers and the subscribers. For example Google News: the news gets published but Google News aggregates the news. Instead of Google News, now IPFS is in the middle and the topic is drivers and passengers. The idea is the passenger broadcasts their location and the driver subscribes to their topic. The driver will publish and the passenger will subscribe. &lt;/p&gt;

&lt;p&gt;Level 1: passenger publish, and all drivers in that area will subscribe&lt;br&gt;
Level 2: Driver will publish to that specifically and the passenger will subscribe or tell the Driver that they accept that fare. The acceptance will then be published to the driver's topic. &lt;/p&gt;

&lt;p&gt;Resources Used: &lt;br&gt;
    &lt;a href="https://blog.ipfs.io/25-pubsub/"&gt;https://blog.ipfs.io/25-pubsub/&lt;/a&gt;&lt;br&gt;
    &lt;a href="https://docs.ipfs.io/reference/cli/#ipfs-pubsub"&gt;https://docs.ipfs.io/reference/cli/#ipfs-pubsub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Design: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List of drivers

&lt;ul&gt;
&lt;li&gt;Driver Object should be a JSON object, python dictionary of values 

&lt;ul&gt;
&lt;li&gt;Name of driver, the value (zipcode) of the driver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;List of passengers

&lt;ul&gt;
&lt;li&gt;Passenger Object should be a JSON object, python dictionary of values 

&lt;ul&gt;
&lt;li&gt;Name of driver, the value (zipcode) of the driver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Function: randomly assigns Driver and Passenger if they are in the same zipcode &lt;/li&gt;
&lt;li&gt;Result: Driver 1 is matched with Passenger 1&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Backend "database":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;(Decentralized) P2P database IPFS/distributed file systems&lt;/li&gt;
&lt;li&gt;(Centralized) Created a small SQL database example to show comparison &lt;/li&gt;
&lt;li&gt;The centralized database was in the demo.py file &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Idea: Is to wrap the shell commands with python code so can write python code in the command line - however this would require writing API REQUESTS&lt;/p&gt;

&lt;p&gt;What we ended executing on: We demonstrated the demo by using curl commands in the terminal &lt;/p&gt;
&lt;h2&gt;
  
  
  Centralized Example
&lt;/h2&gt;

&lt;p&gt;I will showcase what a centralized approach would look like, to contrast against a decentralized ridesharing approach. This centralized approach is what developers are typically more familiar with.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Python file&lt;/li&gt;
&lt;li&gt;Centralized database with SQL
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlite3&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;

&lt;span class="c1"&gt;#first create connection function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;""" create a database connection to the SQLite database
        specified by db_file
    :param db_file: database file
    :return: Connection object or None
    """&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_file&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;conn&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&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;conn&lt;/span&gt;

&lt;span class="c1"&gt;#second create table function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_table_sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;""" create a table from the create_table_sql statement
    :param conn: Connection object
    :param create_table_sql: a CREATE TABLE statement
    :return:
    """&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;create_table_sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_driver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Create a new driver
    :param conn:
    :param driver:
    :return:
    """&lt;/span&gt;

    &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;''' INSERT INTO drivers(name,zipcodes)
              VALUES(?,?) '''&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# this inserts the driver into the database
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastrowid&lt;/span&gt;
&lt;span class="c1"&gt;#third create a main function to create the passenger, in this example you would create a API request to publish the passenger (Decetralized matching, you create the copy and the idea is that it becomes decentralied)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_passenger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Create a new passenger
    :param conn:
    :param passenger:
    :return:
    """&lt;/span&gt;

    &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;''' INSERT INTO passengers(name,zipcodes)
              VALUES(?,?) '''&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# this return function is a webrequest return, you would return the value of the webrequest - success!
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastrowid&lt;/span&gt;
&lt;span class="c1"&gt;#fourth create a main function to create the drivers and passenger tables
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_drivers_passengers&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;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;"pythonsqlite.db"&lt;/span&gt;

    &lt;span class="c1"&gt;# create a database connection
&lt;/span&gt;    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# create a new driver
&lt;/span&gt;        &lt;span class="n"&gt;driver1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'92802'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;driver1ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_driver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# passenger
&lt;/span&gt;        &lt;span class="n"&gt;passenger_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Sydney'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'92704'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;passenger_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Rob'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'92802'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# create passenger
&lt;/span&gt;        &lt;span class="n"&gt;create_passenger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passenger_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;create_passenger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passenger_2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_drivers_passengers_table&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;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;"pythonsqlite.db"&lt;/span&gt;

    &lt;span class="n"&gt;sql_create_drivers_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""" -- drivers table
                                CREATE TABLE IF NOT EXISTS drivers (
                                    id integer PRIMARY KEY,
                                    name text NOT NULL,
                                    zipcodes text NOT NULL
                                    );"""&lt;/span&gt;

    &lt;span class="n"&gt;sql_create_passengers_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"""-- passengers table
                                CREATE TABLE IF NOT EXISTS passengers (
                                    id integer PRIMARY KEY,
                                    name text NOT NULL,
                                    zipcodes text NOT NULL
                                );"""&lt;/span&gt;
    &lt;span class="c1"&gt;# create a database connection
&lt;/span&gt;    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# create tables to create the connection
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# create drivers table
&lt;/span&gt;        &lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql_create_drivers_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# create passengers table
&lt;/span&gt;        &lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql_create_passengers_table&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error! cannot create the database connection."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#Fifth, reconnect database and extract from that database
&lt;/span&gt;
&lt;span class="c1"&gt;# This would have been an API Request to my 127001 - would subscribe and get back all the passengers
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_all_passengers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Query all rows in the passengers table
    :param conn: the Connection object
    :return:
    """&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM passengers"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#fetch all the rows but this does not return anything
&lt;/span&gt;    &lt;span class="n"&gt;passenger_list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;row&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="s"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;row&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="c1"&gt;#reconnect db and extract from that db
&lt;/span&gt;        &lt;span class="n"&gt;passenger_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passenger&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;passenger_list&lt;/span&gt;    


&lt;span class="c1"&gt;#run this function, and call this function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_all_drivers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Query all rows in the drivers table
    :param conn: the Connection object
    :return:
    """&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM drivers"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;driver_list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;row&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="s"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;row&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="c1"&gt;#reconnect db and extract from that db
&lt;/span&gt;        &lt;span class="n"&gt;driver_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&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;driver_list&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;drivers&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;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;"pythonsqlite.db"&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&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;select_all_drivers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;passengers&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;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;"pythonsqlite.db"&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&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;select_all_passengers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;passenger&lt;/span&gt;
&lt;span class="c1"&gt;#make passenger as an argument to match
&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;driver_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;passenger_zipcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;driver_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;driverzipcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"zipcode"&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;driverzipcode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;passenger_zipcode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;#== bc test for equality
&lt;/span&gt;            &lt;span class="n"&gt;drivername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;passengername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;drivername&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;passengername&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
            &lt;span class="c1"&gt;#rememeber to format with f
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;create_drivers_passengers_table&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;#create_drivers_passengers() - this is redundant, does not need to be run more than once
&lt;/span&gt;    &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;"pythonsqlite.db"&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;#select_all_passengers(conn) - these are stepping stones to get database to work
&lt;/span&gt;    &lt;span class="c1"&gt;#select_all_drivers(conn) - these are stepping stones to get database to work
&lt;/span&gt;
    &lt;span class="n"&gt;passenger_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;passengers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;#conn is the connection to the database
&lt;/span&gt;    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passenger_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;passenger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;passenger_list&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="c1"&gt;#takes first passenger out of the list and calls it passenger
&lt;/span&gt;    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Create Table
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;create connection function&lt;/li&gt;
&lt;li&gt;create table function&lt;/li&gt;
&lt;li&gt;create main function to create drivers and passengers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Edit the template to equal to passengers&lt;/p&gt;

&lt;p&gt;Table names must map, and turn those into DB&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Driver Name
Driver Zipcodes
Passenger Name
Pasenger Zipcodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lesson: database is hardcoded within python file&lt;/p&gt;

&lt;h2&gt;
  
  
  Decentralized Example
&lt;/h2&gt;

&lt;p&gt;Building a decentralized example of ridesharing matching, showcases how we as developers have to rethink how to build a "database" of drivers and passengers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a json file for each driver and each passenger&lt;/li&gt;
&lt;li&gt;Matching the driver and passengers with the IPFS pubsub method via curl commands in the terminal to showcase peer to peer to matching&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;driver1.json&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="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Todd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"33101"&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;p&gt;driver2.json&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"33129"&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;p&gt;passenger1.json&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="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"33101"&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;p&gt;passenger2.json&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="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Sally"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zipcode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"33129"&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;p&gt;These json files require less code than a traditional python file with a centralized database.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a Topic - via JSON file&lt;br&gt;
Every passenger would have their own JSON (JSON formmated payloads) file, so if this app had 20M passengers there would be 20M JSON files. So here you can see another perspective of having a decentralized database because you would need 20M individual JSON files rather than having 20M rows in a single database. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a Passenger File&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a Driver File&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish passenger file to passenger topic &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish driver file to driver topic &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subscribe to passenger topic to get location&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point I've created JSON files for Passengers and Drivers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a database as an end point
&lt;/h2&gt;

&lt;p&gt;Install the IPFS&lt;br&gt;
    &lt;a href="https://docs.ipfs.io/install/command-line/#official-distributions"&gt;https://docs.ipfs.io/install/command-line/#official-distributions&lt;/a&gt;&lt;br&gt;
Once IPFS is installed you can call the daemon from the Command Line.&lt;/p&gt;

&lt;p&gt;To store Drivers and Passengers, each profile would be json files in IPFS.&lt;br&gt;
    - List of Drivers with zip codes as a file&lt;br&gt;
    - List of Passengers with zip codes as a file&lt;br&gt;
    Every file would be published with a curl command to the local host 127001.&lt;br&gt;
    Each driver/passenger would publish their own request, and pull each other's profiles. Each file would be their own driver/passenger profile.&lt;/p&gt;

&lt;p&gt;Lesson: at this point, I have: &lt;br&gt;
    - Learned how to interact with IPFS&lt;br&gt;
    - Installed IPFS in the terminal &lt;a href="https://docs.ipfs.io/install/command-line/#official-distributions"&gt;https://docs.ipfs.io/install/command-line/#official-distributions&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Start the daemon
&lt;/h2&gt;

&lt;p&gt;Installing the IPFS is like building the post-office. Publishing a JSON file would be putting a letter in the mail. &lt;/p&gt;

&lt;p&gt;Start the daemon to run in the background, like opening the post-office:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```sudo ipfs daemon```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by starting the IPFS daemon&lt;/p&gt;

&lt;p&gt;IPFS generates a hash in the system to provide a unique identifier. &lt;/p&gt;

&lt;p&gt;Driver1 Hash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hash":"QmWFRKVtsJCdwPaD3SozvSwMdhxo3EJLpEv4LMoPcqopoX"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Driver 2 Hash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hash":"QmUr2jDAeWpVFX6s6fkCLGoQCn8SpDaQQMqZazJSiomZKj"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, we are trying list all file objects loaded in IPFS, to do so we need to know our Hash. &lt;/p&gt;

&lt;p&gt;When running curl commands we directly interacted with IPFS. &lt;/p&gt;

&lt;p&gt;The webapp would send request to sever (or in this case, a decenetralized file system) and now all these hashes are stored in a JSON server. &lt;/p&gt;

&lt;p&gt;Lesson: At this point I am able to upload the JSON files for Drivers and Passengers with a curl command.&lt;/p&gt;

&lt;p&gt;Next Steps:&lt;br&gt;
    1. assign a Topic&lt;br&gt;
    2. and then pub/sub&lt;/p&gt;

&lt;p&gt;A topic can be constructed however you want, so if you had a topic for a particular zip code, then everyone subscribed to that zip code will see all messages published to it. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST -F file=@myfile "http://127.0.0.1:5001/api/v0/pubsub/pub?arg=90011"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would publish to the topic (in this case a zip code) "90011" if you wanted to sub, so you can retrieve all messages sent to that zip code with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST "http://127.0.0.1:5001/api/v0/pubsub/sub?arg=90011"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the terminal, this command should retrieve all previous CIDs (content identifier) I've created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ipfs pin ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;QmejvEPop4D7YUadeGqYWmZxHhLc4JBUCzJJHWMzdcMe2y indirect&lt;br&gt;
QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm indirect&lt;br&gt;
QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y indirect&lt;br&gt;
QmdvS8djomKst8dkkahdCsDkyWjkH3D5yeXu9s5PC74VuB recursive&lt;br&gt;
QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB indirect&lt;br&gt;
QmU5k7ter3RdjZXu3sHghsga1UQtrztnQxmTL22nPnsu3g indirect&lt;br&gt;
QmUr2jDAeWpVFX6s6fkCLGoQCn8SpDaQQMqZazJSiomZKj recursive&lt;br&gt;
QmWFRKVtsJCdwPaD3SozvSwMdhxo3EJLpEv4LMoPcqopoX recursive&lt;br&gt;
QmZnzGhPM5mo8BSWcABeWXavkjpjFsu8yoMg5HQ7A998ty recursive&lt;br&gt;
QmeGVdbzX2gn8wFyK5cQok4UctCfZrS1phPJe5ZEi5FhpW recursive&lt;br&gt;
QmQGiYLVAdSHJQKYFRTJZMG4BXBHqKperaZtyKGmCRLmsF indirect&lt;br&gt;
QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc recursive&lt;br&gt;
QmTReW6Cu4E7PARfJ9FUU5y3r215rVvqmQtripsSAwFBxc recursive&lt;br&gt;
QmQy6xmJhrcC5QLboAcGFcAE1tC8CrwDVkrHdEYJkLscrQ indirect&lt;br&gt;
QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn recursive&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a topic
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.ipfs.io/25-pubsub/"&gt;https://blog.ipfs.io/25-pubsub/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.ipfs.io/reference/cli/#ipfs-pubsub-ls"&gt;https://docs.ipfs.io/reference/cli/#ipfs-pubsub-ls&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;sub to the topic
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;ipfs pubsub passengers&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;publish to a topic
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;ipfs pubsub pub passengers passengers/passenger1.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Result: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l2jFfsuD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/A7iMLVn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l2jFfsuD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/A7iMLVn.png" alt="" width="880" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What ends up happening: &lt;br&gt;
    1. passsenger publishes to a zipcode&lt;br&gt;
    2. driver subs to a zipcode&lt;br&gt;
    3. gets matched through pubsub&lt;/p&gt;
&lt;h2&gt;
  
  
  Publish to a Driver topic
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;sub to the topic
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;ipfs pubsub drivers&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;publish to a topic
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;ipfs pubsub pub drivers drivers/driver1.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IYR3Olkk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/cK0uaAn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IYR3Olkk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/cK0uaAn.png" alt="" width="880" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you see here is John is a passenger in zip code 33101 and Todd is a driver in zip code 33101 and are matched in IPFS. &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;learned a new mental model on databases, so instead of the traditional one database with various files, I had to "host" each individual file in IPFS. Instead of having a database of passenger and drivers, I needed to create a single JSON file per driver and per passenger, and so instead of having a database of 20M drivers and passengers, I would need to create 20M individual JSON files&lt;/li&gt;
&lt;li&gt;learned pubsub, publishing to an IPFS Topic and subscribing to an IPFS Topic which allows passenger to publish their zip code to an IPFS Topic which is then matched with a driver that subscribes to an IPFS Topic&lt;/li&gt;
&lt;li&gt;how conceptually difficult it is to make a decentralized ridesharing app, but at the same time the core matching mechanism of pairing json files to json files requires less lines of code&lt;/li&gt;
&lt;li&gt;learn how to make a database and connecting to it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Note to devs
&lt;/h2&gt;

&lt;p&gt;Take into consideration that this is just an educational tutorial. If you were to build a decentralized ridesharing app there are inherent privacy and safety concerns of matching strangers on a decentralized trust network.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;p&gt;Project can be found: &lt;a href="https://github.com/sydneylai/rideshare"&gt;https://github.com/sydneylai/rideshare&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>filecoin</category>
    </item>
    <item>
      <title>Quickie on Cloud vs IPFS </title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Mon, 31 Jan 2022 15:40:53 +0000</pubDate>
      <link>https://dev.to/sydneylai/quickie-on-cloud-vs-ipfs-1c0n</link>
      <guid>https://dev.to/sydneylai/quickie-on-cloud-vs-ipfs-1c0n</guid>
      <description>&lt;p&gt;There's been a lot of chatter about the metaverse, so I wanted to explore how we as humanity will build the various verses. This reminded me of how there are various cloud service providers ranging from Azure, IBM, AWS to Google Cloud. As I dove into IPFS this theme reminded me of the LAN parties of the 90s, with various gaming worlds operating simultaneously and peer-to-peer. &lt;/p&gt;

&lt;p&gt;Now this article will not be detailing the metaverse backend architecture, I will first begin with looking at cloud infrastructure vs IPFS infrastructure as a primer, as this is a fundamental shift of how we once understood programming. Instead of creating one database with 20M user profiles, now you would create one JSON file per user profile. &lt;/p&gt;

&lt;p&gt;Storage is saving data information on a hard-drive. Then came cloud storage, where a company came in to offer storage services for you so that you did not have to lug around your hard drive. Cloud storage allows you to store internet data through a provider who manages and operates data as a service. You can retrieve your data on demand. IPFS introduces storage across a network of storage providers rather than a centralized provider such as Google Cloud. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difference between Cloud vs IPFS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cloud developers can access their builds across their work computers in Google Cloud Console. Sharing documentation and access rights with colleagues allows for a remote team not tied down to where the company's on prem servers are. If developers ever want to access their Cloud service, they would still need internet connectivity and pay their subscription fee. The key disadvantage for cloud storage is that it only works with an internet connection. Although, most situations in work and life provide for internet access, there are places and times when this just isn’t possible. Thus, you run the risk of not all parties being able to work on the same project.&lt;/p&gt;

&lt;p&gt;Developers using IPFS have no-central-administration feature, therefore a file may not necessarily be stored on one node. There may be many nodes storing small pieces of that file. This means that instead of retrieving the file from one location, you actually retrieve the file from multiple nodes at once, massively reducing bandwidth. If a portion of your data is compromised, not all your information is in jeopardy as your information is dispersed. IPFS provides efficient data storage, distribution, and data permanence that allows for offline-oriented paradigms. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To explain the architecture I'll use a consumer-based approach. When a user uploads data, that data is sent to servers run by Example Startup, and those servers store that data on a company owned IPFS node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lb2571hs3qokb0g9bs5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lb2571hs3qokb0g9bs5.png" alt="This is how IPFS commonly works today (web2.0 style, use server to make available over IPFS) but ultimately the goal would be for the client itself to make it available over IPFS (Step 1, already available over IPFS), then contact the company owned IPFS node, and ask it to help persist it (or/and ask your peers)."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This is how IPFS commonly works today (web2.0 style, use server to make available over IPFS) but ultimately the goal would be for the client itself to make it available over IPFS (Step 1, already available over IPFS), then contact the company owned IPFS node, and ask it to help persist it (or/and ask your peers)." - Discordian, Developer Advocate at Filecoin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For data to be available on the IPFS network, at least one node has to be hosting the data. Thus, IPFS allows us to retrieve that based on what the data is, not where the data is. This means no more fishing around your cloud folders trying to remember which folders you had put those company documents.&lt;/p&gt;

&lt;p&gt;If you share a viral TikTok with everybody, your friends. The way the video clip would be retrieved is everyone clicking on the link to the video. This then takes them to the website that the video is hosted on and every single one of your coworkers’ computers has to individually reach out to the website’s server to download the video. This situation puts enormous strain on our internet infrastructure and is why certain sites are not designed for traffic load capacity crashes.&lt;/p&gt;

&lt;p&gt;IPFS does not use a website’s server to send the video to every single person that’s trying to view it, IPFS looks for the video’s CID, or “content identifier”. The CID is akin to the hash for the content. This CID is based on what the content is, not where the content is located. The site will ask the IPFS network for the video that corresponds to the CID it was just given, regardless of where it is stored, rather than fetching that content from the website’s server. &lt;/p&gt;

&lt;p&gt;Introducing IPFS to a developer’s stack requires a mindshift change on how one develops in web3. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you'd like a detailed document of how I build the technical architecture of the metaverse, please comment below to request, or if any other build requests. &lt;/p&gt;

&lt;p&gt;IPFS Docs: &lt;a href="https://ipfs.io/#install" rel="noopener noreferrer"&gt;https://ipfs.io/#install&lt;/a&gt;&lt;br&gt;
NFT Storage: &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;https://nft.storage/&lt;/a&gt;&lt;br&gt;
Tutorial on how I make &amp;amp; store NFTs: &lt;a href="https://dev.to/sydneylai/create-and-host-nfts-with-25-lines-of-code-4l4e"&gt;https://dev.to/sydneylai/create-and-host-nfts-with-25-lines-of-code-4l4e&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>ipfs</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Build an NFT Wallet with OutSystems &amp; Filecoin</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Fri, 22 Oct 2021 23:31:01 +0000</pubDate>
      <link>https://dev.to/sydneylai/build-an-nft-wallet-with-outsystems-filecoin-2ik4</link>
      <guid>https://dev.to/sydneylai/build-an-nft-wallet-with-outsystems-filecoin-2ik4</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://twitter.com/sydneylai" rel="noopener noreferrer"&gt;@sydneylai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You hear about NFTs as collectables or images, but how do we store or collect them? Today we will build an NFT wallet and host them on IPFS as a unique NFT.&lt;/p&gt;

&lt;p&gt;We host the images in IPFS because this a peer to peer and a decentralized form of storage, rather than a centralized solution like AWS or Google Cloud. Therefore if AWS goes down or you forget to pay your Cloud subscription, you still have a hosting solution that assigned a unique identifier or content identifier (CID).&lt;/p&gt;

&lt;p&gt;Once you have a unique image, you can either distribute your NFTs on a marketplace, put it on a smart contract or turn it into a game. I'll include resources below for how else you can continue to build. This tutorial is for beginners who want to learn how to create and host their NFTs.&lt;/p&gt;




&lt;h1&gt;
  
  
  Start Here
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exposing a REST API for NFT Storage and OutSystems 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tools you'll need:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OutSystems IDE &lt;a href="https://outsyste.ms/developers" rel="noopener noreferrer"&gt;https://outsyste.ms/developers&lt;/a&gt; &lt;br&gt;
Filecoin's NFT Storage &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;https://nft.storage/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Filecoin and IPFS Explained
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Vocab 101&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CID&lt;/strong&gt; - content ID&lt;br&gt;
&lt;strong&gt;Pinning&lt;/strong&gt; - asking the node to keep the data, so that it's not trashed, if you pin it hte data presists&lt;br&gt;
&lt;strong&gt;Quede vs Pinning&lt;/strong&gt; - next deal brokered to get on the Filecoin network&lt;/p&gt;


&lt;h2&gt;
  
  
  Making an NFT Wallet and Hosting NFTs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;https://nft.storage/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is your hosted image, with a CID&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FmSeqVgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FmSeqVgg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hosting NFTs on marketplaces or wallets typically request ETH and gas. NFT developers who want free decentralized storage, you will be able to host your images on-chain with NFT.storage. &lt;/p&gt;

&lt;p&gt;Just upload your data and you'll receive an IPFS hash of the content (a CID) that can be used in on-chain NFT data as a pointer to the content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscEMLLd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscEMLLd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload your data, get back an IPFS hash of the content (a CID) that can be used in on-chain NFT data as a pointer.&lt;/li&gt;
&lt;li&gt;Storage + Retrieval is free!&lt;/li&gt;
&lt;li&gt;Metadata is returned in proper formats!&lt;/li&gt;
&lt;li&gt;Fetch it back via IPFS (pinned redundantly &amp;gt;3x) &lt;/li&gt;
&lt;li&gt;Backed up to Filecoin (stored redundantly &amp;gt;5x)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://filecoin.io/" rel="noopener noreferrer"&gt;Filecoin&lt;/a&gt; provides long term storage for the data ensuring that even if nft.storage is attacked or taken down the NFT data persists.&lt;/p&gt;
&lt;h2&gt;
  
  
  Consume API
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpHRQ9Zh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpHRQ9Zh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can upload either a single file or consume the API to upload multiple files in a directory. The API follows a typical POST and GET Method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**/Upload** - Consuming the API / Post Method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explains uploads, throws it on some IPFS nodes, available over the network, not just centralized, it's free, the storage providers. &lt;br&gt;
&lt;a href="https://nft.storage/api-docs/" rel="noopener noreferrer"&gt;https://nft.storage/api-docs/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Consume NFT Storage API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Start with a mobile app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you launch Service Studio, you want to create a mobile application by clicking on "From Scratch" and then "Phone app". &lt;/p&gt;

&lt;p&gt;Name your application. &lt;/p&gt;

&lt;p&gt;Here you can design your application however you'd like. In this process, I'm creating an NFT wallet with a simple scrolling mechanism similar to the Instagram layout. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Consume the NFT Storage REST API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click on Service, as we are building a service to consume the REST API&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FOPcthtT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FOPcthtT.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right Click on REST and consume REST API&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FqveCE74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FqveCE74.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add Multiple Methods&lt;/p&gt;

&lt;p&gt;Find the YAML file here &lt;br&gt;
&lt;a href="https://nft.storage/api-docs/" rel="noopener noreferrer"&gt;https://nft.storage/api-docs/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Convert the NFT Storage YAML file to a JSON&lt;br&gt;
&lt;a href="https://nft.storage/schema.yml" rel="noopener noreferrer"&gt;https://nft.storage/schema.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Convert with &lt;br&gt;
&lt;a href="https://www.convertjson.com/yaml-to-json.htm" rel="noopener noreferrer"&gt;https://www.convertjson.com/yaml-to-json.htm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fc32MHjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fc32MHjg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check and address any errors and warnings&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create and map out your REST API&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Add Authorizations to your Methods&lt;/p&gt;

&lt;p&gt;Double-click on the orange REST API Method titled "Click" &amp;gt; "Heads and Authentication"&lt;/p&gt;

&lt;p&gt;In the Request headers dropdown select "Authorization"&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FghidFSN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FghidFSN.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the "Test" tab and include a CID in the URL parameter values. You can find your CID &lt;a href="https://nft.storage/api-docs/" rel="noopener noreferrer"&gt;HERE&lt;/a&gt; if you are logged in. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5a1BgES.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5a1BgES.png"&gt;&lt;/a&gt;&lt;br&gt;
in Request headers values, Authorization, include: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bearer[KEY TOKEN]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Bearer&lt;/strong&gt; - When things are stored in, there is a storage deal made, what each API call is doing in the background&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFMFQW6G.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFMFQW6G.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;click on "Test" to see an&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;"ok":true value&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy to response body&lt;/li&gt;
&lt;li&gt;Click on Finish &lt;/li&gt;
&lt;li&gt;Hit the green Publish button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now repeat &lt;strong&gt;Step 3&lt;/strong&gt; for the rest of the REST API Methods titled "delete", "list", "status", "store" respectively&lt;/p&gt;

&lt;p&gt;On the "List" method,&lt;/p&gt;

&lt;p&gt;Include a future date for the &lt;strong&gt;before&lt;/strong&gt; parameter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FqZqWoov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FqZqWoov.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FW8ZQ2BJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FW8ZQ2BJ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy over and match the fields&lt;/p&gt;

&lt;p&gt;While you're creating an Authorization input parameter for both "Status" and "Store" you may get an error or empty payload, just click "Finish"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FwKzGEVp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FwKzGEVp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit the green Publish button&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create a Service Action&lt;/strong&gt;&lt;br&gt;
Right Click on "Service Action" and title your action "List"&lt;/p&gt;

&lt;p&gt;The logic flow will visually appear&lt;/p&gt;

&lt;p&gt;In the Logic tab, &lt;br&gt;
Integrations &amp;gt; REST &amp;gt; NFTStorageAPI &amp;gt; &lt;/p&gt;

&lt;p&gt;Drag the "list" Run Server Action into the logic flow and click on the icon until you see the "Authorization" dropdown&lt;/p&gt;

&lt;p&gt;It's empty&lt;/p&gt;

&lt;p&gt;In "list" Run Server Action, copy all four input parameters, and paste in the "List2" Service Action&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F87BKrXc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F87BKrXc.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now include the Before and Limit within the List Run Server Action you just created on the Logic Flow&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FjkrEGGY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FjkrEGGY.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assign the "list" Run Sever Action by dragging an "Assign" blue icon from the left tray into the logic flow, below the "list" icon&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FJuGUlq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FJuGUlq0.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assign the variable with "Response"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FPMisnBD.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FPMisnBD.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 You may get errors asking to make your structures public&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Integrate your API wrapper&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To integrate your API, head to Interface &amp;gt; Home Screen and "Fetch Data from Other Sources", which I've named "ShowStorage"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F42lS6td.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F42lS6td.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the upper left-hand side there is a 🔌 icon where I will manage my dependencies. I want all the modules that I've created before, to be referenced. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FDxSowRF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FDxSowRF.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head to the Logic tab and locate "List" Service Action, click on and drag the icon into the logic flow.&lt;/p&gt;

&lt;p&gt;Head to the interface tab and double-click on the Output Parameter we've named "Response", set the Data Type to a ListResponse matching the Response Output Parameter in the Logic tab.&lt;/p&gt;

&lt;p&gt;On the logic flow, drag and drop an Assign into the logic flow. In the drop-down, assign Response and List3.Response (or whichever number list you have show up).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fx95Op9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fx95Op9t.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your Run Server Action titled "List", set&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;before: "CurrDateTime()"&lt;br&gt;
Authorization: " "Bearer TOKEN" " &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your Authoization Bearer TOKEN is a string so must close in quotes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4tg57AF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4tg57AF.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Connect the database and images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the Interface tab in the Mainflow UI Flow, add a Block widget and add an Input Parameter titled "CID".&lt;/p&gt;

&lt;p&gt;Double-Click on the "Home" Screen icon and select "Widget Tree" on the top right. &lt;/p&gt;

&lt;p&gt;In Content, drag and drop a Block widget and set the sources: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source Block "MainFlow\Block1"&lt;br&gt;
CID "ShowStorage.Response.value.Current.cid"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6ha9zX9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6ha9zX9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Include three "x.y Expression" widgets within Content&lt;/p&gt;

&lt;p&gt;In the first Expression, map the expression to &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ShowStorage.Response.value.Current.cid&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Folder structure is seen here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FuFXRu2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FuFXRu2i.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second Expression, can be expressed as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FormatDateTime(ShowStorage.Response.value.Current.created, "d MMM yyyy HH:mm")&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The third Expression, we can showcase the pinning service. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Interface tab, click on the Block1 widget. Drag and drop an Image widget from the left. &lt;/p&gt;

&lt;p&gt;Set the Type to "External URL"&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"https://" + CID + ".ipfs.dweb.link"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the API wrapper that I've titled "IPFSNFTStorage", create an Input Parameter within the "store" REST API Method. The Input Parameter will be named "Binary Image" and set the Data Type to "Binary Data".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fa1XLz2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fa1XLz2r.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now copy the three input parameters in store and create a Service Action titled "Upload" within the Service Actions folder. Paste the three input parameters within the "Upload" Service Action&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FI2mGIr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FI2mGIr2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double-click on "Upload" Service Action and drag the store REST API Method onto the logic flow&lt;/p&gt;

&lt;p&gt;The "Store" Run Server Action is like requestion something from someone, in this case asking someone for the image.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6GasJs7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6GasJs7.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore the Assign widget in the logic flow will be the response to the request: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FYAeddk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FYAeddk1.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Success ⭐
&lt;/h2&gt;

&lt;p&gt;You have integrated your NFT Storage API and your mobile application can now display hosted NFTs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6EmcXz3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F6EmcXz3.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Continuing Education
&lt;/h2&gt;

&lt;p&gt;Listen to Patrick Collins, developer advocate at Chainlink explain securing blockchain oracles on Decoded Podcast.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/episode/3AD34nKzqCMoWk4OcJAdx0" width="100%" height="232px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Tutorial
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/3Zy7XfDnev0" rel="noopener noreferrer"&gt;https://youtu.be/3Zy7XfDnev0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/3Zy7XfDnev0" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffz0ravzl7rp3kc4f6mu2.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




</description>
      <category>blockchain</category>
      <category>cloud</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>Create and host NFTs with 25 lines of code</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Mon, 18 Oct 2021 17:39:38 +0000</pubDate>
      <link>https://dev.to/sydneylai/create-and-host-nfts-with-25-lines-of-code-4l4e</link>
      <guid>https://dev.to/sydneylai/create-and-host-nfts-with-25-lines-of-code-4l4e</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://twitter.com/sydneylai" rel="noopener noreferrer"&gt;@sydneylai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You often hear about the 10,000 NFT collection, but how does someone make thousands of unique images? Today we will build an algorithmically generate image dataset and host them on IPFS as a unique NFT. &lt;/p&gt;

&lt;p&gt;We host the images in &lt;a href="https://ipfs.io/" rel="noopener noreferrer"&gt;IPFS&lt;/a&gt; because this a peer to peer and a decentralized form of storage, rather than a centralized solution like AWS or Google Cloud. Therefore if AWS goes down or you forget to pay your Cloud subscription, you still have a hosting solution that assigned a unique identifier or content identifier (CID).&lt;/p&gt;

&lt;p&gt;Once you have a unique image, you can either distribute your NFTs on a marketplace, put it on a smart contract or turn it into a game. I'll include resources below for how else you can continue to build. This tutorial is for absolute beginners who want to learn how to create and host their NFTs.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools you'll need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pillow.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Pillow Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;NFT Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Download Images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sydneylai/generateNFT" rel="noopener noreferrer"&gt;Consolidated Folder&lt;/a&gt; found on my Github&lt;/p&gt;

&lt;p&gt;Otherwise, if you want to create your own selection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;objects: &lt;a href="https://craftpix.net/freebies/free-staves-2d-weapon-pack/" rel="noopener noreferrer"&gt;https://craftpix.net/freebies/free-staves-2d-weapon-pack/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;characters: &lt;a href="https://craftpix.net/freebies/2d-fantasy-elf-free-sprite-sheets/" rel="noopener noreferrer"&gt;https://craftpix.net/freebies/2d-fantasy-elf-free-sprite-sheets/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;background: &lt;a href="https://craftpix.net/freebies/free-elven-land-game-battle-backgrounds/" rel="noopener noreferrer"&gt;https://craftpix.net/freebies/free-elven-land-game-battle-backgrounds/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create Image Folders
&lt;/h2&gt;

&lt;p&gt;Create a master folder, you can name it "NFT1"&lt;br&gt;
Create a folder to organize your:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;backgrounds&lt;/li&gt;
&lt;li&gt;characters&lt;/li&gt;
&lt;li&gt;objects&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Code Breakdown
&lt;/h2&gt;

&lt;p&gt;Install Pillow Library&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install Pillow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go into python, create a python file name "&lt;span&gt;main.py&lt;/span&gt;"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emacs main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your python file, you want to include the following code. &lt;/p&gt;

&lt;p&gt;Here is the python code needed to create your image collection.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mkdir&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;

&lt;span class="n"&gt;output_folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_folder&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;background_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backgrounds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;background_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;#Create character
&lt;/span&gt;  &lt;span class="n"&gt;character_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;characters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;character_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;#x, y
&lt;/span&gt;  &lt;span class="n"&gt;background_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;#Create object
&lt;/span&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;object_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;objects&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;object_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;object_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;#x, y
&lt;/span&gt;    &lt;span class="n"&gt;background_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;object_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;output_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;background_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="nf"&gt;generate_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Coordinates
&lt;/h2&gt;

&lt;p&gt;Calculating the coordinates is how you will layer the image files on top of each other. For example, if you have collectable dogs and they have objects like hats, you will be able to place various hats on the template frame of the dog image.&lt;/p&gt;

&lt;p&gt;Calculate the length and width of your background image, and know where to place your characters.&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="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;#x, y
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculate the length and width of your background image, and know where to place your objects.&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="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;character_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;object_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;#x, y
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Special thanks to Albert Sanchez Lafuente. If additional math is needed for figuring out coordinates on your image &lt;a href="https://towardsdatascience.com/algorithmically-generated-image-dataset-71aee957563a" rel="noopener noreferrer"&gt;read&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  for loops
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object3&lt;/span&gt;&lt;span class="sh"&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 portion of the code allows you to create you generative art. Ensure that your naming convention is consistent with the files in the folders you are referencing &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFn5Sb3H.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFn5Sb3H.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I want to create a custom design, or limited unique art, you can tell python to generate a specific combination or reference a specific file.&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="nf"&gt;generate_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elf1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generate
&lt;/h2&gt;

&lt;p&gt;Run your main&lt;span&gt;.py&lt;/span&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your algorithmically generated image dataset will appear in "generated" folder&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FZYLcotM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FZYLcotM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting NFTs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;https://nft.storage/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is your hosted image, with a CID&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FmSeqVgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FmSeqVgg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hosting NFTs on marketplaces or wallets typically request ETH and gas. NFT developers who want free decentralized storage, you will be able to host your images on-chain with NFT.storage. &lt;/p&gt;

&lt;p&gt;Just upload your data and you'll receive an IPFS hash of the content (a CID) that can be used in on-chain NFT data as a pointer to the content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscEMLLd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscEMLLd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload your data, get back an IPFS hash of the content (a CID) that can be used in on-chain NFT data as a pointer.&lt;/li&gt;
&lt;li&gt;Storage + Retrieval is free!&lt;/li&gt;
&lt;li&gt;Metadata is returned in proper formats!&lt;/li&gt;
&lt;li&gt;Fetch it back via IPFS (pinned redundantly &amp;gt;3x) &lt;/li&gt;
&lt;li&gt;Backed up to Filecoin (stored redundantly &amp;gt;5x)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://filecoin.io/" rel="noopener noreferrer"&gt;Filecoin&lt;/a&gt; provides long term storage for the data ensuring that even if nft.storage is attacked or taken down the NFT data persists.&lt;/p&gt;
&lt;h2&gt;
  
  
  Consume API
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpHRQ9Zh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpHRQ9Zh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can upload either a single file or consume the API to upload multiple files in a directory. The API follows a typical POST and GET Method.&lt;/p&gt;
&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Start building your NFTs! Join Filecoin's Hackathon and showcase your NFT projects, win prize money.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hackathons.filecoin.io/" rel="noopener noreferrer"&gt;https://hackathons.filecoin.io/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Continuing Education
&lt;/h2&gt;

&lt;p&gt;Listen to Patrick Collins, developer advocate at Chainlink explain securing blockchain oracles on Decoded Podcast.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/episode/3AD34nKzqCMoWk4OcJAdx0" width="100%" height="232px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Tutorial
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/gfkWJTBqHuE" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr87xutjtdij3gq7gdmsz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nft</category>
      <category>tutorial</category>
      <category>filecoin</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Tech Stack to build your crypto, NFT or Apps</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Wed, 05 May 2021 16:34:05 +0000</pubDate>
      <link>https://dev.to/sydneylai/tech-stack-to-build-your-crypto-nft-or-apps-3hpa</link>
      <guid>https://dev.to/sydneylai/tech-stack-to-build-your-crypto-nft-or-apps-3hpa</guid>
      <description>&lt;h1&gt;
  
  
  Tech Stack to build your crypto, NFT or Apps
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Pick a blockchain protocol
&lt;/h2&gt;

&lt;p&gt;You've heard of it. You want it. You have some. How are NFTs and crypto built? These web3 (blockchain) and decentralized applications are built on an architecture that is alien from what I've learned in my classic developer bootcamp.&lt;/p&gt;

&lt;p&gt;I'll provide an intro to beginner tools you can use to get started. We will focus on the Ethereum protocol (there are many others) as it's the main protocol that crypto (built on ERC-20), dApps (decentralized apps) (built on ERC-20), and NFTs (built on ERC-721, ERC-1155) are built on. The adoption rate for the Ethereum protocol is staggering in comparison to other protocols, with 3000+ applications and overall Q1 NFT sales for 2021 topping $2B.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/sydneylai/status/1389261566051340292" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FdLupgtD.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Growth of Ethereum)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the same compared to traditional programming
&lt;/h2&gt;

&lt;p&gt;Compared to traditional programming, testing and integration are reasonably similar. The languages used are the same in addition to Solidity, an object-oriented programming language for writing smart contracts. The languages a developer should be familiar with are C++, Python, and JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's different compared to traditional programming
&lt;/h2&gt;

&lt;p&gt;Deployment is very different, and because the blockchain is immutable, every time you deploy it's permanent. A developer will need to audit code to ensure the security of code and certainty. Therefore data storage and maintenance differ as well.&lt;/p&gt;

&lt;p&gt;One important difference compared to traditional development is that the data with which the contract interacts must already be on the blockchain. &lt;/p&gt;

&lt;p&gt;To inject data onto the blockchain requires an oracle, which allows other contracts to consume it. An oracle must be secure or vulnerabilities will be exposed and attacked. &lt;/p&gt;

&lt;p&gt;If the oracle is faulty or compromised, the &lt;a href="https://docs.chain.link/" rel="noopener noreferrer"&gt;Chainlink SDK&lt;/a&gt; can be used as a network of nodes that provide data and information from off-blockchain sources to on-blockchain smart contracts via oracles.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Instead of calling an API to your backend, it's going to call an API to the blockchain and it's going to read off whatever the state of that blockchain is. It's going to be a different environment just because you don't have the kind of ownership of your smart contracts on your backend as you do in the traditional sense." - Patrick Collins, Developer Advocate at Chainlink&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Listen to a Patrick Collins explain securing oracles on Decoded Podcast &lt;a href="https://open.spotify.com/episode/3AD34nKzqCMoWk4OcJAdx0?si=B7fak7v-Q1afadUTH1A30A" rel="noopener noreferrer"&gt;[&lt;strong&gt;Spotify&lt;/strong&gt;]&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools for Web3 Developers (Build an app or crypto)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frameworks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.trufflesuite.com/" rel="noopener noreferrer"&gt;Truffle&lt;/a&gt;&lt;/strong&gt; - Most popular smart contract development, testing, and deployment framework. The Truffle suite includes Truffle, Ganache, and Drizzle. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://hardhat.org/" rel="noopener noreferrer"&gt;Hardhat&lt;/a&gt;&lt;/strong&gt; - Flexible, extensible and fast Ethereum development environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://openzeppelin.com/sdk/" rel="noopener noreferrer"&gt;OpenZeppelin SDK&lt;/a&gt;&lt;/strong&gt; - A suite of tools to help you develop, compile, upgrade, deploy and interact with smart contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/iamdefinitelyahuman/brownie" rel="noopener noreferrer"&gt;Brownie&lt;/a&gt;&lt;/strong&gt; - Brownie is a Python framework for deploying, testing, and interacting with Ethereum smart contracts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootstrap/Out-of-Box tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.trufflesuite.com/boxes" rel="noopener noreferrer"&gt;Truffle boxes&lt;/a&gt;&lt;/strong&gt; - Packaged components for the Ethereum ecosystem&lt;/p&gt;

&lt;h3&gt;
  
  
  Communicating with Ethereum
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/dfuse-io/client-js" rel="noopener noreferrer"&gt;dfuse&lt;/a&gt;&lt;/strong&gt; - A TypeScript library to use dfuse Ethereum API&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ethereum.stackexchange.com/" rel="noopener noreferrer"&gt;Ethereum Stack Exchange&lt;/a&gt;&lt;/strong&gt; - Post and search questions to help your development life cycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.metacartel.org/" rel="noopener noreferrer"&gt;MetaCartel 💰&lt;/a&gt;&lt;/strong&gt; - If you have a project built on Ethereum and need $5K - $10K in developer grants, you can apply &lt;a href="https://forum.metacartel.org/t/guide-how-to-post-a-funding-proposal/74" rel="noopener noreferrer"&gt;here&lt;/a&gt; or any Q&amp;amp;A DM &lt;a href="https://twitter.com/sydneylai" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional Build for Web2 Developers (Build an app)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.outsystems.com/pro-developers/?utm_source=outsystems&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Evangelist_devto_20210505" rel="noopener noreferrer"&gt;OutSystems&lt;/a&gt;&lt;/strong&gt; full-stack platform for the development of mobile and web enterprise applications, which run in the cloud, on-premises, or in hybrid environments.&lt;/p&gt;

&lt;p&gt;If the web3 stack set-up is too complex and you want something up and running you can build as a solo dev with &lt;a href="https://www.outsystems.com/pro-developers/?utm_source=outsystems&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Evangelist_devto_20210505" rel="noopener noreferrer"&gt;OutSystems&lt;/a&gt;, a developer platform that allows you to build web and mobile applications on the enterprise level. This allows you to quickly build a full-stack application regardless of your framework, as long as you know basic application architecture. &lt;/p&gt;

&lt;p&gt;Here's a video where I will walk you through how to connect a database, manage dependencies for plugins, and replicate a full-stack build of a mobile wallet to hold your ETH and various tokens. This app is easy to build with the OutSystems developer platform and you will have yourself a super sweet personal wallet!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_K0BVsi9OjA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;What you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to rapid development for mobile&lt;/li&gt;
&lt;li&gt;How to quickly build applications with developer tools&lt;/li&gt;
&lt;li&gt;Walkthrough of how to create API integrations in-app with AI scripts&lt;/li&gt;
&lt;li&gt;Introduction to ERC20, wallets, and other blockchain token protocols&lt;/li&gt;
&lt;li&gt;Enjoy the ease of building and implementing your own private wallet&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building NFTs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.opensea.io/docs/opensea-sdk" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenSea SDK&lt;/strong&gt;&lt;/a&gt; - A peer-to-peer marketplace for rare digital items. Buy, sell, auction, and discover collectibles.&lt;/p&gt;

&lt;p&gt;ERC-721: “Single” if you want your collectible to be one of a kind &lt;br&gt;
ERC-1155: “Multiple” if you want to sell one collectible multiple times&lt;/p&gt;
&lt;h2&gt;
  
  
  Blockchain for all
&lt;/h2&gt;

&lt;p&gt;Building applications (crypto, NFT, dApps) on blockchain is becoming more accessable and there are various ways for developers of all skill levels to get started. Feel free to reach out on Dev.To or Twitter if you need any help! 👋 &lt;/p&gt;
&lt;h2&gt;
  
  
  Extra Content
&lt;/h2&gt;

&lt;p&gt;Listen to Patrick Collins, developer advocate at Chainlink explain securing oracles on Decoded Podcast.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/episode/3AD34nKzqCMoWk4OcJAdx0" width="100%" height="232px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>blockchain</category>
    </item>
    <item>
      <title>A quick look at Slack's Webhook Logic Flow</title>
      <dc:creator>sydneylai</dc:creator>
      <pubDate>Wed, 24 Feb 2021 19:02:33 +0000</pubDate>
      <link>https://dev.to/sydneylai/a-quick-look-at-slack-s-webhook-logic-flow-3g19</link>
      <guid>https://dev.to/sydneylai/a-quick-look-at-slack-s-webhook-logic-flow-3g19</guid>
      <description>&lt;p&gt;Slack Webhook logic flow illustrated with OutSystems&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Purpose: To show the Slack webhook logic in a dashboard integration&lt;br&gt;
For: Devs familiar with OutSystems's dev platform&lt;br&gt;
Listen: &lt;a href="https://open.spotify.com/episode/71BEEDqPGTCTdMz3zd2wfr?si=Ht0de46USEubkMaekOwAgg&amp;amp;nd=1" rel="noopener noreferrer"&gt;Podcast interview&lt;/a&gt; with software eng on how Slack was built &lt;br&gt;
Ask for help: &lt;a href="https://www.outsystems.com/forums/" rel="noopener noreferrer"&gt;OutSystems Forms&lt;/a&gt; (2 Hour Response Time)&lt;br&gt;
Written by &lt;a href="https://twitter.com/sydneylai" rel="noopener noreferrer"&gt;@sydneylai&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📝 Where do I start?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Have an app to integrate with
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can use a template &lt;a href="https://www.outsystems.com/free-edition" rel="noopener noreferrer"&gt;Download OutSystems&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Try the incident reporting ticketing dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F2Kb74O9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F2Kb74O9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a Slack Incoming Webhook
&lt;/h3&gt;

&lt;p&gt;This is the most common integration, where you have your webapp Slack you a message when an action is triggered. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://api.slack.com/messaging/webhooks" rel="noopener noreferrer"&gt;https://api.slack.com/messaging/webhooks&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find your specific token and Hook URL&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Use a Slack Integration - a Forge Component
&lt;/h3&gt;

&lt;p&gt;Install&lt;br&gt;
&lt;a href="https://www.outsystems.com/forge/component-overview/5381/slack-integration" rel="noopener noreferrer"&gt;https://www.outsystems.com/forge/component-overview/5381/slack-integration&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Hint:&lt;/strong&gt; The way the dev decided to write this component, the token is hard-coded so this means you should create a dynamic token to allow posts in various channels. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5HiYR4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5HiYR4s.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Logic Flow Explained
&lt;/h3&gt;

&lt;p&gt;See how the Issue Tracker dashboard communicates with Slack's Inbound Webhook&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FG6VLCpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FG6VLCpd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(Zoom In) On the left is the Logic Flow and right is the folder structure of containing the logic in the app, which includes server-side actions, functions, as well as REST and SOAP integrations&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscLs9pi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FscLs9pi.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the Start of the logic flow, the user is assigning a ticket status. After the ticket is created, the Server Action or Action that runs logic on the server side, assigns a ticket ID and a ticket is created.&lt;/p&gt;

&lt;p&gt;The request is then sent to Slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5ZXjIOj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F5ZXjIOj.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Assign a Request&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F9UyVeJb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F9UyVeJb.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Run a Server Action&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F7XXt2h9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F7XXt2h9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Result&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  BONUS: OutSystems Resources
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;th&gt;Tutorials&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chatbot Build&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.youtube.com/watch?v=fl_ZHT8ZspU&amp;amp;ab_channel=OutSystems" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Join Dev community&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.outsystems.com/community/" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply for free developer school&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.outsystems.com/events/developer-school/" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How To Videos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.youtube.com/user/outsystems" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Slack Specific
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;th&gt;Tutorials&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Podcast on how Slack was built&lt;/td&gt;
&lt;td&gt;&lt;a href="https://open.spotify.com/episode/71BEEDqPGTCTdMz3zd2wfr?si=Ht0de46USEubkMaekOwAgg&amp;amp;nd=1" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blog post on interview with Slack eng&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.outsystems.com/blog/posts/decoded-future-of-communication/" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video on Slack Logic Flow&lt;/td&gt;
&lt;td&gt;&lt;a href="https://youtu.be/O50sQDsp1mA" rel="noopener noreferrer"&gt;🔗&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>slack</category>
      <category>outsystems</category>
      <category>api</category>
    </item>
  </channel>
</rss>
