<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Paulie's Blog]]></title><description><![CDATA[Paulie's Blog]]></description><link>https://blog.paulmcaviney.ca</link><generator>RSS for Node</generator><lastBuildDate>Tue, 15 Sep 2026 17:42:22 GMT</lastBuildDate><atom:link href="https://blog.paulmcaviney.ca/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Get Started on Celo with Infura RPC Endpoints]]></title><description><![CDATA[Onboarding the next wave of users to Web3 is a massive undertaking that many projects in the ecosystem are building for. One project with a unique approach to this is Celo, a layer-one blockchain network. Celo gives a superior new-user experience by ...]]></description><link>https://blog.paulmcaviney.ca/get-started-on-celo-with-infura-rpc-endpoints</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/get-started-on-celo-with-infura-rpc-endpoints</guid><category><![CDATA[celo]]></category><category><![CDATA[Web3]]></category><category><![CDATA[infura]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Tue, 29 Nov 2022 18:58:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1669743905262/znadCpjOa.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Onboarding the next wave of users to Web3 is a massive undertaking that many projects in the ecosystem are building for. One project with a unique approach to this is Celo, a layer-one blockchain network. Celo gives a superior new-user experience by being a mobile-first layer-1 blockchain that is easy to use with just a mobile phone. Your phone number acts as your address rather than a complex string, and the network allows users the option to pay gas fees with other tokens than the native currency.</p>
<p>However, the user experience is just one side of the onboarding coin. Developer experience is the other. After all, a new network is just as good as the RPCs that let you use it. Only some developers have the resources to run a node.</p>
<p>Infura, one of the most popular Web3 node providers, now offers Celo Network RPC nodes to all users. So if you want to start building on this mobile-first network, there’s never been a better time. Before you start building, let’s learn more about Celo.</p>
<p>This article will provide a high-level overview of the Celo Blockchain Network and how you can start building on it using Infura. </p>
<h2 id="heading-what-is-celo">What is Celo?</h2>
<p>Celo is a <a target="_blank" href="https://cryptonews.com/news/celo-to-be-fastest-evm-chain-by-end-of-2022-co-founder-says.htm">high-throughput layer-1 network</a> that focuses on mobile users.</p>
<h3 id="heading-mapping-phone-numbers-to-public-keys">Mapping Phone Numbers to Public Keys</h3>
<p>Celo is easier for mobile phone users than other networks. Celo maps phone numbers to public keys, allowing users to send tokens to people who don’t have wallets. <a target="_blank" href="https://docs.celo.org/protocol/identity">A decentralized attestation protocol</a> does the mapping and links an account to a phone number. This service never receives the phone number in clear text to <a target="_blank" href="https://docs.celo.org/protocol/identity/odis-use-case-phone-number-privacy">maintain privacy</a>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eycb8s1j6bldc4bhfxnj.png" alt="How Celo’s attestation protocol works – Image from celo.org" /></p>
<p>As a result, user experience is better than most blockchains, as all interactions are done through phone numbers, rather than 30+ character-long strings that are easy to make mistakes with and impossible to memorize.</p>
<h3 id="heading-paying-gas-fees-with-erc-20-tokens">Paying Gas Fees with ERC-20 Tokens</h3>
<p>Another usability hurdle is that most networks require users to pay gas fees with a native token. This results in users exchanging other tokens for native ones just to be able to send transactions. </p>
<p>This is a problem for two reasons. First, it adds a non-trivial step to every transaction if the user doesn’t have enough native tokens. Second, exchanging tokens is taxable in some countries, so they need to keep track of each time they exchange to a native token just to cover gas fees.</p>
<p>With Celo, you can pay with any approved ERC-20 token currently available, even stablecoins, lowering yet another barrier to entry and making costs more predictable. However, there is one caveat: transactions paid with non-CELO gas currencies will cost roughly <a target="_blank" href="https://docs.celo.org/protocol/transaction/erc20-transaction-fees#fee-currency-field">50k additional gas</a>. It’s also important to note that there is a <a target="_blank" href="https://docs.celo.org/protocol/transaction/erc20-transaction-fees#fee-currency-field">governable list of accepted currencies</a>. </p>
<p>When developing, Celo comes with a dapp SDK called <a target="_blank" href="https://docs.celo.org/developer/contractkit/migrating-to-contractkit-v1#what-is-contractkit-version-v10">ContractKit</a>. This SDK is a suite of packages that make building on Celo more straightforward. Connect, one of ContractKit’s main packages, acts as a wrapper around web3.js that handles the different currencies to pay the fees.</p>
<p>You can set your preferred currency as default for all transactions, like in this example:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">import</span> { CeloContract } <span class="hljs-keyword">from</span> <span class="hljs-string">"@celo/contractkit"</span>

<span class="hljs-keyword">const</span> accounts = <span class="hljs-keyword">await</span> kit.web3.eth.getAccounts()
kit.defaultAccount = accounts[<span class="hljs-number">0</span>]
<span class="hljs-keyword">await</span> kit.setFeeCurrency(CeloContract.StableToken)
</code></pre>
<p>With this in your code, you are setting the default currency if the <code>feeCurrency</code> field is left blank when sending a transaction. The user can still select another currency to use.</p>
<p>ContractKit comes with a list of contract addresses that include all core Celo currencies. In the example <code>CeloContract.StableToken</code> refers to cUSD.</p>
<p>It’s also possible to set your preferred currency per transaction. In this example, we send cUSD and also pay with cUSD.</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> kit.contracts.getStableToken()
<span class="hljs-keyword">await</span> contract.transfer(recipientAddress, amount)
  .send({ <span class="hljs-attr">feeCurrency</span>: contract.address })
</code></pre>
<p>Celo’s virtual machine is also EVM compatible since it originated as a fork of <a target="_blank" href="https://github.com/ethereum/go-ethereum">Geth</a>. This compatibility enables you to reuse most of your Solidity skills when deploying your smart contracts on Celo. However, there are some notable differences.</p>
<p>The first difference is that transaction objects have additional fields like <code>feeCurrency</code>, <code>gatewayFee</code>, and <code>gatewayFeeRecipient</code>. They provide full-node incentives and allow users to pay their gas fees with different tokens. This doesn’t affect you when porting smart contracts from Ethereum to Celo, but it could be an issue when porting from Celo to Ethereum.</p>
<p>The second difference could have implications for your Ethereum-based smart contracts. The <code>DIFFICULTY</code> and <code>GASLIMIT</code> opcodes aren’t supported, and the fields are also missing from block headers.</p>
<p>A third difference is that the key derivation path is <code>m/44'/52752'/0'/0</code> and not <code>m/44'/60'/0'/0</code> like in Ethereum. Essentially, this derivation path allows wallets to generate different keys from one seed phrase.</p>
<h3 id="heading-the-network-is-carbon-negative">The Network is Carbon Negative</h3>
<p>CO2 production by blockchain networks has been a huge talking point in the last few years. Coming from Bitcoin, many of the early networks used the Proof-of-Work consensus algorithm to eliminate Sybil attacks.</p>
<p>The Celo protocol uses <a target="_blank" href="https://docs.celo.org/protocol/pos">BFT Proof-of-Stake</a>, which minimizes energy usage of the network by over 90%. Plus, it can create a new block in five seconds, less than half the time Ethereum needs.</p>
<p>Furthermore, all blocks are finalized immediately, so you and your users don’t have to wait for their actions to be written on-chain.</p>
<p>All this optimization still produces CO2, so <a target="_blank" href="https://www.wren.co/profile/celo">Celo uses projects like Wren</a>, a carbon offset subscription service that offsets 65.7 tons of CO2 monthly to get carbon negative. With tech-funded rainforest protection, Celo has already saved over 30,000 tons of CO2. </p>
<h2 id="heading-why-use-celo-with-infura">Why Use Celo with Infura?</h2>
<p>Infura offers free RPCs for prominent wallets, and <a target="_blank" href="https://www.infura.io/customers">many big Web3 projects</a> use them as their RPC provider, including Brave, Uniswap, Compound, Gnosis, and Maker, just to name a few. Additionally, Infura has achieved 99.99% uptime and about 10 times faster response times than other service providers like Alchemy or Quicknode.</p>
<p>ConsenSys, the company behind Infura also created and maintains crucial Web3 projects such as <a target="_blank" href="https://metamask.io/">MetaMask</a> and the <a target="_blank" href="https://trufflesuite.com/docs/">Truffle Suite</a>. So the shared know-how of creating wallets, dev tools, and RPCs creates synergies you won’t get from any other RPC provider. This also means you get trusted and complementary end-to-end tooling from the ConsenSys suite of products that flawlessly integrate with Infura RPCs.</p>
<p>With the release of <a target="_blank" href="https://blog.infura.io/post/celo-x-infura-continuing-our-multi-chain-expansion-with-social-regenerative-defi">Celo RPCs</a>, Infura now supports <a target="_blank" href="https://www.infura.io/networks">10 different networks</a>, so you can build on multiple chains at once. Best of all, it’s free to access these networks and their archived data!</p>
<h2 id="heading-summary">Summary</h2>
<p>Celo is an exciting chain that tackles Web3 user and developer experience pain-points with innovative solutions. With its mobile-first approach, users can interact with the network and receive tokens with their phone number rather than a crypto wallet, making onboarding to the network easier for Web3 newcomers.</p>
<p>With the option to pay gas fees with other tokens rather than the native currency, Celo also removed a massive hurdle in the daily use of a blockchain network. Other networks require fees paid with a native and potentially volatile token.</p>
<p>Now that Infura offers RPC nodes for the Celo network, it’s the perfect time to start building on this mobile-first blockchain network. For more information, <a target="_blank" href="https://docs.infura.io/infura/networks/celo">check out Infura’s docs</a>.</p>
]]></content:encoded></item><item><title><![CDATA[How to Run Ganache in a Browser]]></title><description><![CDATA[When developing Web3 projects, it helps to have a local blockchain devnet for testing. Ganache is one of the most popular tools for this in the Ethereum ecosystem, and part of Truffle. Ganache allows you to set up a local blockchain with different se...]]></description><link>https://blog.paulmcaviney.ca/how-to-run-ganache-in-a-browser</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/how-to-run-ganache-in-a-browser</guid><category><![CDATA[Web3]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[truffle]]></category><category><![CDATA[ganache]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Mon, 31 Oct 2022 17:48:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1667236817707/vCLzsjhws.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When developing Web3 projects, it helps to have a local blockchain devnet for testing. <a target="_blank" href="https://trufflesuite.com/ganache/">Ganache</a> is one of the most popular tools for this in the Ethereum ecosystem, and part of <a target="_blank" href="https://www.google.com/url?q=https://trufflesuite.com/&amp;sa=D&amp;source=docs&amp;ust=1666974697266273&amp;usg=AOvVaw2MJDRYhKuW4DmJ8Qv97XKz">Truffle</a>. Ganache allows you to set up a local blockchain with different settings to thoroughly test your smart contracts before deployment.</p>
<p>Seeing a local blockchain’s output in the terminal helps you to understand how your project will behave in a live environment. The ability to set the output to variables to manipulate some frontend code is even more useful. Some users may not know that you can do this by running Ganache in your browser.</p>
<p>This article explores how to run Ganache in your browser and highlights three great new features that make developing your Web3 projects easier.</p>
<h3 id="heading-ganache-in-the-browser">Ganache in the Browser</h3>
<p>Running a local blockchain instance to test your smart contracts is an essential step in the Web3 development process. By testing in this manner, you confirm things are working correctly before using a node service, such as <a target="_blank" href="https://infura.io/">Infura</a>, to deploy your contracts to a testnet or mainnet. This minimizes the risk of ramping up daily limits and ensures you only need to deploy once. Ganache is an excellent tool that simulates the Ethereum network and allows developers to:</p>
<ul>
<li><a target="_blank" href="https://trufflesuite.com/blog/introducing-ganache-7/#2-fork-any-ethereum-test-network-without-waiting-for-sync-time">Fork any Ethereum network without waiting to sync</a></li>
<li><a target="_blank" href="https://trufflesuite.com/blog/introducing-ganache-7/#5-mine-blocks-instantly-at-interval-or-on-demand">Establish block mining rules (instant, on-demand, intervals)</a></li>
<li><a target="_blank" href="https://trufflesuite.com/blog/introducing-ganache-7/#7-impersonate-any-account">Impersonate any real account without needing their private keys</a></li>
<li>Make function calls with Ethereum JSON-RPC support</li>
</ul>
<p>However, many who use this tool may be unaware that, since v7.0.0.0, Ganache can also run in your browser. Running in the browser allows you to set the local blockchain’s output to variables, which you can then use to test your frontend code. This visual process helps you to understand how your users will interact with your project and also enables you to test your dapp entirely offline (when using a local instance).</p>
<p>By first running Ganache in the browser and fine-tuning how your dapp reacts, you can easily switch the provider to your node service API once things are working as intended. Additionally, since Ganache’s latest update (v7.3.2 at the time of writing), you can now<a target="_blank" href="https://trufflesuite.com/blog/three-new-ganache-features-to-improve-your-developer-experience/#zero-config-mainnet-forking-now-available-in-the-browser"> fork the Ethereum mainnet when running Ganache in the browser</a>. This allows you to interact with real accounts and contracts through your frontend code.</p>
<h3 id="heading-the-project">The Project</h3>
<p>In this section, we will create a basic smart contract using Truffle and its VS Code extension. Then, we’ll first deploy our contract to Ganache via the command line. Afterward, we will create a simple frontend to use Ganache in the browser and interact with our deployed contract.</p>
<h4 id="heading-requirements">Requirements</h4>
<p>For this project, we will use the following:</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/">NodeJS / NPM</a></li>
<li><a target="_blank" href="https://trufflesuite.com/docs/truffle/getting-started/installation/">Truffle</a> &amp; <a target="_blank" href="https://github.com/trufflesuite/ganache#readme">Ganache</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/Download">The VS Code Editor</a></li>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=trufflesuite-csi.truffle-vscode">Truffle for VS Code Extension</a></li>
</ul>
<h4 id="heading-step-1-installation">Step 1 – Installation</h4>
<p>First, we can run the command <code>node --version</code> in our terminal to ensure NodeJS and NPM are <a target="_blank" href="https://nodejs.org/en/">properly installed</a> on our machine.</p>
<p>Next, we will install Truffle and Ganache by running the following command:</p>
<pre><code>npm install -g truffle ganache
</code></pre><p>Checking the version number for Truffle and Ganache with <code>truffle --version</code> and <code>ganache --version</code> respectively will tell us if both tools were installed successfully. </p>
<p>The next step is to <a target="_blank" href="https://code.visualstudio.com/Download">install VS Code</a>, then navigate to the <strong>Extensions</strong> tab in the editor and search for <strong>Truffle for VS Code</strong>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmke8bhz3y1b6wmre3a4.png" alt /></p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kl70ae6tlclbrqjxbpoo.png" alt /></p>
<p>With everything now installed, we are ready to start working on the project.</p>
<h4 id="heading-step-2-set-up-the-project">Step 2 – Set Up the Project</h4>
<p>With the Truffle for VS Code extension, we can easily create a new Truffle project through the VS Code command palette. Press <code>ctrl + shift + P</code> in the editor to open up the command palette and type <code>truffle</code> to see a list of commands we can use. Select <strong>Truffle: New Solidity Project</strong> and then <strong>create basic</strong> project to create a new project in the desired folder.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmaavbpygcfhgy5coku1.png" alt /></p>
<p>This creates an initialized project with a simple folder structure and example code we can use if we wish. </p>
<p>The ability to use <code>console.log</code> in our smart contract code is another great new feature <a target="_blank" href="https://trufflesuite.com/blog/three-new-ganache-features-to-improve-your-developer-experience/#ability-to-use-consolelog-from-solidity">recently available for Ganache</a>. Before we create the smart contract for our project, let’s set that up by installing the required package. Navigate to the project folder in the terminal and type the following command:</p>
<pre><code>npm install @ganache/<span class="hljs-built_in">console</span>.log
</code></pre><h4 id="heading-step-3-write-the-smart-contract">Step 3 – Write the Smart Contract</h4>
<p>The smart contract for our project will be a basic one we can donate some ETH to and request to see the balance. </p>
<p>In the <strong>contracts</strong> folder, create a new file and call it <strong>SimpleContract.sol</strong>. Next, fill it with the following smart contract code:</p>
<pre><code class="lang-Solidity"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.13;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">'@ganache/console.log/console.sol'</span>;

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">SimpleContract</span> </span>{

  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
    console.log(<span class="hljs-string">'\n\n#################################################\n'</span>
    <span class="hljs-string">'####         Now Deploying Contract          ####\n'</span>
    <span class="hljs-string">'#################################################'</span>
    );
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">donate</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
    console.log(<span class="hljs-string">'Successfully Donated '</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>);
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getBalance</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>) </span>{
    console.log(<span class="hljs-string">"This contract's balance is:"</span>, <span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>;
  }

  <span class="hljs-comment">// Needed in order to receive payments</span>
  <span class="hljs-function"><span class="hljs-keyword">receive</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{}

}
</code></pre>
<p>The code in our smart contract is relatively simple. It displays a message in the console when we deploy our smart contract, provides the functionality to donate ETH and query the balance, and prints messages in the console when calling the functions.</p>
<h4 id="heading-step-4-deploy-to-ganache">Step 4 – Deploy to Ganache</h4>
<p>After installing the Truffle for VS Code Extension, we can easily deploy by right-clicking the smart contract file and choosing <strong>Deploy Contracts.</strong> However, if we want to see our console messages, we will have to use our own terminal rather than the one built into VS Code. This could potentially change in the future, but for now, we will have to create a simple migration script to carry out the deployment.</p>
<p>In the <strong>migrations</strong> folder, create a new script called <code>1_SimpleContract.js</code> and input the following code:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> SimpleContract = artifacts.require(<span class="hljs-string">"SimpleContract"</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">deployer</span>) </span>{
  deployer.deploy(SimpleContract);
};
</code></pre>
<p>Next, open up a new terminal window and start Ganache:</p>
<pre><code>ganache
</code></pre><p>This terminal window is where we will see our console messages when they appear. We now have two terminal windows open: one running Ganache and the other open in the folder of our Truffle project.</p>
<p>In the terminal window that’s open in our Truffle project’s location, type the following command to initiate the deployment:</p>
<pre><code>truffle migrate --network development
</code></pre><p>If the deployment is successful, we can see our console message printed in the terminal:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16is2vjp508aw5a0rhp8.png" alt /></p>
<p>Great! Our contract is live on our local Ganache instance! We’ll leave Ganache running for now so we can interact with our contract using the browser. Before we get to that, copy the <code>contract address</code> from the output in the terminal where we typed the <code>migrate</code> command. We will use this address to point our frontend to our smart contract.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ktlxsv38patytq7hj7sg.png" alt /></p>
<h4 id="heading-step-5-build-the-frontend">Step 5 – Build the Frontend</h4>
<h4 id="heading-5a-setup">5.a – Setup</h4>
<p>For the frontend of this project, we will use React. Navigate to a new empty folder and type:</p>
<pre><code>npx create-react-app ganache-browser-test
</code></pre><p>Next, we will install Web3.JS to easily interact with our smart contract. Navigate into our new project folder and install Web3.JS with this command:</p>
<pre><code>cd ganache-browser-test
npm install web3
</code></pre><p>Newer versions of create-react-app don’t play nicely with Web3.JS, so we need to install a specific version of React Scripts. We can do so with this command:</p>
<pre><code>npm install --save-exact react-scripts@<span class="hljs-number">4.0</span><span class="hljs-number">.3</span>
</code></pre><p>Finally, to use Ganache in our browser, we will install it directly as a dependency:</p>
<pre><code>npm install ganache
</code></pre><p>Alternatively, you can add the CDN link in the html to access Ganache from the browser:</p>
<pre><code class="lang-HTML"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/ganache@7.3.2/dist/web/ganache.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Before we start working on the frontend code, we need to create a file containing our contract’s ABI so that we can interact with our smart contract. We can copy that file directly from our Truffle project. Navigate to the <strong>build/contracts</strong> folder in our Truffle project and copy the <strong>SimpleContract.json</strong> file.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tnyf5goks4u9tmkoqg4y.png" alt /></p>
<p>Next, open up our frontend project in the editor and create a new folder called <strong>abi</strong>. In that folder, paste the <strong>SimpleContract.json</strong> file. The file structure for our frontend now looks like this:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0xail05l47xu32bsjiz.png" alt /></p>
<h4 id="heading-5b-the-frontend-code">5.b – The Frontend Code</h4>
<p>With all the setup out of the way, we can start working on our frontend. First, open the <strong>App.js</strong> file in the <strong>src</strong> folder and replace the boilerplate code with this:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> SimpleContract <span class="hljs-keyword">from</span> <span class="hljs-string">'./abi/SimpleContract.json'</span>;

<span class="hljs-keyword">const</span> ganache = <span class="hljs-built_in">require</span>(<span class="hljs-string">'ganache'</span>);
<span class="hljs-keyword">const</span> Web3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'web3'</span>);

<span class="hljs-keyword">const</span> options = {}  
<span class="hljs-keyword">const</span> provider = ganache.provider(options);

<span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(<span class="hljs-string">'http://127.0.0.1:8545'</span>);  

<span class="hljs-keyword">const</span> CONTRACT_ADDRESS = <span class="hljs-string">'YOUR_CONTRACT_ADDRESS'</span>  
<span class="hljs-keyword">const</span> USER_ADDRESS = web3.utils.toChecksumAddress(<span class="hljs-string">'YOUR_ACCOUNT_ADDRESS'</span>);

<span class="hljs-keyword">const</span> contractInstance = <span class="hljs-keyword">new</span> web3.eth.Contract(SimpleContract.abi, CONTRACT_ADDRESS);

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [contractBalance, setContractBalance] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> donate = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> donationAmount = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#donationAmount'</span>).value;

    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> contractInstance.methods.donate().send({
      <span class="hljs-attr">from</span>: USER_ADDRESS,
      <span class="hljs-attr">value</span>: web3.utils.toWei(donationAmount)
    });

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'donate response:'</span>, response);

  };

  <span class="hljs-keyword">const</span> getBalance = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> contractInstance.methods.getBalance().call();

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'getBalance response:'</span>, response);

    setContractBalance(web3.utils.fromWei(response));

  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Ganache In The Browser<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">'number'</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">'donationAmount'</span>
            <span class="hljs-attr">defaultValue</span>=<span class="hljs-string">{0.01}</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">'donationAmount'</span>&gt;</span>ETH<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">br</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">'donate'</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">'button'</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{donate}</span>
          &gt;</span>
            Donate
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">'getBalance'</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">'button'</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{getBalance}</span>
          &gt;</span>
            Get Contract Balance
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            {contractBalance} ETH
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>


      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Be sure to change <code>CONTRACT_ADDRESS</code> to the address we received when deploying our smart contract back in Step 4. As well, the <code>USER_ADDRESS</code> is the account that will call the functions. We can get this from the list of accounts that displays when we first started our Ganache instance in the terminal:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k272mv0ud9k27anqmz44.png" alt /></p>
<p>Any of these account addresses will work.</p>
<p>Before we move on, let’s take a second to walk through the code we wrote:</p>
<ul>
<li>We import our dependencies and <code>SimpleContract</code> JSON file.</li>
<li>Set the <code>ganache</code>and <code>Web3</code> variables.</li>
<li>Create an empty <code>options</code> variable that we initialize our <code>provider</code> instance with.<ul>
<li><strong>Note</strong>: This <code>options</code> variable is where we would set <a target="_blank" href="https://github.com/trufflesuite/ganache#documentation">any of the options</a> we would like our local blockchain instance to include, such as forking Mainnet or Goerli, when running Ganache strictly in the browser (without it running in our other terminal window).</li>
</ul>
</li>
<li>Initialize our <code>web3</code> object using our <code>localhost URL</code> and port <code>8545</code>, where our Ganache instance is already running.<ul>
<li><strong>Note</strong>: You can run Ganache strictly in the browser at this point by using the <code>provider</code> variable instead of localhost. We are using <code>localhost</code> in this case since we want to interact with our already deployed smart contract and see our <code>console.log</code> messages in the terminal output.</li>
</ul>
</li>
<li>Set our <code>CONTRACT_ADDRESS</code> and <code>USER_ADDRESS</code> variables.</li>
<li>Create a contract instance we can use to call our functions in the <code>App</code> code.</li>
<li>Create the <code>contractBalance</code> React state variable and its <code>set</code> method.</li>
<li>Define our <code>donate</code> and <code>getBalance</code> functions.</li>
<li>Finally, we return the <code>html</code> for our frontend.</li>
</ul>
<h4 id="heading-5c-run-the-project">5.c – Run the Project</h4>
<p>Now we can run our app with <code>npm start</code> to display our frontend, which looks like this:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohc6s8o4ku1s4zbqzidy.png" alt /></p>
<p>When we test our project, we can see the results and our <code>console.log</code> messages displayed on the terminal window which is running Ganache, and the ETH balance on our frontend successfully updates with the new balance.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/milqcjnq4vi7unowjxas.png" alt /></p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7pnstzj5m45ltpldduwm.png" alt /></p>
<h4 id="heading-step-6-fork-goerli-or-mainnet-with-ganache-in-the-browser">Step 6 – Fork Goerli or Mainnet with Ganache in the Browser</h4>
<p>Now that we know our project functions properly on a locally running instance of Ganache, the next step is to run it on a forked version of a testnet and then mainnet. We won’t run through the actual process of doing that in this article, but setting it up to do so is simple. All we need to do is change a few lines of our frontend code.</p>
<p>First, the options variable needs to specify which network we wish to fork:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> options = { <span class="hljs-attr">fork</span>: { <span class="hljs-attr">network</span>: <span class="hljs-string">'goerli'</span> } };
</code></pre>
<p>Or:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> options = { <span class="hljs-attr">fork</span>: { <span class="hljs-attr">network</span>: <span class="hljs-string">'mainnet'</span> } };
</code></pre>
<p>Then we need to update our <code>web3</code> variable declaration:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(options);
</code></pre>
<p>Finally, we need to make sure that we update <code>CONTRACT_ADDRESS</code> with our address on whichever network we are forking. We also need to update <code>USER_ADDRESS</code> to an account address on the same network that has sufficient funds to donate to our contract.</p>
<p>When forking mainnet, that section of code could look something like this:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> options = { <span class="hljs-attr">fork</span>: { <span class="hljs-attr">network</span>: <span class="hljs-string">'mainnet'</span> } };
<span class="hljs-keyword">const</span> provider = ganache.provider(options);

<span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(provider);

<span class="hljs-keyword">const</span> CONTRACT_ADDRESS = <span class="hljs-string">'0x692586eaC70114C8F4714D89E7f72FAAbaeE0Cd7'</span>  
<span class="hljs-keyword">const</span> USER_ADDRESS = web3.utils.toChecksumAddress(<span class="hljs-string">'0xCe7A99Bba7018fa455E6eD5CF88a7F26010F1E8F'</span>);
</code></pre>
<p>And with that, we could test our project with a forked version of mainnet using Ganache in our browser.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Testing projects by creating an interface helps to visualize how your dapp is running and gives you a better idea of how it will perform for users once on mainnet. Running in your browser while testing your frontend code is one of the features that make Ganache such a powerful tool in your development toolkit. For more information about working with Ganache or to contribute to the project, <a target="_blank" href="https://github.com/trufflesuite/ganache#documentation">check out their Github</a> or <a target="_blank" href="https://trufflesuite.com/docs/ganache/quickstart/">documentation</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Infura’s Plans To Launch A New Decentralized Infrastructure Protocol And Why It Matters]]></title><description><![CDATA[Introduction
At ETH Berlin recently, Infura announced plans for a new decentralized infrastructure network. This decentralized network has the potential to vastly improve how web3 developers and end-users access and interact with the data on blockcha...]]></description><link>https://blog.paulmcaviney.ca/infuras-decentralized-network</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/infuras-decentralized-network</guid><category><![CDATA[Web3]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[decentralization]]></category><category><![CDATA[infura]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Wed, 21 Sep 2022 14:36:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1663712857265/Rt3uEbpmU.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>At <a target="_blank" href="https://ethberlin.ooo/">ETH Berlin</a> recently, <a target="_blank" href="https://twitter.com/infura_io/status/1570794318067290112?s=20&amp;t=k28Iqc0qT3Y6nNcL4lipWw">Infura announced plans for a new decentralized infrastructure network</a>. This decentralized network has the potential to vastly improve how web3 developers and end-users access and interact with the data on blockchains.</p>
<p>Why is this a big deal? And what could it mean for Web3? Let’s take a look.</p>
<h3 id="heading-decentralized-protocols">Decentralized Protocols</h3>
<p>One of the most important innovations Web3 and blockchain technology make possible are <strong>decentralized protocols</strong>—networks and communities where anyone and everyone can participate. Protocols are a powerful new form of human coordination using technology and protocols like Bitcoin and Ethereum have led the way for so many others to emerge: NEAR, Polygon, and Arbitrum, just to name a few. </p>
<p>But what about the <strong>infrastructure and protocols</strong> that exist on top of these networks? Many companies creating the building blocks are operating in Web2 terms with centralized ownership and access to their services. As Web3 technology grows and matures, the need for <strong>decentralized protocols and infrastructure</strong> grows with it. That’s why Infura is launching a new infrastructure protocol for node services.</p>
<p>Node services are how some dapps access blockchain data in Web3. While some larger organizations choose to host their own nodes, self-hosting can be complicated and expensive. As a result, many developers rely on companies like Infura to manage the infrastructure and blockchain access for them.</p>
<p>A decentralized infrastructure protocol—one that offers this access but isn’t controlled by a single centralized entity—is a critical piece to completing the Web3 tech stack. </p>
<h2 id="heading-what-is-a-decentralized-infrastructure-protocol">What is a Decentralized Infrastructure Protocol?</h2>
<p>Let’s break down this question of centralized versus decentralized a bit further.</p>
<p>In a <em>centralized</em> node service, a single entity controls the protocol and infrastructure. Similar to how Web2 companies like Twitter or Facebook: one entity hosts the server that ensures the service is operational, gatekeeping the user data and pocketing the revenue. As a result, end-users like you and me only have one entry point into the service, and zero control over what happens behind the scenes. </p>
<p>In the case of a node provider, a single entity is responsible for keeping the service operational, the infrastructure running, and the node responses flowing. While there are multiple nodes running, they are all controlled by this single entity. If the centralized entity or its infrastructure goes down, so does the entire service, along with any applications that rely on that service. <a target="_blank" href="https://en.wikipedia.org/wiki/2021_Facebook_outage">Remember when Facebook went offline on October 4th in 2021</a>? That’s a prime example. Millions of people and services were disconnected as a result of their server outage. This is the principal shortcoming of centralized infrastructure: it can never guarantee 100% uptime the way a decentralized network can. </p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ea26kwrtz7jtv14prjtp.jpg" alt="A centralized node provider with a single entry point leading into multiple nodes, which in turn, lead into the blockchain" /></p>
<p>In a <em>decentralized</em> node service, there are multiple entities all joining together to support the protocol, host the nodes, validate the data, and distribute the risk of infrastructure. The decentralization of responsibilities is closer to the ultimate goals of Web3 and a truly permissionless infrastructure. </p>
<p>And, because there are multiple providers, users will have the choice of which provider to use. If a provider goes down, or one makes technical decisions the user doesn’t like, then the user can easily switch to a new provider. </p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhq1q0d2azmptsefs5v8.jpg" alt="A decentralized node providing service with many providers and multiple points of entry" /></p>
<p>With this many actors, there’s a requirement for ways to agree on upgrades, revenue sharing, architectural changes, and so on. We can already see this on Ethereum with the EIP system. From past experience, this often means implementing decentralized governance like a DAO.</p>
<h2 id="heading-why-is-decentralized-infrastructure-important">Why is Decentralized Infrastructure Important?</h2>
<p>So why is this decentralized node protocol a big deal? </p>
<p>As I mentioned earlier, decentralized <em>networks</em> have progressed significantly as well as some of the protocols, DeFi above all. However, decentralized data <strong>access</strong> is one of the most important components of the Web3 tech stack. </p>
<p>Until now, node access has been mostly centralized, since the vast majority of users access the blockchain through the node providing services. Without a decentralized node access protocol and infrastructure, we don’t really have decentralized Web3, which is the ultimate goal of this industry and ecosystem. A decentralized infrastructure protocol gives us: </p>
<ul>
<li><p><strong>High-throughput and reliability</strong> - a proven architectural solution spread out over multiple entities reduces the risk of downtime and failures. It can ensure that users can access the data they need.</p>
</li>
<li><p><strong>Increased transparency</strong> - decentralized solutions, like open source software, often result in a higher level of transparency.</p>
</li>
<li><p><strong>Improved cooperation</strong> - Instead of competing, protocol providers collaborate to create a more effective and reliable infrastructure protocol.</p>
</li>
</ul>
<p>How this will evolve is yet to be seen, but Infura plans to release the new protocol in stages. </p>
<h2 id="heading-what-can-you-do">What Can You Do?</h2>
<p>Since Infura’s announcement at ETH Berlin was high-level, we don’t know yet how this decentralized infrastructure protocol will be implemented. </p>
<p>That said, there was an open call for infrastructure providers to get involved. Qualified providers can <a target="_blank" href="https://infura.io/resources/network/decentralized-infrastructure-network-early-access-program?utm_source=twitter&amp;utm_medium=organicsocial&amp;utm_campaign=2022_Sep_decentralized-network-eap-infura_announcement_content">sign up for the early access program</a> to help construct the test network. In the announcement, they listed the following qualifications:</p>
<ul>
<li><p>Experience running blockchain infrastructure</p>
</li>
<li><p>Willingness to actively participate and provide feedback</p>
</li>
<li><p>Interest in decentralizing blockchain API access</p>
</li>
</ul>
<p>If you want to learn more about this decentralized network, keep an eye on <a target="_blank" href="https://blog.infura.io/">Infura’s official channels</a> for more information.</p>
]]></content:encoded></item><item><title><![CDATA[How Does Polygon Help Ethereum Scale?]]></title><description><![CDATA[Introduction
Since its inception in 2014, Ethereum has established itself as the de facto leader of blockchain platforms capable of supporting turing-complete smart contracts.
Ethereum has been instrumental in bringing about a revolution that we now ...]]></description><link>https://blog.paulmcaviney.ca/how-does-polygon-help-ethereum-scale</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/how-does-polygon-help-ethereum-scale</guid><category><![CDATA[Web3]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Polygon]]></category><category><![CDATA[NFT]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Mon, 12 Sep 2022 20:22:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662756701136/M2bpxUwdK.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction"><strong>Introduction</strong></h3>
<p>Since its inception in 2014, Ethereum has established itself as the de facto leader of blockchain platforms capable of supporting turing-complete smart contracts.</p>
<p>Ethereum has been instrumental in bringing about a revolution that we now know as web3. The largest decentralized exchange, NFT marketplace, and yield farming protocol all reside on Ethereum. The chain is responsible for handling billions of dollars worth of value, and it has opened up avenues for creators and investors that were previously unfathomable.</p>
<p>Although Ethereum dapps have enjoyed an immense amount of popularity amongst their users, they are nowhere close to achieving mass adoption. The sum of people who have used dapps still number only in the few millions. One of the biggest reasons for this is the scaling handicaps endemic to the chain. It becomes unusable very quickly for everyone barring a few high net-worth users.</p>
<p>Fortunately, there have been serious efforts made by the community to help Ethereum scale. By far, the most popular scaling solution available in the market today is the Polygon POS (Proof of Stake) sidechain. In this article, we are going to explore what Polygon is and how it overcomes Ethereum’s drawbacks. Finally, we will make a side-by-side comparison of both chains’ performances by creating an NFT-minting smart contract.</p>
<h3 id="heading-the-problem-with-ethereum"><strong>The Problem with Ethereum</strong></h3>
<p>Ethereum, despite its market leader position, suffers from a host of problems:</p>
<ol>
<li><strong>Low Transaction Throughput</strong>: Ethereum can handle only 15 transactions per second. Compared to solutions like Visa or Mastercard, which handle over 25,000 transactions per second, this figure is scant.</li>
<li><strong>High Gas Fees</strong>: When a chain can handle few transactions, it must increase processing costs when the transaction volumes are high. Ethereum is notorious for its high gas fees. For instance, not long ago, it reached almost 7000 Gwei during a popular NFT mint (called Otherside). During this period, it would’ve cost you in excess of $500 to perform even the most basic transaction.</li>
<li><strong>Slow Transaction Finality</strong>: Ethereum adds a block to its chain approximately once every 15 seconds. Since there are multiple miners competing to mine blocks at the same time, a block cannot be considered final until at least 4-5 blocks have been added on top of it. In essence, it takes more than a minute for a transaction to be considered final. With applications like games and financial tools, such a slow transaction finality is simply not acceptable.</li>
</ol>
<h3 id="heading-the-solution"><strong>The Solution</strong></h3>
<p>In order to achieve mass adoption and acceptance, it is imperative that a solution be developed on top of Ethereum that addresses its most glaring problems. In essence, we need a solution that has the following features:</p>
<ol>
<li><strong>Low-cost</strong>: Even the most computationally intensive transactions shouldn’t cost more than a few cents.</li>
<li><strong>Fast</strong>: Transactions are confirmed almost instantly.</li>
<li><strong>EVM Compatible</strong>: Developers don’t need to learn new tooling or languages in order to build on the solution.</li>
<li><strong>Interoperable with Ethereum</strong>: Easy to deposit and withdraw funds to and from Ethereum and the solution.</li>
<li><strong>Engaged community</strong>: A community that is committed to improving the solution over time as well as building user-friendly dapps on top of it.</li>
<li><strong>Sustainable:</strong> Any solution looking to reach mass adoption must also be environmentally conscious.</li>
</ol>
<p>Ethereum core developers are working on Layer 1 scaling fixes, such as <a target="_blank" href="https://ethereum.org/en/upgrades/sharding/">sharding</a>, but these solutions are nowhere near completion. We need solutions available today that are easy for anyone to get started on.</p>
<h3 id="heading-introducing-polygon"><strong>Introducing Polygon</strong></h3>
<p>The creators of Polygon designed a chain with all the aforementioned features in mind. Since its inception in 2017, the Polygon chain has gone on to become one of the most popular Ethereum scaling solutions.</p>
<p>Technically speaking, Polygon is an Ethereum sidechain. A sidechain is an independent blockchain that is connected to Ethereum via a bridge. Unlike L2s, sidechains do not inherit the security features of the main Ethereum chain. Instead, they implement their own consensus protocols and block parameters. As a result, sidechains aren’t required to post state changes and transaction data to Ethereum (whereas L2s are).</p>
<p>The greater independence of sidechains from Ethereum makes Polygon slightly more centralized but also enables it to achieve extraordinarily high levels of throughput.</p>
<p>The following are the improvements that Polygon has been able to achieve over Ethereum:</p>
<ol>
<li><strong>High transaction speeds</strong>: Polygon is capable of handling up to 65,000 tx/second, comparable to the scale of its centralized rivals.</li>
<li><strong>Low transaction costs</strong>: Even the heaviest transactions on Polygon cost only a few cents. In most cases, a 10,000x reduction in cost can be observed vis-à-vis Ethereum.</li>
<li><strong>Instant transaction finality</strong>: Polygon’s consensus protocol guarantees that transactions are confirmed almost instantly (less than 2 seconds).</li>
<li><strong>EVM compatible</strong>: Polygon is built on the same software as Ethereum. Therefore, Ethereum developers can build on Polygon using the exact same tools.</li>
<li><strong>Strong community</strong>: The Polygon team has spent millions of dollars to build a robust community of builders, investors, and users. It is already home to some of the most popular dapps on Ethereum with better UX and much cheaper costs.</li>
<li><strong>Low energy consumption</strong>: Polygon uses the Proof-of-Stake protocol, which consumes 99.9% less energy than its PoW counterpart. In fact, Polygon has committed to being <a target="_blank" href="https://polygon.technology/sustainability/">carbon negative</a> by the end of 2022, making it one of the largest environment-friendly blockchains in the market today.</li>
</ol>
<h4 id="heading-a-note-on-polygon-pos-security"><strong>A Note on Polygon PoS Security</strong></h4>
<p>Unlike other sidechains, Polygon PoS does have a method in which it is able to inherit the security of Ethereum. The Polygon PoS chain utilizes the <a target="_blank" href="https://docs.polygon.technology/docs/develop/ethereum-polygon/plasma/getting-started/">Plasma Bridge</a> in order to maintain and guarantee a high level of security. Plasma has a unique exit mechanism, basically a set of smart contracts to help move assets and checkpoints for verification, which enables Polygon PoS to leverage Ethereum’s security. </p>
<p>The only drawback here is withdrawals from Polygon to Ethereum through the Plasma Bridge must go through a 7-day withdrawal period. Quicker withdrawals (within 30 minutes to 3 hours) are possible with the <a target="_blank" href="https://docs.polygon.technology/docs/develop/ethereum-polygon/pos/getting-started/">PoS Bridge</a>, however, this method is not as secure as using the Plasma Bridge.</p>
<p>Both these bridges are still secure and safe to use, and in most cases should suit a user’s needs just fine. However, if your project requires state-of-the-art security, it is prudent to consider using Polygon L2 solutions such as <a target="_blank" href="https://polygon.technology/solutions/polygon-zero/">Zero</a>, <a target="_blank" href="https://polygon.technology/solutions/polygon-nightfall/">Nightfall</a>, and <a target="_blank" href="https://polygon.technology/solutions/polygon-hermez/">Hermez</a>.</p>
<h3 id="heading-comparison-in-action"><strong>Comparison in Action</strong></h3>
<p>Now that we've seen the advantages that Polygon PoS has over Ethereum for certain projects, let's analyze deployment to both chains.</p>
<p>In the following sections of this article, we will create a simple NFT contract and deploy it to Polygon Mumbai and Ethereum Goerli testnets. We will observe how the development process for both chains is nearly identical.</p>
<p>Next, we will analyze NFT contracts that have been deployed previously (by other teams) on Ethereum and Polygon mainnets, and then compare cost and confirmation times.</p>
<h3 id="heading-overview-of-the-nft-project"><strong>Overview of the NFT Project</strong></h3>
<p>The project that we're going to create is extremely simple. We want to write and deploy an ERC-721 contract that mints a single NFT to the blockchain of our choice.</p>
<p>The first step in such projects is to create the NFT art, its associated metadata, and upload it to IPFS. For this tutorial, we have already done this for you.</p>
<p>You can check out the image uploaded to IPFS <a target="_blank" href="https://gateway.pinata.cloud/ipfs/QmeDadHM1U3jVw1pMpZ5ZENBJhFGafHQeUNTNoapw7j3mq">here</a> and the associated NFT metadata <a target="_blank" href="https://gateway.pinata.cloud/ipfs/QmUyZoK21qb8YknXGfDB34RTY8vMqPb6Bsj9U9iLEnyrZR">here</a>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lgm2gpvg1c0ju1p41sh.png" alt /></p>
<p>In case you're interested in learning more about NFT metadata, IPFS, and Pinata, check out this article <a target="_blank" href="https://dev.to/rounakbanik/working-with-nft-metadata-ipfs-and-pinata-3ieh">here</a>.</p>
<h3 id="heading-creating-the-nft-contract"><strong>Creating the NFT Contract</strong></h3>
<h4 id="heading-step-1-install-the-metamask-extension"><strong>Step 1: Install the MetaMask Extension</strong></h4>
<p>In case you haven't already, install the <a target="_blank" href="https://metamask.io/download/">MetaMask extension</a> for your browser. Once installed, MetaMask will guide you through creating your first wallet.</p>
<h4 id="heading-step-2-add-goerli-and-mumbai-chains-to-metamask"><strong>Step 2: Add Goerli and Mumbai Chains to MetaMask</strong></h4>
<p>By default, MetaMask comes with the Ethereum mainnet and the Goerli testnet configured. To add the Polygon mainnet and the Mumbai testnet chains, follow the instructions in <a target="_blank" href="https://docs.polygon.technology/docs/develop/metamask/config-polygon-on-metamask/">this document</a>.</p>
<h4 id="heading-step-3-get-goerlieth-and-mumbai-matic-from-a-faucet"><strong>Step 3: Get GoerliETH and Mumbai MATIC from a Faucet</strong></h4>
<p>Head over to Alchemy's <a target="_blank" href="https://goerlifaucet.com/">Goerli faucet page</a> and request some free GoerliETH. You may be required to create a free Alchemy account for this.</p>
<p>If all goes well, you should have 0.05 GoerliETH in your wallet when you switch to the Goerli test network.</p>
<p>In the same vein, acquire some free Mumbai MATIC from <a target="_blank" href="https://faucet.polygon.technology/">Polygon's official faucet</a>. If successful, switching to the Mumbai chain should tell you that you have a balance of 0.2 MATIC.</p>
<h4 id="heading-step-4-install-npm-and-node"><strong>Step 4: Install NPM and Node</strong></h4>
<p>We will build our project using JavaScript and node. In case you don't have node and npm installed on your local machine, you can do so <a target="_blank" href="https://nodejs.org/en/download/">here</a>.</p>
<p>You can ensure that everything is working properly by checking the version number of node on your terminal.</p>
<pre><code class="lang-bash">$ node -v
</code></pre>
<h4 id="heading-step-5-create-a-node-project-and-install-dependencies"><strong>Step 5: Create a Node Project and Install Dependencies</strong></h4>
<p>Let's set up an empty project repository by running the following commands:</p>
<pre><code class="lang-bash">$ mkdir nft-contract &amp;&amp; <span class="hljs-built_in">cd</span> nft-contract
$ npm init -y
</code></pre>
<p>We will be using Hardhat, an industry-standard Ethereum development environment, to build and deploy our smart contract. Install Hardhat by running:</p>
<pre><code class="lang-bash">$ npm install --save-dev hardhat
</code></pre>
<p>We can now create a sample Hardhat project by running the following command and choosing <strong>Create a basic sample project</strong>.</p>
<pre><code class="lang-bash">$ npx hardhat
</code></pre>
<p>Agree to all the defaults (project root, adding a <code>.gitignore</code>, and installing all sample project dependencies).</p>
<p>To check if everything works properly, run:</p>
<pre><code class="lang-bash">$ npx hardhat <span class="hljs-built_in">test</span>
</code></pre>
<p>We now have our Hardhat development environment successfully configured. Let us next install the OpenZeppelin contracts package. This will give us access to ERC-721 implementations (the standard for NFTs), on top of which we will build our contract.</p>
<pre><code class="lang-bash">$ npm install @openzeppelin/contracts
</code></pre>
<h4 id="heading-step-6-writing-the-smart-contract"><strong>Step 6: Writing the Smart Contract</strong></h4>
<p>Open the repository in your favorite code editor (e.g. VS Code). In the <code>contracts</code> folder, create a new file called <code>NFTContract.sol</code>.</p>
<p>We are going to create a very simple ERC-721 contract that mints a single NFT when deployed (i.e. within the constructor). Add the following code to the file:</p>
<pre><code class="lang-Solidity"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.4;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"</span>;

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">NFTContract</span> <span class="hljs-keyword">is</span> <span class="hljs-title">ERC721URIStorage</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) <span class="hljs-title">ERC721</span>(<span class="hljs-params"><span class="hljs-string">"Panda NFT"</span>, <span class="hljs-string">"PNFT"</span></span>) </span>{

        <span class="hljs-comment">// Mint NFT</span>
        _mint(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-number">0</span>);

        <span class="hljs-comment">// Set metadata</span>
        _setTokenURI(<span class="hljs-number">0</span>, <span class="hljs-string">"ipfs://QmUyZoK21qb8YknXGfDB34RTY8vMqPb6Bsj9U9iLEnyrZR"</span>);

    }
}
</code></pre>
<h4 id="heading-step-7-deploy-the-contract-locally"><strong>Step 7: Deploy the Contract Locally</strong></h4>
<p>Let's now write a script to deploy and test the contract locally. In the scripts folder, create a new file called <code>run.js</code> and add the following code:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">const</span> hre = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">const</span> contractFactory = <span class="hljs-keyword">await</span> hre.ethers.getContractFactory(<span class="hljs-string">"NFTContract"</span>);
  <span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> contractFactory.deploy();

  <span class="hljs-keyword">await</span> contract.deployed();

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contract deployed to:"</span>, contract.address);
}

main()
  .then(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>))
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
    process.exit(<span class="hljs-number">1</span>);
});
</code></pre>
<p>Now run the following command on your terminal:</p>
<pre><code class="lang-Bash">$ npx hardhat run scripts/run.js
</code></pre>
<h4 id="heading-step-8-deploy-the-contract-to-goerli"><strong>Step 8: Deploy the Contract to Goerli</strong></h4>
<p>In order to deploy the contract to Goerli, we have to add the network to the <code>hardhat.config.js</code> file. Replace the <code>module.exports</code> object at the end of the file with the following:</p>
<pre><code class="lang-JSON">module.exports = {
  solidity: <span class="hljs-string">"0.8.4"</span>,
  networks: {
    goerli: {
      url: <span class="hljs-string">"https://ethereum-goerli-rpc.allthatnode.com/"</span>,
      accounts: [<span class="hljs-string">"&lt;-- WALLET PRIVATE KEY --&gt;"</span>]
    }
  }
};
</code></pre>
<p>Replace the placeholder with your MetaMask wallet's private key. (This can be found in <em>Account Details.</em>) Take care to never share this key or file publicly.</p>
<p>To deploy to the Goerli testnet, run the following command:</p>
<pre><code class="lang-Bash">npx hardhat run scripts/run.js --network goerli
</code></pre>
<p>If all goes well, your terminal will display the address of the deployed contract on the Goerli network. Head over to <a target="_blank" href="https://goerli.etherscan.io/">https://goerli.etherscan.io</a> and search for your contract address to view your contract.</p>
<p>You can find the contract that we deployed <a target="_blank" href="https://goerli.etherscan.io/address/0x64ccE52898F5d61380D2Ec8C02F2EF16F28436de">here</a>.</p>
<h4 id="heading-step-9-deploy-the-contract-to-mumbai"><strong>Step 9: Deploy the Contract to Mumbai</strong></h4>
<p>Let's now deploy our contract to the Polygon Mumbai network. The best part of this step is that we have to change <strong>absolutely nothing</strong> in our contract or the run script. The only thing we need to add is the <code>mumbai</code> network to <code>hardhat.config.js</code>.</p>
<pre><code class="lang-JSON">module.exports = {
  solidity: <span class="hljs-string">"0.8.4"</span>,
  networks: {
    goerli: {
      url: <span class="hljs-string">"https://ethereum-goerli-rpc.allthatnode.com/"</span>,
      accounts: [<span class="hljs-string">"&lt;-- WALLET PRIVATE KEY --&gt;"</span>]
    },
    mumbai: {
      url: <span class="hljs-string">"https://rpc-mumbai.maticvigil.com"</span>,
      accounts: [<span class="hljs-string">"&lt;-- WALLET PRIVATE KEY --&gt;"</span>]
    }
  }
};
</code></pre>
<p>Deploy to Mumbai by running:</p>
<pre><code class="lang-Bash">npx hardhat run scripts/run.js --network mumbai
</code></pre>
<p>You can search for your contract address at <a target="_blank" href="https://mumbai.polygonscan.com/">https://mumbai.polygonscan.com</a>. You can find our contract <a target="_blank" href="https://mumbai.polygonscan.com/address/0x785e970C281ecFCBbc83b1CA1b32Fb30BA0E08B3">here</a>.</p>
<p>You can also search for your Goerli and Mumbai NFTs on <a target="_blank" href="https://testnets.opensea.io/">OpenSea Testnets</a>. For example, <a target="_blank" href="https://testnets.opensea.io/assets/mumbai/0x785e970c281ecfcbbc83b1ca1b32fb30ba0e08b3/0">here</a> is the NFT we minted on the Mumbai network.</p>
<h3 id="heading-comparing-cost-and-time"><strong>Comparing Cost and Time</strong></h3>
<p>By now, it should be abundantly clear that developing for Ethereum and the Polygon sidechain is nearly identical.</p>
<p>But what are the cost and time implications?</p>
<p>We won't be able to answer these questions with the contracts we deployed since we were operating on testnets using fake money.</p>
<p>But not to worry. We have deployed these contracts to the Ethereum and Polygon mainnets on your behalf. Let’s take a look at the performance.</p>
<h4 id="heading-ethereum"><strong>Ethereum</strong></h4>
<p>You can check out the deployed NFT contract on Ethereum <a target="_blank" href="https://etherscan.io/address/0x5acea83cd77703773429959e66cc2c2f648262a7">here</a> and the contract creation transaction <a target="_blank" href="https://etherscan.io/tx/0x26ac19375af708c7d7b9266d9aae9198f49b41124f49af68dc1d28963f6363af">here</a>.</p>
<p>Despite the recent drops in Ethereum prices (in terms of USD) and average gas prices (in terms of gwei), you can see that contract deployment cost around <strong>0.02 ETH or $40</strong>.</p>
<p>The time to confirm this Ethereum transaction was <strong>approximately 40 seconds.</strong></p>
<h4 id="heading-polygon"><strong>Polygon</strong></h4>
<p>You can check out the deployed NFT contract on Polygon <a target="_blank" href="https://polygonscan.com/address/0xceb61fdf7130d170c50c02e3a9bed4eb83b42a46">here</a> and the contract creation transaction <a target="_blank" href="https://polygonscan.com/tx/0x95c2bbbb79ab07db7ea656b0506c88bd3f3e83e485e1d075f770581f312ffd06">here</a>.</p>
<p>Notice that we paid 0.06 MATIC when MATIC was trading at $0.94. Therefore, we paid <strong>$0.06 to deploy the contract</strong>.</p>
<p>The time to confirm this transaction was <strong>6 seconds</strong>.</p>
<p>In essence, this contract was confirmed almost <strong>7 times faster and with a cost reduction of 1000x</strong>!</p>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>Ethereum is easily the most important smart contract blockchain in existence. However, it faces huge obstacles when it comes to scale and transaction costs.</p>
<p>Hopefully, this article has made a strong case for why Polygon is an excellent panacea to Ethereum's scalability problems. By operating as a PoS sidechain, it significantly increases processing speeds and reduces costs.</p>
<p>For Ethereum developers, building on Polygon requires almost zero additional upskilling. Ethereum tools are compatible with both environments. To start  building on Polygon, check out the documentation <a target="_blank" href="https://docs.polygon.technology/docs/develop/getting-started/">here</a>.</p>
]]></content:encoded></item><item><title><![CDATA[No-Code: Buy Me a Coffee With Coinbase!]]></title><description><![CDATA[Introduction
I never thought of myself as a writer. However, it turns out I actually have a knack for it! Learning new technology and then writing about it helps me solidify the concepts. As an added bonus, I’m able to help teach others on the same p...]]></description><link>https://blog.paulmcaviney.ca/no-code-buy-me-a-coffee-with-coinbase</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/no-code-buy-me-a-coffee-with-coinbase</guid><category><![CDATA[Web3]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[No Code]]></category><category><![CDATA[coinbase]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Tue, 19 Jul 2022 15:30:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1658183133599/Wnzddl1N5.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I never thought of myself as a writer. However, it turns out I actually have a knack for it! Learning new technology and then writing about it helps me solidify the concepts. As an added bonus, I’m able to help teach others on the same path as me. Creating technical content is fun! Eating cheap, frozen dinners every night is not. So how can I start accepting payment for all the hard work I’m putting in?</p>
<p>Some of my readers suggested I build a “<em>Buy Me A Coffee</em>” type feature on my website. This simple method to start accepting crypto donations could be my answer to move from frozen dinners to fresh produce!  </p>
<p>This article will explain how I installed a method to receive crypto donations using no-code solutions by Coinbase Commerce. Then, we’ll build a simple project so you can see just how easy it is and how little code is involved.</p>
<h2 id="heading-the-problem-broke-but-still-building">The Problem: Broke But Still Building</h2>
<p>I tell my <a target="_blank" href="https://blog.paulmcaviney.ca/">readers</a> and <a target="_blank" href="https://twitter.com/paul_can_code">Twitter followers</a> all the time that creating content around web3 tech is one of the best ways to learn it. Writing about something quickly points out any gaps in your knowledge. It’s a fast track to understanding these complicated networks and how they operate at a technical level. However, what I don’t tell them is that when you’re first starting out, writing technical articles doesn’t exactly pay the bills if you don’t have any clients yet.</p>
<p>Clients or not, helping others learn through content creation is rewarding. One of my favorite aspects of being a technical writer is when a reader reaches out saying that I helped them solve a problem or learn something new. Some of these readers even expressed interest in returning the favor. They suggested I build a “<em>Buy Me A Coffee</em>” type feature on my website. This seemed like an excellent way to get paid for the hard work I put into my content.</p>
<p>Building a feature like this from scratch sounds like a nightmare, though. I don’t have time to improve my frontend skills to do this properly; I just want to focus on web3 stuff! So I started looking for an easier solution—and found one with <a target="_blank" href="https://docs.cloud.coinbase.com/commerce/docs">Coinbase Commerce</a>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8sss9rk9ypqtsrml6tbm.png" alt /></p>
<h2 id="heading-the-solution-no-code-with-coinbase-commerce">The Solution: No-Code With Coinbase Commerce</h2>
<p>Coinbase Commerce has easy-to-install payment gateways that make it simple to accept crypto. I can use this to create a “<em>Buy Me A Coffee</em>” feature on my site, no problem!</p>
<p>As a plus, I’m already familiar with Coinbase. I’ve been trading cryptocurrencies since 2017, and Coinbase was the first crypto exchange I ever signed up for.</p>
<p>Installing the donation gateway was easy. All I had to do was create the gateway in my Coinbase Commerce dashboard and then copy the code it generated onto my site. Then with only minor adjustments to the code, I got it to look how I wanted. Now I’m ready to start accepting crypto donations so I can hopefully treat myself to something a little better than frozen pizzas.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdr4jj60zxq4mkgmxupb.png" alt /></p>
<h2 id="heading-how-to-install-a-crypto-donations-button">How to Install a Crypto Donations Button</h2>
<p>For the rest of the article, we’ll run through creating a crypto donations button to show you just how easy it is. We’ll go through it step by step, so even if you’re not a developer, you’ll be able to start accepting crypto in minutes</p>
<hr />
<hr />
<h3 id="heading-what-youll-learn">What You’ll Learn</h3>
<ul>
<li>How to easily install a link on your website to start accepting crypto donations</li>
</ul>
<h3 id="heading-what-youll-need">What You’ll Need</h3>
<ul>
<li>A <a target="_blank" href="https://commerce.coinbase.com/">Coinbase Commerce account</a></li>
<li>The <a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&amp;gl=US">Google Authenticator App</a> on your phone (for 2-step account verification)</li>
<li>A website to install your link on</li>
</ul>
<h3 id="heading-additional-resources">Additional Resources</h3>
<ul>
<li><a target="_blank" href="https://commerce.coinbase.com/docs/">Coinbase Commerce Docs</a></li>
</ul>
<hr />
<hr />
<h3 id="heading-step-1-set-up-a-coinbase-commerce-account">Step 1 - Set Up a Coinbase Commerce Account</h3>
<p>The first step in getting a button to accept crypto donations is to set up a Coinbase Commerce account. Head to <a target="_blank" href="https://commerce.coinbase.com/">https://commerce.coinbase.com/</a> and select the <strong>Get Started</strong> button. Follow the steps to get everything set up correctly.</p>
<ul>
<li>Choose the <em>Self managed</em> option to get started with just an email address.</li>
<li>Verify your account through email.</li>
<li>Set up 2-step verification using the <a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&amp;gl=US">Google Authenticator</a> app on your phone.</li>
<li>Set up a Coinbase Crypto Wallet. <ul>
<li><strong><em>IMPORTANT!</em></strong>– Write down your seed phrase somewhere safe! Anyone with this seed phrase can empty your wallet!</li>
<li>Verify your seed phrase in the next step. </li>
<li>Lastly, you can save an encrypted version of your wallet to Google Drive if you want, but it’s not necessary.</li>
</ul>
</li>
</ul>
<p>After completing all the above steps, go to your new dashboard!</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cazrqhu36uvsj9p32rl8.png" alt /></p>
<h3 id="heading-step-2-whitelist-your-website">Step 2 - Whitelist Your Website</h3>
<p>Now that you have a place to send any funds you may receive, the next step is to add your website to the whitelist. This just means adding your website to a list of approved websites that are allowed to host your new payment button. You wouldn’t want just anyone installing it wherever they want!</p>
<p>Click on your email address in the top right corner of the screen and select <strong>Settings</strong>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxru4qsijzf3qzmmtj8c.png" alt /></p>
<p>Next, select the <strong>Security</strong> tab and click on the <strong>Whitelist a domain</strong> button. Enter the full URL of your website, including the <code>https://</code> part. If this is successful, you will now see it in the list of approved sites.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2ja75w7y48a2i449fsk.png" alt /></p>
<p><strong>Note:</strong> If you are a developer testing on a locally hosted instance of your website, you do not need to whitelist <code>localhost</code>.</p>
<h3 id="heading-step-3-create-a-checkout">Step 3 - Create a Checkout</h3>
<p>The next step is to create the payment gateway your donate button will send the user to. Click on the <strong>Checkouts</strong> tab on the left-hand side of the screen, then select <strong>Create a checkout</strong>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfpgxzxep0a41r93066o.png" alt /></p>
<p>Fill in the details for your checkout, giving it a name, description, and image if you’d like. Then, select <strong>Let your visitors choose</strong> under the <strong>"What kind of pricing do you want to offer?”</strong> heading to accept donations. You can also ask for additional information from the person donating, but this is optional.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ffiytb1g1bzvgkibdx0m.png" alt /></p>
<p>Once you have filled in the details, click on the <strong>Create checkout</strong> button at the bottom to finish. A popup will display some options for you to share your new checkout.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8cpwbs8pqjng0g6tiztm.png" alt /></p>
<p>You can <strong>share</strong> your checkout link directly, <strong>copy the code</strong> to create the Donation Button on your website, or select <strong>View checkout</strong> to see it in action.</p>
<h3 id="heading-step-4-add-the-code-to-your-website">Step 4 - Add the Code to Your Website</h3>
<p>The final step is to place the checkout code on your website. So navigate to your <code>index.html</code> or whichever page you want to put the button on and paste the code where it makes sense for you. For example, I added mine to the bottom of my hero section and changed the Button text to say “Buy Me A Coffee”.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0szqs06mgws6uwtln8o3.png" alt /></p>
<p>Now clicking on the Donate button will send any charitable users to your shiny, new checkout page where they can donate as much as they like in multiple cryptocurrencies. Here’s what mine looks like: </p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9tetu41xuz4kvrfmhfw.png" alt /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating web3 technical content is challenging, yet rewarding. Any newcomer will see that it is a fast way to learn concepts quickly. However, they will also learn that being a content creator takes a while to start being a profitable career choice. This is where a “<em>Buy Me A Coffee</em>” button helps a lot.</p>
<p>This no-code solution makes things simple for anyone to make a crypto payment gateway in minutes. Now that I’ve got this fancy, new feature on my website, I can start accepting donations for all the hard work I put into creating content! No more frozen dinners for this guy! I’m moving up in the world!</p>
<p>If this article has helped you, maybe <a target="_blank" href="https://commerce.coinbase.com/checkout/7acfc6cf-bfe3-4e0e-bbd0-7f10dc4d9cb5">Buy Me A Coffee</a>? ;)</p>
]]></content:encoded></item><item><title><![CDATA[Using Infura’s NFT API With Lootbox]]></title><description><![CDATA[Introduction
I’ve only been in Web3 for about a year now, but I can honestly say that NFTs are the most exciting aspect about it for me. I’m not talking about Apes or Punks, however. PFP (profile picture) projects and art, although cool and a simple ...]]></description><link>https://blog.paulmcaviney.ca/using-infuras-nft-api-with-lootbox</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/using-infuras-nft-api-with-lootbox</guid><category><![CDATA[Web3]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[NFT]]></category><category><![CDATA[infura]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Thu, 07 Jul 2022 20:55:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1657225039662/r7t-uiC92.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I’ve only been in Web3 for about a year now, but I can honestly say that NFTs are the most exciting aspect about it for me. I’m not talking about Apes or Punks, however. PFP (profile picture) projects and art, although cool and a simple proof of concept for the technology, won’t create a better world. </p>
<p>Instead, I’m excited about the actual utility of NFTs. Allowing gamers to own their assets, delivering fair royalty commissions to musicians and artists, and making concert tickets impossible to scalp while providing a sweet digital memento are some of the use cases I find interesting.</p>
<p>However, building and interacting with NFTs aren’t always the easiest thing to do. As developers, we need clear resources to build projects effectively in order to give our users a better experience. </p>
<p>I recently heard about <a target="_blank" href="https://infura.io/resources/apis/nft-api-beta-signup">Infura’s private beta for their NFT API</a>, so I thought I would check it out and see how it could improve my development workflow. In this article, I will explore the capabilities of Infura’s NFT API and test it out using a Lootbox NFT sample project from Infura’s Github.</p>
<h2 id="heading-what-is-the-infura-nft-api">What is the Infura NFT API?</h2>
<p>According to <a target="_blank" href="https://blog.infura.io/post/introducing-the-infura-nft-api-beta-release">this blog post</a> on Infura’s website, the NFT API will help me “accelerate my time to value” and allow me to interact with anything related to NFTs through a convenient SDK. In addition, I can build and verify my NFTs, create metadata templates and easily mint NFTs. So my first impression is that I can start creating and interacting with NFTs using API endpoints rather than building smart contracts and deploying them.</p>
<p>Sounds pretty useful! And I’m all for testing any tool that will help improve my development processes. Infura’s NFT API suite seems helpful for any dev transitioning from Web2, since you can run API endpoints without Solidity.  </p>
<p>Now let’s dive deeper and see what this NFT API is capable of.</p>
<h2 id="heading-infura-nft-api-capabilities">Infura NFT API Capabilities</h2>
<p>A quick glance through the <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk">NFT API documentation</a> on Infura’s website proves my first impression correct. I will be able to deploy and call methods on my NFT contracts using Infura’s API endpoints, without having to actually write the smart contract code. This is a huge time saver! </p>
<p><a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/how-to/deploy-a-contract">Deploying a contract</a> is straightforward. I create the NFT metadata in JSON format, <a target="_blank" href="https://docs.infura.io/infura/networks/ipfs/how-to/make-requests">upload the metadata to IPFS</a> in another Infura project, then create a simple deployment script and run it with node. I also have to make a <code>.env</code> file to hold some environment variables. My deployment script ends up looking something like this:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">import</span> { config <span class="hljs-keyword">as</span> loadEnv } <span class="hljs-keyword">from</span> <span class="hljs-string">'dotenv'</span>;
<span class="hljs-keyword">import</span> { SDK, Auth, TEMPLATES } <span class="hljs-keyword">from</span> <span class="hljs-string">'@infura/sdk'</span>;

loadEnv();

<span class="hljs-keyword">const</span> auth = <span class="hljs-keyword">new</span> Auth({
      <span class="hljs-attr">projectId</span>: process.env.INFURA_PROJECT_ID,
      <span class="hljs-attr">secretId</span>: process.env.INFURA_PROJECT_SECRET,
      <span class="hljs-attr">privateKey</span>: process.env.WALLET_PRIVATE_KEY,
      <span class="hljs-attr">chainId</span>: <span class="hljs-number">4</span>,
    });

<span class="hljs-keyword">const</span> sdk = <span class="hljs-keyword">new</span> SDK(auth);

<span class="hljs-keyword">const</span> myNFTContract = <span class="hljs-keyword">await</span> sdk.deploy({
   <span class="hljs-attr">template</span>: TEMPLATES.ERC721Mintable,
   <span class="hljs-attr">params</span>: {
     <span class="hljs-attr">name</span>: <span class="hljs-string">'My NFT Contract'</span>,
     <span class="hljs-attr">symbol</span>: <span class="hljs-string">'MYNFT'</span>,
     <span class="hljs-attr">contractURI</span>: <span class="hljs-string">'https://MY_NFT_METADATA_URL'</span>,
   },
 });
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Contract address is: <span class="hljs-subst">${myNFTContract.contractAddress}</span>`</span>);
</code></pre>
<p>Then, I run it with Node. Infura creates a smart contract for me and uploads it to Ethereum behind the scenes. After that, I just need to make sure I have some tokens for whichever <code>chainId</code> I have specified in my code. In this case, the Rinkeby testnet (chainId: 4). From here, I could <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/how-to/mint-an-nft">mint NFTs</a> from this contract or gather the contract metadata. </p>
<p>This is a much easier method to create an NFT contract than writing Solidity code and deploying it myself!</p>
<p>The NFT API also provides methods for <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/how-to/get-nft-information">gathering NFT info</a> from wallets, <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/how-to/transfer-an-nft">transferring NFTs</a> from one wallet to another, and a host of other <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/apis/javascript-api/templates/erc721mintable-methods">NFT methods</a>. These include <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/apis/javascript-api/templates/erc721mintable-methods/addminter">adding an address to the minter list</a>, <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/apis/javascript-api/templates/erc721mintable-methods/setroyalties">setting royalty info</a>, and <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/apis/javascript-api/templates/erc721mintable-methods/setcontracturi">changing the contract URI</a>. </p>
<p>Overall, it seems that Infura’s NFT API indeed helps improve my development workflow. Having all the necessary functionality for building and interacting with NFTs packaged together in an easy-to-use SDK is quite convenient!</p>
<p>But enough about what it can do, let’s see how this API works!</p>
<h2 id="heading-the-lootbox-project">The Lootbox Project</h2>
<p>Along with the NFT API, Infura released an <a target="_blank" href="https://github.com/INFURA/nft-api-lootbox-gallery-app">NFT Gallery Project on their Github</a> to demo its capabilities. All I will have to do is input an Infura project ID and secret, then connect my MetaMask wallet to the dapp frontend. Then the dapp uses the API to fetch all my NFTs to display nicely in the frontend. So to break that down, I will need the following things for this project:</p>
<ul>
<li>An <a target="_blank" href="https://infura.io/">Infura account</a></li>
<li>Infura Project ID and Secret</li>
<li>A <a target="_blank" href="https://metamask.io/">MetaMask wallet extension</a> with NFTs in it </li>
</ul>
<p>Let’s get started!</p>
<h3 id="heading-step-1-the-infura-project-id-and-secret">Step 1 - The Infura Project ID and Secret</h3>
<p>Before starting the Lootbox project, I want to gather the necessary items. So first, I’ll head to <a target="_blank" href="https://infura.io/">infura.io</a>, log in, and create a new project. Then, I can grab the <strong>Project ID</strong> and <strong>Project Secret</strong> for use later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156660361/iM4_70xaC.png" alt="A new project dialogue box on Infura" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156667916/tBjafxDSg.png" alt="The project ID and project secrets, highlighted in red, showing the reader where to copy from" /></p>
<h3 id="heading-step-2-metamask">Step 2 - MetaMask</h3>
<p>This step will be quick because I already have the extension installed in my browser. If someone following along with this article doesn’t, however, head to <a target="_blank" href="https://metamask.io/">metamask.io</a> and <a target="_blank" href="https://metamask.io/download/">download</a> the extension for your specific browser. Then follow the steps to create a new account.</p>
<p>Next, I’ll sign in and switch accounts to the wallet address that holds my NFTs. If you need to acquire an NFT, you can head to <a target="_blank" href="https://looksrare.org/">your favorite marketplace</a> and buy one or try to create one yourself using the Infura NFT API 😉. Either way, you will need some ETH in your wallet.</p>
<h3 id="heading-step-3-setting-up-the-project">Step 3 - Setting Up The Project</h3>
<p>With all the prep work out of the way, I can start building the project. So next, I’ll clone the project repo onto my local machine. I’ll first navigate to the folder I want to work out of and then type the following command:</p>
<pre><code class="lang-Bash">git <span class="hljs-built_in">clone</span> https://github.com/INFURA/nft-api-lootbox-gallery-app.git
</code></pre>
<p>Next, I will change directories into the project folder and install dependencies using <a target="_blank" href="https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable">yarn</a>:</p>
<pre><code class="lang-Bash"><span class="hljs-built_in">cd</span> nft-api-lootbox-gallery-app
yarn
</code></pre>
<p>After everything is installed, the last thing I need to do is create a <code>.env</code> file to store my environment variables and secrets. I’ll just copy the file that’s already there and add my variables to it.</p>
<pre><code class="lang-Bash">cp .env .env.local
</code></pre>
<p>Now I’ll open up the project and add my <strong>Project ID</strong> and <strong>Project Secret</strong> from my recently created Infura project. There’s also an option to input the Account Address of any wallet to view their NFTs, but I’ve got my own I want to see in the Lootbox NFT Gallery.</p>
<p>With all the setup out of the way, I can finally run the Lootbox project. But first, I want to browse through the code to see what’s happening under the hood.</p>
<h3 id="heading-step-4-the-lootbox-code">Step 4 - The Lootbox Code</h3>
<p>Based on the <a target="_blank" href="https://github.com/INFURA/nft-api-lootbox-gallery-app#readme">README file</a> of the Lootbox project, the most important components are in the <code>pages/index.tsx</code>, <code>hooks/useWallet.ts</code>, and <code>pages/api/assets.ts</code> files. So I’m going to browse those and see if I can figure out how this project uses the Infura NFT API.</p>
<p>After looking through these files, I can see the <code>pages/index.tsx</code> file contains the code which displays the frontend for the project. If the <code>showGallery</code> state variable is true, then it should display my NFTs. If it’s false, then it should display the welcome text with the <strong>Connect Wallet</strong> button. This Connect Wallet button connects to some functions in the <code>hooks/useWallet.ts</code> file, so I’ll check there next.</p>
<p>In the <code>hooks/useWallet.ts</code> file, I can see the function which is supposed to grab my NFTs. Specifically, the <code>getTokens</code> function.</p>
<pre><code class="lang-JavaScript"> <span class="hljs-keyword">const</span> getTokens = <span class="hljs-keyword">async</span> (accountAddress: string) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">'/api/assets'</span>, { accountAddress });
      <span class="hljs-keyword">return</span> data.assets;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
        setErrorMessage(<span class="hljs-string">'Error getting tokens'</span>);
      }, <span class="hljs-number">2000</span>);
      <span class="hljs-keyword">return</span>;
    }
  };
</code></pre>
<p>This function seems to make a POST request using a parameter from the <code>/api/assets</code> file and return the results with my assets. So looking into the <code>pages/api/assets.ts</code> file, I can see where the NFT API is being used. </p>
<pre><code class="lang-JavaScript">  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> axios.get(  <span class="hljs-string">`https://nft.api.infura.io/networks/1/accounts/<span class="hljs-subst">${accountAddress}</span>/assets/nfts`</span>,
      {
        <span class="hljs-attr">headers</span>: {},
        <span class="hljs-attr">auth</span>: {
          <span class="hljs-attr">username</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.INFURA_PROJECT_ID}</span>`</span>,
          <span class="hljs-attr">password</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.INFURA_PROJECT_SECRET}</span>`</span>
        }
      }
    );

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">assets</span>: data.assets,
    });
</code></pre>
<p>This code calls the <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk/apis/javascript-api/sdk/getnfts">get function of the NFT API</a>, using my <code>Infura Project ID</code> and <code>Project Secret</code> to access my account, and returns my NFTs in a JSON object. Following the path back to the <code>pages/index.tsx</code> file, if the <code>getTokens</code> function from <code>hooks/useWallet.ts</code> doesn’t timeout, it will return my NFTs, switch the <code>setGallery</code> state variable to <code>true</code>, and display my NFTs on the page.</p>
<p>Cool! So I’ve got an idea of how it works, let’s see it in action!</p>
<h3 id="heading-step-5-running-the-lootbox-project">Step 5 - Running The Lootbox Project</h3>
<p>To run the project locally, I just need to type:</p>
<pre><code class="lang-Bash">yarn dev
</code></pre>
<p>After navigating to <a target="_blank" href="http://localhost:3000/">http://localhost:3000/</a>, I can see a nice-looking frontend for the Lootbox Project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156535309/Cm6kzROX3.png" alt="The Lootbox project main page displays the title &quot;Creat an NFT Gallery&quot; and there is a button to connect your web3 wallet" /></p>
<p>Clicking on <strong>Connect Wallet</strong> prompts my MetaMask wallet to pop up to approve the connection request.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156522069/Y-_LxW3BW.png" alt="MetaMask pops up, prompting me to connect my wallet" /></p>
<p>After connecting, it immediately starts fetching my tokens. This is the point where I now know the dapp is using the NFT API.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156505691/oOjts2qlm.png" alt="It says: &quot;Fetching Tokens&quot; and has a loading symbol next to it" /></p>
<p>Once the fetch is successful, it displays my NFTs in a fancy gallery, allowing me to browse and choose each one to get a better look at them. Neat!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1657156493427/PsKk_F5br.png" alt="My NFTs displayed successfully" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>My verdict on the Infura NFT API is that it's a tool that cuts down my development time, and there’s quite a bit I can do with it. It’s handy to build, mint, and interact with NFTs from an easy-to-use API. Although I am more familiar with building NFT contracts with Solidity and deploying them with Truffle, I can easily see how this would help smooth the transition of a Web2 dev into Web3. Using JavaScript rather than writing a smart contract will be a huge time saver for many Web2 developers.</p>
<p>I would suggest trying the NFT API out for yourself. It’s still in private beta, but anyone can <a target="_blank" href="https://infura.io/resources/apis/nft-api-beta-signup">register</a>. For more information on its capabilities, you can check out <a target="_blank" href="https://www.youtube.com/watch?v=ERV_FbCDBIQ">this YouTube demo</a> or <a target="_blank" href="https://docs.infura.io/infura/features/nft-sdk">Infura’s documentation</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Accessing Ethereum Archive Nodes With Infura]]></title><description><![CDATA[Introduction
Archive nodes are particular nodes on the Ethereum Network that store historical blockchain data. Because they offer this historical information, they are helpful when you need to audit past transaction history or gather data. Services l...]]></description><link>https://blog.paulmcaviney.ca/accessing-ethereum-archive-nodes-with-infura</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/accessing-ethereum-archive-nodes-with-infura</guid><category><![CDATA[Web3]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Wed, 01 Jun 2022 15:11:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653933955986/egTJMeVQ3.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Archive nodes are particular nodes on the Ethereum Network that store historical blockchain data. Because they offer this historical information, they are helpful when you need to audit past transaction history or gather data. Services like <a target="_blank" href="https://etherscan.io/">Etherscan</a> and <a target="_blank" href="https://docs.dune.xyz/">Dune Analytics</a> use archive nodes, but anyone can run one themselves. </p>
<p>In this article, we will review the different types of Ethereum nodes, dive deeper into Archive Nodes, and introduce the new archive node capabilities of Infura. We’ll then walk through a real-world project to show how to connect the Infura API and web3.js to a pre-built react frontend. Once complete, the user will be able to query an Archive Node for some statistics for a given Ethereum wallet address.</p>
<h2 id="heading-what-are-ethereum-nodes">What Are Ethereum Nodes?</h2>
<p>In simple terms, a node is just a connection point in a network. However, in the case of Ethereum, different types of nodes hold various responsibilities to the network.</p>
<p>The Ethereum blockchain operates on what is called the <a target="_blank" href="https://ethereum.org/en/developers/docs/evm/">Ethereum Virtual Machine</a> (EVM), which is a type of decentralized <a target="_blank" href="https://etherscan.io/nodetracker">global</a> computer. Nodes, in this case, provide the processing power for this computer. They serve requested data, create and validate blocks, store transaction data or smart contract code, and much more. Anyone with the required hardware can download an <a target="_blank" href="https://ethereum.org/en/developers/docs/nodes-and-clients/#execution-clients">Ethereum client</a> and spin up their own node to participate in the network. This also prevents any single entity from controlling the entire network and contributes to Ethereum’s decentralization.</p>
<p>There are four main types of Ethereum nodes, each contributing to the network differently. Together they relay information to other nodes, verify transactions and the EVM state, and provide the infrastructure needed to keep the Ethereum Network operating efficiently. They communicate with one another to ensure they all agree on the state of the network. Therefore, having more nodes makes the network stronger and more resilient to <a target="_blank" href="https://www.investopedia.com/terms/1/51-attack.asp">attacks</a>. </p>
<h2 id="heading-types-of-ethereum-nodes">Types of Ethereum Nodes</h2>
<h3 id="heading-full-node">Full Node</h3>
<p>Full Nodes verify transactions and EVM state, validate blocks, launch and execute smart contract code, and can serve network data when requested. They also store the state of the Ethereum Blockchain up to the most recent 128 blocks but can build an archive of historical states on demand.</p>
<h3 id="heading-mining-node-commonly-referred-to-as-a-miner">Mining Node (Commonly referred to as a “Miner”)</h3>
<p>A Miner is a Full Node running a <a target="_blank" href="https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/mining/">mining client</a>. In its present state, Ethereum provides consensus through the <a target="_blank" href="https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/">proof-of-work</a> algorithm. To summarize, this means a mining node competes in a computation race with other mining nodes to create the next block. Once created, the new block is broadcast to the network to be verified by other nodes and appended to the end of the blockchain.</p>
<h3 id="heading-light-node">Light Node</h3>
<p>A Light Node is a “light” version of a Full Node, which only contains block header data such as the previous block’s hash and a timestamp rather than the block data in its entirety. They make on-demand requests to Full Nodes and only validate certain pieces of state as required by their users. Example uses are to check balances, verify if a transaction was confirmed, check event logs, and do other light-duty tasks. Light Nodes can be easily run by lower-capacity devices such as a mobile phone or RaspberryPi.</p>
<h3 id="heading-archive-node">Archive Node</h3>
<p>An Archive Node is a type of Full Node that is running in “archive mode”. They contain all the same data as a Full Node but also all the historical state data of the entire blockchain since <a target="_blank" href="https://etherscan.io/block/0">Genesis Block</a>. We’ll focus on archive nodes for the remainder of this article.</p>
<h2 id="heading-more-on-archive-nodes">More on Archive Nodes</h2>
<p>Although Full Nodes can rebuild historical blockchain state data, this process is <a target="_blank" href="https://geth.ethereum.org/docs/dapp/tracing">slow and inefficient</a>. Depending on the use case, this data may need to be served up quickly. This is where Archive Nodes come in. Because Archive Nodes contain historical data from the very first block, they can easily trace any arbitrary transaction at any time.</p>
<h3 id="heading-why-access-an-archive-node">Why Access an Archive Node?</h3>
<p>If there is information you need to get from the Ethereum Blockchain before the most recent 128 blocks, the most efficient way to get this is through an Archive Node. Some of this information may include account balances, smart contract code, transaction counts, or the value at a particular storage position. They also enable the testing of smart contract code without creating a transaction on the blockchain.</p>
<h3 id="heading-specs-to-run-an-archive-node">Specs to Run an Archive Node</h3>
<p>Running your own node means having more control of the information you share with the blockchain. You can create more secure and private dApps (decentralized apps), and your addresses and balances won’t leak to random nodes on the network. Running an Archive Node also means quick access to historical blockchain data without signing up for any third-party services.</p>
<p>These are the specifications you would need to be able to <a target="_blank" href="https://ethereum.org/en/run-a-node/">run your own Ethereum Archive Node</a>:</p>
<ul>
<li>A CPU with at least four cores</li>
<li>16 GB or more of RAM</li>
<li>An SSD drive with at least 6 TB of space</li>
<li>At least 25 MBit/s bandwidth</li>
</ul>
<p>As you can see, the requirements to spin up an Archive Node make it reasonably accessible. Not exactly cheap, but still within reach to an individual. It does require some technical know-how and constant upkeep though. If you don’t have the time, drive, or equipment to run your own, a Node Provider is a great alternative.</p>
<h3 id="heading-archive-node-providers">Archive Node Providers</h3>
<p>Node Providers make it simple for anyone to access and interact with the Ethereum Blockchain through their easy-to-use APIs. All you need to do is create a new project and then easily call <a target="_blank" href="https://www.wallarm.com/what/what-is-json-rpc">JSON RPC methods</a> with the URL they provide.</p>
<h4 id="heading-infura">Infura</h4>
<p>Infura is arguably the most popular Node Provider in the space. It was created by ConsenSys, the team behind MetaMask and the Truffle blockchain development framework. They’ve been around for a while, and their services are great for beginners and organizations looking to scale.  </p>
<ul>
<li>Now has free Archive Node Access</li>
<li>Great <a target="_blank" href="https://infura.io/pricing">free pricing tier</a></li>
<li>Offers access to Layer 2 scaling solutions</li>
<li>Many other add-ons to fit your needs</li>
<li>Excellent <a target="_blank" href="https://docs.infura.io/infura">documentation</a></li>
</ul>
<h3 id="heading-use-cases">Use Cases</h3>
<p>Depending on the type of project you are building, there are several different technologies you could connect to a Node Provider. </p>
<h4 id="heading-truffle-hardhat">Truffle / Hardhat</h4>
<p>If you are writing smart contracts that interact with historical data, then a development suite such as Truffle or Hardhat would fit your needs. They both have an assortment of built-in tools that make the entire development lifecycle for your dApp much easier. Connecting to an Archive Node, in this case, is as easy as setting your provided API URL endpoint as a variable to be used in your frontend code.</p>
<h4 id="heading-ganache">Ganache</h4>
<p>If you need quick access to an Archive Node for local development or testing, Truffle offers a personal blockchain that accomplishes this nicely. This blockchain is called <a target="_blank" href="https://trufflesuite.com/docs/ganache/index.html">Ganache</a>. As of <a target="_blank" href="https://blog.infura.io/fork-ethereum-replay-historical-transactions-with-ganache-7-archive-support/">Ganache version 7.0</a>, spinning up a local instance of the Ethereum blockchain with Archive access is as simple as one command: </p>
<pre><code class="lang-bash">ganache --fork
</code></pre>
<p>You could then interact with it similarly as above, using the URL: <code>http://localhost:8545</code>, or whatever you set the port to.</p>
<h4 id="heading-direct-integration">Direct Integration</h4>
<p>If you don’t require a suite of blockchain tools, then you can use your Node Provider URL directly in your frontend code and connect to it with a JavaScript library such as ethers.js or web3.js. This is the option we will explore in the project below.</p>
<h2 id="heading-the-project">The Project</h2>
<p>As mentioned at the start of this article, we will be making a simple “Year in Review” type app to display some wallet statistics from 2021. We will clone a pre-built frontend, so all we have to worry about is querying an archive node and then displaying the data nicely.</p>
<h4 id="heading-what-we-will-learn">What we will learn:</h4>
<ul>
<li>How to get an Infura API URL with archive access</li>
<li>How to gather archive data using an Infura API URL and web3.js</li>
<li>The JavaScript required to collect the data from the blockchain</li>
<li>How to put the data together to display it nicely in the app</li>
</ul>
<h4 id="heading-what-is-needed-to-complete-the-project">What is needed to complete the project:</h4>
<ul>
<li><a target="_blank" href="https://infura.io/">An Infura account</a></li>
<li><a target="_blank" href="https://git-scm.com/downloads">Git</a></li>
<li><a target="_blank" href="https://nodejs.org/en/">Node / npm</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/">A code editor</a></li>
</ul>
<h4 id="heading-additional-resources">Additional resources</h4>
<ul>
<li><a target="_blank" href="https://docs.infura.io/infura">Infura docs</a></li>
<li><a target="_blank" href="https://web3js.readthedocs.io/en/v1.7.0/web3.html">Web3.js docs</a></li>
</ul>
<h3 id="heading-the-infura-api-url">The Infura API URL</h3>
<p>The first step in our project is to set up our Infura account and acquire our API Endpoint URL. Head to https://infura.io/ and either create a new account or log in.</p>
<p>Create a new project to get the API Endpoint URL we will need later in our project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653934864152/jo7aeAjbt.jpg" alt="The Infura project dashboard where we get the RPC endpoint URL" class="image--center mx-auto" /></p>
<p>Since archive access is now free for all users, we don’t need to complete any other steps with our Infura account.</p>
<p>With that out of the way, let’s start working on the frontend!</p>
<h3 id="heading-the-frontend">The Frontend</h3>
<p>We will be building on top of a pre-made React frontend for the rest of this project. If you’ve never used React before, that’s okay. We will be walking through the rest of the steps together. </p>
<p>To install the project properly, we will use <strong>git</strong> and <strong>node package manager</strong> (npm). To see if they are already installed, we can check the version numbers in the command line:</p>
<pre><code class="lang-bash">npm --version
</code></pre>
<pre><code class="lang-bash">git --version
</code></pre>
<p>If they still need to be installed on your machine, you can get them at the following links:</p>
<ul>
<li>Node / npm: <a target="_blank" href="https://nodejs.org/en/">https://nodejs.org/en/</a></li>
<li>Git: <a target="_blank" href="https://git-scm.com/downloads">https://git-scm.com/downloads</a></li>
</ul>
<p>Once installed, we are ready to start working on the rest of the project:</p>
<ol>
<li><p>In the command line, navigate to the folder you would like to work out of and clone the repository for our project:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/paul-mcaviney/archive-node-project-frontend.git
</code></pre>
</li>
<li><p>Change directories into the new project folder and install the required dependencies:
cd archive-node-project-frontend</p>
<pre><code class="lang-bash">npm i
</code></pre>
</li>
<li><p>After the dependencies finish installing, let’s run the project to make sure it’s working correctly so far:</p>
<pre><code class="lang-bash">npm start
</code></pre>
<p>If everything is installed correctly, we will now have a frontend running on <code>http://localhost:3000</code> that looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653935017102/Wll8hPJjR.jpg" alt="The frontend for our React project. A user inputs an Ethereum wallet address to receive statistics from 2021" class="image--center mx-auto" /></p>
<p>There’s a text field we will use to enter a wallet address. Clicking the Submit button takes us to our results page. We can also return to the input page from here by pressing the Enter New Address button.</p>
</li>
<li><p>Before we start coding, we need to install one more dependency. We will be using web3.js to access an Archive Node with our Infura URL. To install web3.js, type the following command in the directory for our project:</p>
<pre><code class="lang-bash">npm install web3
</code></pre>
</li>
<li><p>We will do all of our coding in the <code>App.js</code> file under the <code>src</code> folder. The first bit of code we need to write is to import web3 to our project and connect it to our Infura URL. Under the import statements, and before the App function, add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Web3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'web3'</span>); 
<span class="hljs-keyword">const</span> infuraURL = <span class="hljs-string">'YOUR_INFURA_URL_HERE'</span>; 
<span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(<span class="hljs-keyword">new</span> Web3.providers.HttpProvider(infuraURL));
</code></pre>
<p><strong>Note</strong>: Do not upload this project to a public repository without first hiding your actual Infura URL. You can use environment variables for this.</p>
</li>
<li><p>We’ll be using the <code>useState</code> React hook to update our UI. You’ll notice it’s already imported at the top of our file. Next, let’s add some React state variables to make it easier to display the data we gather from our Archive Node. Under the results state variable, add the following:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [address, setAddress] = useState(<span class="hljs-string">''</span>); 
<span class="hljs-keyword">const</span> [currentBalance, setCurrentBalance] = useState(<span class="hljs-number">0</span>); 
<span class="hljs-keyword">const</span> [startOfYearBalance, setStartOfYearBalance] = useState(<span class="hljs-number">0</span>); 
<span class="hljs-keyword">const</span> [endOfYearBalance, setEndOfYearBalance] = useState(<span class="hljs-number">0</span>); 
<span class="hljs-keyword">const</span> [balanceDifference, setBalanceDifference] = useState(<span class="hljs-number">0</span>); 
<span class="hljs-keyword">const</span> [transactionCount, setTransactionCount] = useState(<span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p>Now we need to update the <code>handleInput</code> function to assign the user input to our address state variable instead of logging the comment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleInput = <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {     
  setAddress(event.target.value); 
};
</code></pre>
<p><strong>Note</strong>: You’ll notice we didn’t put any checks here to make sure what the user inputs is actually an Ethereum wallet address. This is for the sake of keeping this tutorial simple. You will want to handle this differently if deploying publicly.</p>
</li>
<li><p>The last bit of JavaScript is an asynchronous function that will gather the data from the Archive Node, convert it to more readable values, and set our state variables. Under the comment that says <em>Your JavaScript code will go here</em>, type the following code:</p>
<pre><code class="lang-Javascript"><span class="hljs-comment">// Access and process data from Ethereum blockchain</span>
<span class="hljs-keyword">const</span> accessEthereum = <span class="hljs-keyword">async</span> () =&gt; {

  <span class="hljs-comment">// 2021 Start and End Block variables </span>
  <span class="hljs-keyword">const</span> START_2021_BLOCK = <span class="hljs-number">11565019</span>;
  <span class="hljs-keyword">const</span> END_2021_BLOCK = <span class="hljs-number">13916165</span>;

  <span class="hljs-comment">// Get current balance of address </span>
  <span class="hljs-keyword">const</span> balance = <span class="hljs-keyword">await</span> web3.eth.getBalance(address);

  <span class="hljs-comment">// Convert balance from wei to ETH and set state variable</span>
  setCurrentBalance(<span class="hljs-keyword">await</span> web3.utils.fromWei(balance.toString(), <span class="hljs-string">'ether'</span>));

  <span class="hljs-comment">// Get wallet balance at the start of 2021 (Block #11565019)</span>
  <span class="hljs-keyword">const</span> startBalance = <span class="hljs-keyword">await</span> web3.eth.getBalance(address, START_2021_BLOCK);

  <span class="hljs-comment">// Get wallet balance at the end of 2021 (Block #13916165)</span>
  <span class="hljs-keyword">const</span> endBalance = <span class="hljs-keyword">await</span> web3.eth.getBalance(address, END_2021_BLOCK);

  <span class="hljs-comment">// Convert startBalance to ETH and set state variable</span>
  <span class="hljs-keyword">const</span> startBalanceAsETH = <span class="hljs-keyword">await</span> web3.utils.fromWei(startBalance.toString(), <span class="hljs-string">'ether'</span>);
  setStartOfYearBalance(startBalanceAsETH);

  <span class="hljs-comment">// Convert endBalance to ETH and set state variable</span>
  <span class="hljs-keyword">const</span> endBalanceAsETH = <span class="hljs-keyword">await</span> web3.utils.fromWei(endBalance.toString(), <span class="hljs-string">'ether'</span>);
  setEndOfYearBalance(endBalanceAsETH);

  <span class="hljs-comment">// Set balanceDifference from start to end of 2021</span>
  setBalanceDifference(endBalanceAsETH - startBalanceAsETH);

  <span class="hljs-comment">// Get transaction count at start of 2021 (Block #11565019)</span>
  <span class="hljs-keyword">let</span> startTransactions = <span class="hljs-keyword">await</span> web3.eth.getTransactionCount(address, START_2021_BLOCK);

  <span class="hljs-comment">// Get transaction count at end of 2021 (Block #13916165)</span>
  <span class="hljs-keyword">let</span> endTransactions = <span class="hljs-keyword">await</span> web3.eth.getTransactionCount(address, END_2021_BLOCK);

  <span class="hljs-comment">// Set total transaction count in 2021</span>
  setTransactionCount(endTransactions - startTransactions);

  <span class="hljs-comment">// Received results, condition met to show them on screen</span>
  setResults(<span class="hljs-literal">true</span>);    

};
</code></pre>
</li>
<li><p>Moving on to the HTML, the first thing we need to do is replace the button function with the new one we just wrote. Change the function call for the button under the <em>Change this button function</em> comment:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{accessEthereum}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'form-button'</span> <span class="hljs-attr">type</span>=<span class="hljs-string">'submit'</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'submit'</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'submit'</span>&gt;</span>
</code></pre>
</li>
<li><p>The final bit of code we need is the HTML that will display the data we gathered from our Archive Node. In the return statement, scroll down to the comment that says <em>Your HTML code will go here</em> and add the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>{address}<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'result-heading'</span>&gt;</span>Current Balance<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{currentBalance} ETH<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'result-heading'</span>&gt;</span>Start of 2021 Balance<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{startOfYearBalance} ETH<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'result-heading'</span>&gt;</span>End of 2021 Balance<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{endOfYearBalance} ETH<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'result-heading'</span>&gt;</span>Difference from Start of 2021<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{balanceDifference} ETH<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'result-heading'</span>&gt;</span>Number of transactions in 2021<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{transactionCount}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
</code></pre>
<p>To see the complete project code, check out <a target="_blank" href="https://github.com/paul-mcaviney/archive-node-project-complete">this Github repository</a>.</p>
</li>
<li><p>Now let’s test out our app and see if it works! First, start the app:</p>
<pre><code class="lang-bash">npm start
</code></pre>
<p>Enter an Ethereum wallet address to the text field and hit <strong>Submit</strong>. If you don’t have a wallet address that was active in 2021, you can use Vitalik’s.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653935901369/IVXnHTr79.jpg" alt="The results from querying an archive node for wallet stats for 2021" /></p>
<p>Awesome! Our results are displayed correctly, and we can see all the activity of the wallet address in 2021!</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>By following this tutorial, you accessed the data on an Archive Node using your Infura API Endpoint URL, then displayed it nicely in a simple ETH Year in Review app.</p>
<p>An Archive Node is required to access data from the Ethereum Blockchain prior to the most recent 128 blocks. They store all historical state data from the very first block and serve it up much more quickly and efficiently than a Full Node. Now that Infura offers free Archive Node access to all users, gathering historical blockchain data has never been easier!</p>
]]></content:encoded></item><item><title><![CDATA[How to Mint an NFT on Polygon]]></title><description><![CDATA[Introduction
Non-Fungible Tokens (NFTs) have exploded in popularity over the last year. And with NFTs being used for art, PFPs, lifestyle brands, sports, games, the metaverse, and more, they won’t be going away anytime soon. But the current state of ...]]></description><link>https://blog.paulmcaviney.ca/how-to-mint-an-nft-on-polygon</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/how-to-mint-an-nft-on-polygon</guid><category><![CDATA[Web3]]></category><category><![CDATA[Polygon]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[NFT]]></category><category><![CDATA[THW Web3]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Tue, 10 May 2022 22:17:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1652208918453/9Cp6BApUZ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Non-Fungible Tokens (NFTs) have exploded in popularity over the last year. And with NFTs being used for <a target="_blank" href="https://opensea.io/">art</a>, <a target="_blank" href="https://boredapeyachtclub.com/">PFPs</a>, lifestyle brands, sports, games, <a target="_blank" href="https://pages.consensys.net/nfts-the-metaverse-ready-for-take-off">the metaverse</a>, and more, they won’t be going away anytime soon. But the current state of NFTs has a few problems - notably, minting on Ethereum can be prohibitively expensive and the metadata behind those NFTs is often centralized.  </p>
<p>In this article, we’ll look at one way to solve those issues by creating and deploying an NFT to the Polygon Network and using IPFS to store the metadata. In our example, we’ll use Truffle as our development environment and Infura to connect and interact with the blockchain and IPFS. </p>
<h3 id="heading-a-quick-overview-of-nfts">A Quick Overview of NFTs</h3>
<p><strong>Fungible </strong> tokens are cryptographic tokens that can be exchanged for any other of the same token (1 == 1). These include cryptocurrencies such as Bitcoin (BTC) or ETH. One Bitcoin is exactly the same as any other Bitcoin.</p>
<p>In contrast, <a target="_blank" href="https://consensys.net/knowledge-base/a-blockchain-glossary-for-beginners/#NFT">NFTs</a> are <strong>not</strong> fungible - one token is <strong>not</strong> replaceable by another, and they may have varying values (1 != 1). An NFT is an undisputable representation of digital ownership. It can be used to represent any manner of digital property such as images, videos, music, and so much more. </p>
<h3 id="heading-nfts-on-ethereum-and-layer-two">NFTs on Ethereum and Layer Two</h3>
<p>Most NFTs are created on the <a target="_blank" href="https://ethereum.org/en/">Ethereum Network</a>, as it allows for the greatest sense of security and decentralization. However, for the average person, there is a major issue: Transacting on Layer 1 of the Ethereum Network is expensive. </p>
<p>Over the course of 2021, several solutions to this problem have gained popularity. Layer 2 solutions such as <a target="_blank" href="https://arbitrum.io/">Arbitrum</a>, <a target="_blank" href="https://zksync.io/userdocs/">zkSync</a>, and the <a target="_blank" href="https://polygon.technology/">Polygon Network</a> are here to provide a more user-friendly experience. Transaction fees on these networks are a fraction of what they would be on Layer 1, and in most cases, significantly faster.</p>
<p>Another current problem with NFTs is that the metadata they contain isn’t always stored in a decentralized manner. If the organization hosting the metadata disappears, so does the value of your NFT. The best solution is to host the metadata using a global, peer-to-peer file system such as <a target="_blank" href="https://ipfs.io/">InterPlanetary File Storage</a> (IPFS).</p>
<p>Combining technologies such as Polygon and IPFS creates a cost-effective method to deploy and store your NFT in a more decentralized and permanent way. Although we could use no-code services such as those provided by <a target="_blank" href="https://consensys.net/solutions/nft-experiences/">ConsenSys</a>, it’s more fun to actually deploy one yourself and you will get a better understanding of how it all works behind the scenes. </p>
<p>So let’s look at how you can create and deploy an NFT to the Polygon Network. We will use Truffle as our development environment and Infura to connect and interact with the blockchain, and to store the metadata with IPFS. </p>
<p>Before deploying, we will test on a local instance of a blockchain with Ganache. When it’s ready to go live, we will deploy to the Polygon Mumbai Test Network and will verify the NFT on OpenSea, the world’s most popular NFT platform.</p>
<h2 id="heading-the-project">The Project</h2>
<h3 id="heading-what-you-will-learn">What You Will Learn</h3>
<ul>
<li>Upload the NFT image and metadata to IPFS via Infura</li>
<li>Set up the Polygon Network in MetaMask and get test funds</li>
<li>Set up Truffle Development Environment</li>
<li>Write an NFT smart contract</li>
<li>Test deployment locally using Ganache</li>
<li>Deploy to Polygon testnet using Truffle console and Infura</li>
<li>Verify the NFT on opensea.io</li>
</ul>
<h3 id="heading-what-you-will-need">What You Will Need</h3>
<ul>
<li><a target="_blank" href="https://docs.npmjs.com/cli/v8/configuring-npm/install">NodeJS / NPM</a> - installation and package management</li>
<li><a target="_blank" href="https://trufflesuite.com/docs/truffle/getting-started/installation/">Truffle</a> - development environment</li>
<li><a target="_blank" href="https://trufflesuite.com/docs/ganache/quickstart/">Ganache</a> - local blockchain instance for testing</li>
<li><a target="_blank" href="https://infura.io/">Infura account</a> - used to interact with IPFS and Polygon Networks</li>
<li><a target="_blank" href="https://metamask.io/">MetaMask account</a> - supply funds to process transactions</li>
</ul>
<h3 id="heading-additional-resources">Additional Resources</h3>
<ul>
<li><a target="_blank" href="https://docs.polygon.technology/docs/develop/getting-started">Polygon Docs</a></li>
<li><a target="_blank" href="https://trufflesuite.com/docs/truffle/">Truffle Docs</a></li>
<li><a target="_blank" href="https://infura.io/docs/ethereum">Infura Docs</a></li>
<li><a target="_blank" href="https://docs.metamask.io/guide/">MetaMask Docs</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652210087502/xvI5swuPO.jpg" alt="An image saying &quot;let's build it!&quot; with a nice light blue background and silhouette of a construction site with cranes holding the logos for Truffle, Polygon, and Infura" /></p>
<h2 id="heading-setting-up-accounts">Setting Up Accounts</h2>
<p>Before we get to the fun parts like building and testing, let’s set up our accounts and get everything in place. This will ensure the rest of the process goes smoothly.</p>
<h3 id="heading-get-an-infura-account">Get an Infura Account</h3>
<p>Infura is an Ethereum node provider and API. It will allow us to easily connect to the Polygon Network and also provides an easy-to-use method for utilizing IPFS.</p>
<p>The first thing we need to do is head to <a target="_blank" href="https://infura.io/register">infura.io</a> and set up a free account. After verifying our email address, we can access the dashboard, where we can make new projects. The Polygon Network isn’t enabled by default, however.</p>
<p>We can add Polygon to our plan by selecting the “Add-Ons” tab on the left-hand side of the screen and scrolling down to “Network Add-Ons”. Next, we select “Polygon PoS Add-On” and go through the prompt to add it. </p>
<p>Now we’re ready to create a new project. Let’s head back to the dashboard and click on the “Create New Project” button. We’ll select Ethereum as the product and name our project <strong>Polygon-NFT</strong>.</p>
<p>Once our project is created, there are several things to note:</p>
<ul>
<li>The Project ID</li>
<li>The project secret</li>
<li>Endpoints selection</li>
<li>Our endpoint link</li>
</ul>
<p>Let’s change our Endpoint from <strong>MAINNET</strong> to <strong>POLYGON MUMBAI</strong>, which is the Polygon testnet. Our Endpoint link will then change. We will need the values on this page later, but for now, we are done with the project page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652210329034/0IxGkOHoz.png" alt="A view of our Infura project, with the endpoint switched from mainnet to polygon mumbai" /></p>
<h3 id="heading-ipfs-via-infura">IPFS via Infura</h3>
<p>Since we are already in our Infura account, let’s go ahead and create another project. This one will be for utilizing IPFS to store the image and metadata of our NFT. This time when we create a new project, we will select IPFS as the product. Let’s name this one <strong>Polygon-NFT-Metadata</strong>.</p>
<p>For the next steps we will need the Project ID, project secret, and endpoint URL, but first, we need an image for our NFT.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652209221640/HFE9ZVWrH.jpg" alt="The image to be used for our Polygon NFT -- It's dark navy blue with the words &quot;My Amazing&quot; in cursive at the top, the Polygon logo in purple, and the words &quot;Polygon NFT&quot; in purple pixely text underneath the logo." /></p>
<blockquote>
<p>Just right-click and save this to your machine ;)</p>
</blockquote>
<p>Feel free to use your own image moving forward. OpenSea recommends the image size to be 350 x 350 pixels.</p>
<p>Now let’s upload the image to IPFS!</p>
<p>Using a command terminal, we will <code>cd</code> into the folder where our image is stored.
To upload the image, type the following command:</p>
<pre><code>curl <span class="hljs-operator">-</span>X POST <span class="hljs-operator">-</span>F file<span class="hljs-operator">=</span>@myfile \ <span class="hljs-operator">-</span>u <span class="hljs-string">"PROJECT_ID:PROJECT_SECRET"</span> \ <span class="hljs-string">"https://ipfs.infura.io:5001/api/v0/add"</span>
</code></pre><p><strong>Note</strong>:</p>
<ul>
<li><code>@myfile</code> should be the name of the image file in the current folder. So in our case <code>@polygon-nft.jpg</code>.</li>
<li><code>PROJECT_ID</code> and <code>PROJECT_SECRET</code> will be the keys provided in the settings for our Infura project.</li>
</ul>
<p>The output from the command should look something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652214797674/k67jg7i7T.png" alt="The console readout after uploading an image to IPFS via the command line" /></p>
<p>The most important part of the output will be our “Hash”. We can actually verify the image was uploaded successfully by pasting that Hash into the following URL: <code>https://ipfs.io/ipfs/YOUR_HASH_HERE</code></p>
<p>It’s important to note that Infura pins our data to IPFS by default. If we ever want to remove an item from IPFS we have to <a target="_blank" href="https://infura.io/docs/ipfs#section/Getting-Started/Unpin-a-file">unpin it</a>. Now that our image is stored on IPFS, let’s get the metadata stored there as well. According to <a target="_blank" href="https://docs.opensea.io/docs/metadata-standards">standards by OpenSea</a>, we will want our metadata in JSON format like so:</p>
<pre><code class="lang-json">{ 
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"My Sweet Polygon NFT"</span>,     
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Our amazing NFT deployed to the Polygon Network"</span>,     
  <span class="hljs-attr">"image"</span>: <span class="hljs-string">"ipfs://YOUR_HASH_HERE"</span> 
}
</code></pre>
<p>So let’s create a new text file in the same folder on our local machine as our NFT image. We can use any text editor for this; it doesn’t need to be anything fancy.</p>
<p>We’ll add the metadata in the same format as above. However, rather than using <code>YOUR_HASH_HERE</code> we’ll insert the actual Hash for our image that we just verified. We’ll save the file as <code>nft-metadata.json</code>. We also need to make sure there is no comma after the last item in our JSON file. If there is a comma, then OpenSea will not display the NFT properly. </p>
<p>Now we can add this file to IPFS using the same command as last time; we just need to replace the file name with <code>@nft-metadata.json</code>.</p>
<p>Excellent! We now have our metadata pinned to IPFS which has a link that points to our already pinned image. We’ll copy the Hash in the output to use later.</p>
<h3 id="heading-setting-up-metamask">Setting Up MetaMask</h3>
<p>In order to interact with the Polygon Network and to pay any transaction fees, we will need to set up a Web3 wallet. We will use MetaMask to do this. It is installed as a browser extension and allows us to connect to Decentralized Apps (dApps). </p>
<p>Let’s head over to <a target="_blank" href="https://metamask.io/">metamask.io</a> and download the extension for our browser. When using a crypto wallet like MetaMask, it’s a good idea to understand <a target="_blank" href="https://metamask.zendesk.com/hc/en-us/articles/360015489591-Basic-Safety-and-Security-Tips-for-Metamask">wallet safety</a>. </p>
<p><strong>Remember</strong>: Never share your seed phrase with <strong>anyone</strong>! Whoever has your seed phrase can withdraw your tokens.</p>
<p>We will need to use the 12-word seed phrase when setting up our Truffle project. So be sure to write that down and save it for later. Once we install MetaMask and open it to the dashboard, we need to add Polygon to our Networks dropdown.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652215041652/oB7knWrQQ.png" alt="Where to click to add new networks to metamask" /></p>
<p>When we click the dropdown, it reveals a button to add new networks to the list. So we’ll press the “Add Network” button, and <a target="_blank" href="https://docs.polygon.technology/docs/develop/metamask/config-polygon-on-metamask/">add both the Polygon Mainnet and Mumbai Testnet</a>. </p>
<p>We will need to enter in the following information:</p>
<p><strong>Mumbai Testnet</strong></p>
<blockquote>
<p>Network Name: Mumbai (Polygon Testnet)</p>
<p>New RPC URL: https://rpc-mumbai.maticvigil.com/</p>
<p>Chain ID: 80001</p>
<p>Currency Symbol: MATIC</p>
<p>Block Explorer URL: https://mumbai.polygonscan.com/</p>
</blockquote>
<p><strong>Polygon Mainnet</strong></p>
<blockquote>
<p>Network Name: Polygon Mainnet</p>
<p>New RPC URL: https://polygon-rpc.com/</p>
<p>Chain ID: 137</p>
<p>Currency Symbol: MATIC</p>
<p>Block Explorer URL: https://polygonscan.com/</p>
</blockquote>
<p>Now we have the Polygon Network added to our MetaMask, but if we switch to the Mumbai Testnet, there’s no MATIC! Let’s change that. We’ll need to copy our wallet address, which is listed under the name of our Account. It starts with 0x…</p>
<p>Next, we’ll head over to <a target="_blank" href="https://faucet.polygon.technology/">https://faucet.polygon.technology/</a> which is a faucet that provides test funds for development. We need to select the Mumbai Network and then paste our address into the text field. Once we hit “Submit” we should see some MATIC tokens in our MetaMask wallet after a minute or two.</p>
<p><strong>Note</strong>: If you have multiple accounts in your MetaMask wallet, Truffle uses the first one by default. So be sure to add the test MATIC tokens to the first account in your list.</p>
<p>Now that we have loaded our wallet with some test tokens, we are ready to move on.</p>
<h3 id="heading-install-truffle-and-ganache">Install Truffle and Ganache</h3>
<h4 id="heading-truffle">Truffle</h4>
<p>Truffle is a development environment that provides tools to make building on the blockchain much easier. In order to install it via the command line, we will need NodeJS v8.9.4 or later and Node Package Manager (npm). If it’s not already installed, <a target="_blank" href="https://nodejs.dev/learn/how-to-install-nodejs">check out this link</a>.</p>
<p>Once it’s installed on our machine, we can install Truffle using this command in the terminal:</p>
<pre><code><span class="hljs-built_in">npm</span> install -g truffle
</code></pre><p>We can type the command <code>truffle version</code> afterward to ensure it was installed correctly. If there are any errors, be sure to add the npm modules to your path.</p>
<h4 id="heading-ganache">Ganache</h4>
<p>Next we’ll install Ganache, a local blockchain instance used for testing before deploying to the Mumbai Testnet.</p>
<p>Ganache has a GUI version that can be downloaded <a target="_blank" href="https://trufflesuite.com/ganache/">here</a>, but we will use the terminal version for the rest of this tutorial. It can be installed using this command:</p>
<pre><code><span class="hljs-built_in">npm</span> install ganache --<span class="hljs-built_in">global</span>
</code></pre><p>Again, we can verify proper installation by checking the version: <code>ganache --version</code></p>
<h2 id="heading-setting-up-our-project">Setting Up Our Project</h2>
<p>Now that our accounts are set up and everything is installed properly, let’s start putting it all together. The first step is to navigate in our terminal to where we want to create our project and make a new directory.</p>
<pre><code>mkdir polygon<span class="hljs-operator">-</span>nft<span class="hljs-operator">-</span>project <span class="hljs-operator">&amp;</span><span class="hljs-operator">&amp;</span> cd polygon<span class="hljs-operator">-</span>nft<span class="hljs-operator">-</span>project
</code></pre><p>One incredibly useful thing about Truffle is they offer a full suite of “<a target="_blank" href="https://trufflesuite.com/ganache/">boxes</a>” for getting started quickly. They are essentially boilerplates that include helpful modules, pre-made smart contracts, frontend views, and more. For this project, we will utilize <a target="_blank" href="https://trufflesuite.com/ganache/">Truffle’s Polygon Box</a>. Installation is simple; we just need to type this command:</p>
<pre><code>truffle unbox <span class="hljs-type">polygon</span>
</code></pre><p>After installation, we can see there are several new files in our project folder. The most important ones we will be working with are the <code>README.md</code> file, <code>truffle-config.polygon.js</code>, the <code>1_deploy_simple_storage.js</code> under the <code>migrations</code> folder, and <code>SimpleStorage.sol</code> files, which can be found in the ‘contracts` folder. </p>
<p>You will likely see an <code>ethereum</code> and <code>polygon</code> folder under <code>contracts</code>. This is because typically when a project is deployed to Polygon, it should also be deployed to Ethereum so users can easily bridge their assets back and forth. We can delete the <code>SimpleStorage.sol</code> contracts since we won’t be using them.  </p>
<p>Taking a quick glance through the <code>README.md</code> file, we can see that in order to deploy to the Polygon Network, we will have to add two things:</p>
<ol>
<li>The Mnemonic phrase (seed phrase) of the wallet we are using</li>
<li>The Infura Project ID</li>
</ol>
<p>We’ll want to store these in a <code>.env</code> file and make sure it’s added to our <code>.gitignore</code> so we don’t accidentally upload these secrets if storing our project on a public repository. </p>
<p>Downloading the Polygon Truffle Box also installed the <code>.dotenv</code> package for us. All we need to do is create a <code>.env</code> file in our root folder. </p>
<p>The mnemonic phrase for our wallet can be found in our MetaMask settings under the “Security &amp; Privacy” heading. The Project ID can be found under the “Keys” heading in our Infura project settings. Our <code>.env</code> file will look something like this:</p>
<pre><code><span class="hljs-attr">MNEMONIC</span>=<span class="hljs-string">"your twelve words here ..."</span>`
<span class="hljs-attr">INFURA_PROJECT_ID</span>=<span class="hljs-string">"project ID # here"</span>
</code></pre><p>The next thing we should do is update Truffle to use the latest version of Solidity. In our <code>truffle-config.polygon.js</code> file, we can add the compiler version we wish to use.</p>
<p>Under the <code>compilers</code> section, within the <code>solc</code> curly braces, we’ll add the following: <code>version: “0.8.11”</code> (the latest version of Solidity at the time of this writing).</p>
<p>It should look like this:</p>
<pre><code><span class="hljs-comment">// Configure your compilers</span>
<span class="hljs-attribute">compilers</span>: {
    <span class="hljs-attribute">solc</span>: {
        <span class="hljs-attribute">version</span>: <span class="hljs-string">"^0.8.11"</span>
    }
},
</code></pre><p><strong>Note</strong>: If you didn’t delete the <code>SimpleStorage.sol</code> contracts, then you will need to update their Solidity version in order to compile properly. Simply change the pragma line to the following: <code>pragma solidity &gt;=0.4.21 &lt;0.9.0;</code> </p>
<p>The last bit of prep work is just to install the <a target="_blank" href="https://docs.openzeppelin.com/contracts/4.x/">OpenZeppelin contract library</a>, as we will import several contracts. We can install it by typing this command in the root directory of our project:</p>
<pre><code><span class="hljs-built_in">npm</span> install @openzeppelin/contracts
</code></pre><p>We are utilizing the OpenZeppelin library to make writing our smart contract easier and much safer. The contracts we will use have had thorough security audits and it ensures we are adhering to the industry standard for NFTs.</p>
<p>With our project set up properly, we are ready to get to the best part… Creating the NFT!</p>
<h2 id="heading-the-smart-contract">The Smart Contract</h2>
<p>We will open up our preferred code editor from our project root folder. (I’m using vscode so the command is <code>code .</code>.) Create a new file under the <code>contracts</code> folder named <code>PolygonNFT.sol</code>.</p>
<p><strong>Note</strong>: If you need to brush up on the Solidity coding language, check out my <a target="_blank" href="https://blog.paulmcaviney.ca/series/solidity-basics">Solidity Basics Series</a>.</p>
<p>We’ll be using the following smart contract for our NFT:</p>
<pre><code class="lang-js"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.11</span>;

<span class="hljs-comment">// Import the OpenZeppelin contracts</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/ERC721.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/utils/Counters.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;

<span class="hljs-comment">// Declare our contract and inherit from the OpenZeppelin ERC721 and Ownable contracts </span>
contract PolygonNFT is ERC721, Ownable {
    <span class="hljs-comment">// Helpers for counting safely and converting data to strings</span>
    using Counters <span class="hljs-keyword">for</span> Counters.Counter;
    using Strings <span class="hljs-keyword">for</span> uint256;

    <span class="hljs-comment">// State variable for storing the current token Id</span>
    Counters.Counter private _tokenIds;
    <span class="hljs-comment">// Map token Ids to token URI</span>
    mapping (<span class="hljs-function"><span class="hljs-params">uint256</span> =&gt;</span> string) private _tokenURIs;

    <span class="hljs-comment">// ERC721 requires a name for the NFT collection and a symbol</span>
    <span class="hljs-keyword">constructor</span>() ERC721("PolygonNFT", "PNFT") {}

    <span class="hljs-comment">// Set the URI (metadata) for tokenId</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_setTokenURI</span>(<span class="hljs-params">uint256 tokenId, string memory _tokenURI</span>)
        <span class="hljs-title">internal</span>
        <span class="hljs-title">virtual</span>
    </span>{
        _tokenURIs[tokenId] = _tokenURI;
    }

    <span class="hljs-comment">// Return the Token URI - Required for viewing properly on OpenSea</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenURI</span>(<span class="hljs-params">uint256 tokenId</span>)
        <span class="hljs-title">public</span>
        <span class="hljs-title">view</span>
        <span class="hljs-title">virtual</span>
        <span class="hljs-title">override</span>
        <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>)
    </span>{
        <span class="hljs-built_in">require</span>(_exists(tokenId), <span class="hljs-string">"Token does not exist"</span>);
        string memory _tokenURI = _tokenURIs[tokenId];

        <span class="hljs-keyword">return</span> _tokenURI;
    }

    <span class="hljs-comment">// Mint the NFT to the provided address, using the provided metadata URI </span>
    <span class="hljs-comment">// Only the wallet address that deployed this contract can call this function</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mint</span>(<span class="hljs-params">address recipient, string memory uri</span>)
        <span class="hljs-title">public</span>
        <span class="hljs-title">onlyOwner</span>
        <span class="hljs-title">returns</span> (<span class="hljs-params">uint256</span>)
    </span>{
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();

        _mint(recipient, newItemId);
        _setTokenURI(newItemId, uri);

        <span class="hljs-keyword">return</span> newItemId;
    }
}
</code></pre>
<p>Pretty short, right?! That’s the beautiful thing about the composability of Web3. OpenZeppelin is doing most of the heavy lifting here with their ERC721 standard.</p>
<p>Basically, we are simply defining the NFT collection and symbol, supplying the NFT metadata via the <code>_setTokenURI()</code> function, putting it together with our <code>mint()</code> function, and then providing a way for OpenSea or anyone else to retrieve the NFT metadata through our <code>tokenURI()</code> function.</p>
<h2 id="heading-testing-deployment-with-ganache">Testing Deployment With Ganache</h2>
<p>Deploying to the blockchain is pretty simple, but before we can do that, we need to modify the <code>1_deploy_simple_storage.js</code> file under the <code>migrations</code> folder. We just need to replace every instance of <code>SimpleStorage</code> with whatever we named our NFT smart contract. In our case: <code>PolygonNFT</code>. We should also rename the file to <code>1_deploy_polygon_nft.js</code> to eliminate any confusion. </p>
<p>Our migration file should now look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PolygonNFT = artifacts.require(<span class="hljs-string">"PolygonNFT"</span>); 

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">deployer</span>) </span>{ 
    deployer.deploy(PolygonNFT); 
};
</code></pre>
<p>Before deploying our project to a live blockchain, it is common practice to test it on a local blockchain instance. We will use Ganache to do this. In a new terminal window, we will use this command to get it up and running:</p>
<pre><code>ganache
</code></pre><p>The terminal should output some Available Accounts, their Private Keys, and so on.</p>
<p>To deploy our project to Ganache, open up the original terminal window. In the root directory of our project, type the command:</p>
<pre><code>truffle migrate <span class="hljs-operator">-</span><span class="hljs-operator">-</span>config<span class="hljs-operator">=</span>truffle<span class="hljs-operator">-</span>config.polygon.js <span class="hljs-operator">-</span><span class="hljs-operator">-</span>network<span class="hljs-operator">=</span>development
</code></pre><p>Since there are two config files in our project, we need to specify which one to use. Truffle will use the <code>truffle-config.js</code> file by default. After hitting enter, we can see that Truffle compiles our contracts and then starts the migration. If all goes successfully, you will receive a transaction receipt that will look something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652216222772/BjQeY9QTq.png" alt="the transaction receipt returned in the command line after a successful migration" /></p>
<blockquote>
<p>Take note of the contract address</p>
</blockquote>
<p>Now that our contract has migrated successfully to our local blockchain instance, we can use the <a target="_blank" href="https://trufflesuite.com/docs/truffle/getting-started/interacting-with-your-contracts.html">Truffle Console</a> to interact with it. The Truffle Console is a powerful tool that allows us to use JavaScript to interact directly with our contract without having to set up a frontend. To use it, type the command:</p>
<pre><code>truffle console <span class="hljs-operator">-</span><span class="hljs-operator">-</span>config<span class="hljs-operator">=</span>truffle<span class="hljs-operator">-</span>config.polygon.js <span class="hljs-operator">-</span><span class="hljs-operator">-</span>network<span class="hljs-operator">=</span>development
</code></pre><p>Notice how the command prompt changes to <code>truffle(development)&gt;</code>. We are now ready to start interacting with our smart contract. </p>
<p>First, we need to get an instance of our contract. Copy the contract address from our transaction receipt to be used in this line of code:</p>
<pre><code>let instance <span class="hljs-operator">=</span> await PolygonNFT.at(<span class="hljs-string">"YOUR_CONTRACT_ADDRESS_HERE"</span>)
</code></pre><p>It will return undefined but if we type <code>instance</code> it should output our contract ABI. Now we can call the mint function. We will need a contract address in which to send the NFT and our IPFS URI from earlier in the format: ipfs://YOUR_HASH_HERE</p>
<pre><code>await instance.mint(<span class="hljs-string">"YOUR_WALLET_ADDRESS"</span>, <span class="hljs-string">"YOUR_METADATA_URI"</span>)
</code></pre><p>It’s important to note that the mint function is being called by the address that deployed the contract because that is the one we logged into the Truffle Console with by default. The address we placed in the code above is the recipient of the NFT.</p>
<p>If all went well with our code above, we shouldn’t see any errors after we hit enter! We now know our contract works and we are able to mint an NFT from it. Unfortunately, since this is a local blockchain instance, we don’t have OpenSea or PolygonScan to verify that our 
NFT actually exists. For that, we will deploy to the Mumbai Testnet.</p>
<h2 id="heading-deploy-to-polygon-testnet">Deploy to Polygon Testnet</h2>
<p>The process to deploy to the Mumbai Testnet is very similar to launching on our Ganache blockchain instance. We just need to exit the Truffle console by typing <code>ctrl+c</code> twice and then follow the exact same steps as above. The only difference is we will replace the network= <code>development</code> with <code>polygon_infura_testnet</code>. </p>
<p>Before moving forward, we need to make sure our Mnemonic phrase and Project ID are set up properly in our <code>.env</code> file otherwise, the next steps won’t work. (See the steps in the Setting Up Our Project section.) With those in place, our commands will now look like this:</p>
<pre><code>truffle migrate <span class="hljs-operator">-</span><span class="hljs-operator">-</span>config<span class="hljs-operator">=</span>truffle<span class="hljs-operator">-</span>config.polygon.js <span class="hljs-operator">-</span><span class="hljs-operator">-</span>network<span class="hljs-operator">=</span>polygon_infura_testnet
</code></pre><p>The migration will take a little bit longer than our Ganache instance. Once it’s complete it will output a transaction receipt that looks similar to our last one. This time we can verify that our contract was successfully migrated to the Mumbai Testnet by entering our contract address to <a target="_blank" href="https://mumbai.polygonscan.com/address/">https://mumbai.polygonscan.com/address/YOUR_ADDRESS_HERE</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652216623850/dkLVM0tRq.png" alt="what the transaction looks like on Polygonscan" /></p>
<p>Excellent! Our contract is live on the Mumbai Testnet! Now let’s interact with it and actually mint our NFT!</p>
<p>We’ll access the Truffle Console using the same commands as before, again, replacing the network= <code>development</code> with <code>polygon_infura_testnet</code>.</p>
<pre><code>truffle console <span class="hljs-operator">-</span><span class="hljs-operator">-</span>config<span class="hljs-operator">=</span>truffle<span class="hljs-operator">-</span>config<span class="hljs-operator">-</span>polygon.js <span class="hljs-operator">-</span><span class="hljs-operator">-</span>network<span class="hljs-operator">=</span>polygon_infura_testnet
</code></pre><p>Get an instance of our contract using the contract address that was output on our Mumbai Testnet transaction receipt:</p>
<pre><code>let instance <span class="hljs-operator">=</span> await PolygonNFT.at(<span class="hljs-string">"YOUR_CONTRACT_ADDRESS_HERE"</span>)
</code></pre><p>And now, for the moment we’ve been building towards this entire article! Mint our NFT to our desired address using our IPFS URI in the format: <code>ipfs://YOUR_HASH_HERE</code></p>
<pre><code>await instance.mint(<span class="hljs-string">"YOUR_WALLET_ADDRESS"</span>, <span class="hljs-string">"YOUR_METADATA_URI"</span>)
</code></pre><p>If there aren't any errors, we can check our contract on mumbai.polygonscan again and see that our <code>mint()</code> function was called! This time, we can verify that our NFT actually exists by checking it out on OpenSea.</p>
<h2 id="heading-verify-our-nft-on-opensea">Verify Our NFT On OpenSea</h2>
<p>We can easily check out our new NFT on OpenSea by copying our contract address into the search bar at https://testnets.opensea.io/. Ethereum addresses have two versions, one that is checksummed and one that is not. The difference being the non-checksummed version is all lowercase. We may need to use the non-checksummed version to find our NFT on OpenSea. We can get this address by clicking on the Txn Hash on mumbai.polygonscan and then copying the address across from <code>Interacted With (To):</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652216849864/honheRkru.png" alt="The highlighted address" /></p>
<blockquote>
<p>Your contract address will be different</p>
</blockquote>
<p>If our metadata was entered correctly we should now see our beautiful, new NFT live on OpenSea!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652216884400/hM1FYVu_X.png" alt="our beautiful new NFT as seen on OpenSea" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You have successfully deployed an NFT to the Polygon Mumbai Testnet! You uploaded your NFT image and metadata to IPFS using Infura’s API, set up your Truffle project and wrote a smart contract to create an NFT, tested deployment locally using Ganache, deployed to the Polygon Testnet with Truffle, Infura, and MetaMask, and finally, verified your NFT on OpenSea.</p>
<p>You now have the knowledge to deploy to the Polygon Mainnet, just make sure you have real MATIC tokens in your MetaMask wallet. Additionally, when deploying, be sure to use network=<code>polygon_infura_mainnet</code> instead of <code>polygon_infura_testnet</code>. </p>
<p>Your next steps would be to deploy to the Ethereum Mainnet to be able to bridge your NFT from Layer 2 to Layer 1. That is the topic for another article so be sure to check out the <a target="_blank" href="https://docs.polygon.technology/docs/develop/ethereum-polygon/getting-started">Polygon Docs</a> in the meantime.</p>
<p>Thank you for following along with this tutorial! Take care, and happy building!</p>
<blockquote>
<p>(The code for this project can be found here: <a target="_blank" href="https://github.com/paul-mcaviney/polygon-nft-project">https://github.com/paul-mcaviney/polygon-nft-project</a>)</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[My Experience Joining Developer DAO]]></title><description><![CDATA[Every once in a while, something comes along that completely changes the trajectory of your career. That thing for me was joining Developer DAO. 
I'm Paulie from the Newsletter Team, and this is my story.
A Bit About Me
In 2021, I was having difficul...]]></description><link>https://blog.paulmcaviney.ca/paulies-experience</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/paulies-experience</guid><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Wed, 23 Mar 2022 21:35:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1648070368502/Z0_p54Pd-.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every once in a while, something comes along that completely changes the trajectory of your career. That thing for me was joining Developer DAO. </p>
<p>I'm Paulie from the Newsletter Team, and this is my story.</p>
<h2 id="heading-a-bit-about-me">A Bit About Me</h2>
<p>In 2021, I was having difficulty wanting to be at my job. Being an overhead crane technician and working away from home on shiftwork for seven years was starting to get old, and it was time for a change. Tech has always been a field I’ve been interested in. I love computers and building cool shit. </p>
<p>I’ve been dabbling in different technologies since 2017, from web dev to Python to game development with Unity and C#. But I've been a computer nerd pretty much my whole life.</p>
<p>I figured around the beginning of 2021, why not give web development an actual shot? So I started down the <a target="_blank" href="https://www.freecodecamp.org/">freeCodeCamp</a> path, learning frontend, and building websites. </p>
<p>I got a couple cool sites up and running and was in the process of starting a freelance hustle when I began hearing a lot of buzz on <a target="_blank" href="https://twitter.com/paul_can_code">Twitter</a> about Web3. Of course, I had to at least look into it. I’m not one to dismiss something just because people say it’s all hype.</p>
<p>After I dug into Ethereum and realized just how valuable this tech could be in the future, I had to give it a try. Right around that time, I stumbled across some DAOs, but none really clicked with me.</p>
<p>Then I read <a target="_blank" href="https://twitter.com/dabit3">Nader Dabit</a>’s tweet:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/dabit3/status/1433879106119208966?t=J5p4IdsWbavzPk75gv52yA&amp;s=19">https://twitter.com/dabit3/status/1433879106119208966?t=J5p4IdsWbavzPk75gv52yA&amp;s=19</a></div>
<p>I knew this was something I needed to get involved with. Unfortunately, I wasn’t entirely confident in my building skillz yet. But what better place to learn than a group of Web3 developers and enthusiasts?! So I minted my first-ever NFT and joined Developer DAO.</p>
<h2 id="heading-overwhelmed-but-optimistic">Overwhelmed but Optimistic</h2>
<p>I soon discovered just how fast the web3 space moves. So much was happening in the DAO, it was hard to know where to focus or spend my time. It was obvious right off the bat though, that this is where I should be. </p>
<p>I could see a lot of enthusiasm across the entire DAO and so many talented people! The only thing was, I felt I wasn’t good enough to contribute. How could I? With so many people building things beyond my skill level, I would just make a fool of myself.</p>
<p>So I kept quiet, posting things once in a while that I came across on Twitter and participating in a few conversations here and there. However, I was still able to learn a lot even without contributing. People posted excellent links to learning resources and ideas flowed like crazy! I started the <a target="_blank" href="https://blog.developerdao.com/the-100daysofweb3-challenge">#100DaysOfWeb3 Challenge</a> on Twitter and picked up the idea to start writing about what I’ve been learning. So, of course, <a target="_blank" href="https://blog.paulmcaviney.ca/">I started my own blog</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647986536069/DNnwkQO0H.jpg" alt="D4R NFT plus Pixel Dev" />
Holders of the Devs4Revolution NFT can now <a target="_blank" href="https://pixel-devs.developerdao.com/">mint their own Pixel Dev</a>!</p>


<h2 id="heading-paulie-the-writer">Paulie the Writer?!</h2>
<p>I never actually saw myself as a writer before. But, through writing down my learnings, I’ve kind of taken a liking to it! It has helped me articulate my thoughts and solidify the concepts I learn. If I know a topic well enough to write it down in my own words, I’d say it has firmly lodged itself in my brain. I have returned to my own writing a few times to review things I get stuck on.</p>
<p>On top of all that, it helps other people! There have been multiple people reaching out saying I’ve helped them in one way or another, even inspiring others to start their own blogs! Man, that is a great feeling! 😁 </p>
<p>Not to mention the opportunities that come along with proving you can do something. Your writing becomes your marketing. If people see that you can help with their problem, they are more likely to reach out! The demand for technical writers in the Web3 space is huge right now!</p>
<p>But I digress. Let’s get back to my journey with D_D.</p>
<h2 id="heading-back-to-the-dao">Back to the DAO</h2>
<p>Writing blog posts gave me something original to share with the DAO. My content would then get boosted by the <a target="_blank" href="https://twitter.com/developer_dao">D_D Twitter account</a>, helping me reach more people and acquire new followers with every post.</p>
<p>However, it still felt like I wasn’t doing much in the DAO. I was attending Town Halls and voting on <a target="_blank" href="https://snapshot.org/#/devdao.eth">snapshots</a>, but still searching for a way to get more involved. </p>
<p>Then Season 0 started, and guilds became a thing.</p>
<p>With specific guilds to cover different topics in the DAO, it was easier to narrow my focus. I was immediately drawn to the Writers Guild due to my interest in becoming a better writer. If you are interested in doing something, surround yourself with people already doing that thing, right? </p>
<p>The Writers Guild has been there to provide assistance when I feel stuck. There’s also a channel for requesting feedback on your written content.</p>
<h2 id="heading-finally-a-way-to-contribute">Finally A Way to Contribute</h2>
<p>Towards the end of November 2021, the Writers Guild announced they would create a newsletter for the DAO. Guild leader <a target="_blank" href="https://twitter.com/wolovim">marc | wolovim.eth</a> made a post calling for someone to help curate the highlights for the guilds, and right away, I thought this was something I might be able to do. Finally! A way I can contribute! </p>
<p>The only thing was... I was incredibly nervous to reply 😅</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647987028497/YLmqMGB8d.jpg" alt="Marc-call-for-volunteer-smaller.jpg" /></p>
<p>I thought about it for hours, deliberating whether I should or not. I eventually convinced myself to give it a shot. What’s the worst that could happen? If I feel overwhelmed, I could just take a step back, and someone else could pick up that task. That’s how DAOs work, isn’t it? </p>
<p>My reasoning was that I thought it would be an excellent opportunity to keep track of everything going on in Developer DAO. I was already browsing a lot of the channels. So why not write some of it down and share it with the rest of the DAO?!</p>
<p>So I replied to Marc saying I was interested, and he gave me an outline of what they were looking for. I managed to scrape together <a target="_blank" href="https://developerdao.substack.com/p/probably-nothing-0?s=w">something that was acceptable</a> and haven’t looked back since!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647987133205/-bfbYfGaL.jpg" alt="Marc-call-for-volunteer-2-smaller.jpg" /></p>
<h2 id="heading-confidence-through-contribution">Confidence Through Contribution</h2>
<p>Joining the newsletter team allowed me to narrow my focus. I was looking too broadly before, not knowing where to spend my energy. Now I have specific duties to get done weekly. </p>
<p>It has also made me more comfortable communicating in the DAO. Carrying out newsletter duties broke some of the hesitancy I once felt. I have no problem speaking up when others need help or if there’s a discussion I want to get involved with. </p>
<p>My willingness to help and activity didn’t go unnoticed either! Marc asked if I would like to be a moderator, to which I replied, “Of course!”.</p>
<p>With everything I’ve been helping out with, my confidence has been growing by the day. I really feel like I’m contributing to something great and that I’m actually able to make a difference by helping people in the DAO. </p>
<p>I’ve also tried to be more active on Twitter, helping out there when I see opportunities. Tons of people have questions about D_D!</p>
<h2 id="heading-learn-from-my-example">Learn From My Example</h2>
<p>Taking the leap and getting more involved is scary! You might feel like you don’t have anything to contribute, but trust me, you do! Developer DAO is a big place with a lot going on. <a target="_blank" href="https://blog.developerdao.com/how-to-deal-with-the-developer-dao-discord">Join channels on topics that interest you, and ignore the rest</a>.</p>
<p>You can get a broad overview of what’s going on by subscribing to our <a target="_blank" href="https://developerdao.substack.com/">newsletter</a>. Once you start participating in conversations, opportunities for involvement will present themselves. Being friendly and helping others when you can goes a long way.</p>
<p>When you start working on a project or two, you could write about it also! The newsletter and <a target="_blank" href="https://blog.developerdao.com/">DAO blog</a> are always looking for more writers. So let us know what you’ve been working on! It could help others get involved too.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>I’ve been writing for a couple months now and gained a few great clients, but I’m happy to announce my next big venture...</p>
<p>As of April 4th, 2022, I will be assuming the role of Director of Web3 Content at Dev Spotlight! They have been my best client, and when my contact offered me a position with them, there was no way I could refuse! </p>
<p>So long overhead crane technician, I’m going Web3 full-time baby!</p>
<p>Taking the leap and joining the newsletter team has taught me the benefit of getting out of my comfort zone. Being a part of Developer DAO has shown me the path I want to follow, and I’ve never felt closer to achieving my goals. I’ve also met some really great people along the way.</p>
<p>So if you are still hesitant about getting more involved, just know it’s not as scary as you think! Take the chance and get out of your comfort zone. It could be the best decision you ever make 😉</p>
]]></content:encoded></item><item><title><![CDATA[The #100DaysOfWeb3 Challenge]]></title><description><![CDATA[About The Challenge
In this challenge, you are tasked with learning something Web3 everyday for 100 days. You should publicly announce somewhere, perhaps on Twitter, that you are attempting the challenge. Ideally, you will also post your progress oft...]]></description><link>https://blog.paulmcaviney.ca/100daysofweb3-invite</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/100daysofweb3-invite</guid><category><![CDATA[Web3]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Solana]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Mon, 14 Feb 2022 00:27:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1644462870386/dRtJqBuGR.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-about-the-challenge">About The Challenge</h2>
<p>In this challenge, you are tasked with learning something Web3 everyday for 100 days. You should publicly announce somewhere, perhaps on Twitter, that you are attempting the challenge. Ideally, you will also post your progress often. Anything from the things you are learning, to how you are feeling about the challenge, or even just thoughts related to Web3. Just remember to use the tag #100DaysOfWeb3 somewhere in your post.</p>
<p>It is very similar to the #100DaysOfCoding challenge that has been popular on tech Twitter for many years. The goal is to build a habit and keep your learning consistent and accountable. You can use it to jump start your transition into the Web3 space, or just use it to build a healthy habit of learning.</p>
<h2 id="heading-what-is-web3">What Is Web3?</h2>
<p>Web3 is the decentralized version of the internet, aiming to return power back into the hands of everyday people, rather than the corporate megacorporations pervading the space today. </p>
<p>It heavily incorporates blockchain technology, so typically that is what people focus on when attempting the challenge. You may also cover other Web3 topics such as decentralized governance, DAOs (Decentralized Autonomous Organizations), Web3 gaming and micro-economies, or any number of other Web3 topics.</p>
<h2 id="heading-why-the-challenge">Why The Challenge?</h2>
<p>If you struggle with learning something and sticking with it, it’s not necessarily about what you’re learning but more about your consistency. This challenge is to help you build a habit of logging on to your computer every day and dedicating some time towards learning a new skill. Regardless of what you want the outcome to be. Just showing up is the most important step.</p>
<p>Learning in public is a great way to hold yourself accountable and meet like-minded people. If you are posting your progress on Twitter, others can follow the hashtag which opens it up to the entire community. Posting often will also hopefully ease any anxiety you might have about putting yourself out there by giving you something straightforward to share every day. </p>
<h2 id="heading-how-to-get-started">How To Get Started</h2>
<p>The first thing you should do before starting the challenge is figure out why you want to do it. Having a “why” in place will help you on the hard days when you aren’t feeling particularly motivated or things are feeling too challenging. </p>
<p>Your second step should be to create a Twitter account. Twitter is where almost everyone in the Web3 space hangs out so building your profile is an important step. Join the community and say hi! Some people like myself monitor the #100DaysOfWeb3 tag to say hello and offer encouragement to people on the journey. You could also do the challenge on Facebook or LinkedIn but the response will not be as impactful there.</p>
<p>Third, figure out where you want to start! I’ve got some resources listed below that should help you figure that out if you haven’t already. </p>
<p>Finally, just post your progress on Twitter from time to time. Most people post every day because it helps establish a habit of writing and putting yourself out there, but you absolutely do not have to if you don’t want to. This is your challenge! Do what works best for you! Just remember to add the number of day you are on and the #100DaysOfWeb3 tag.</p>
<p>ex: Day 33 / #100DaysOfWeb3</p>
<h2 id="heading-how-to-succeed">How To Succeed</h2>
<p>This challenge is tough and not everybody will make it to the end. 100 days is a long time! Don’t be hard on yourself if you have to step back. Just know there is a whole community of us rooting for you to cross that finish line! Armed with the right attitude and some help from the community, you will be able to make it! With that in mind, here are a few tips to help you out: </p>
<ul>
<li><strong>Ease into it</strong> — Going too hard right out of the gate will set your expectations too high for the rest of the challenge. There’s no need for any extra pressure.</li>
<li><strong>Take breaks</strong> — The risk of burnout in this challenge is real. If you need a day or two off here and there, that’s totally fine. We have lives outside of this challenge.</li>
<li><strong>Try not to compare yourself to other people</strong> — This is the trap of social media and is a recipe for discouragement. Everyone’s skill level and learning capabilities are different.</li>
<li><strong>Pick something and stick with it</strong> — Bouncing around from topic to topic without finishing something makes learning more difficult. There are some exceptions here but ideally you should finish that tutorial/project/whatever before starting a new one.</li>
<li><strong>Join a community</strong> — Surrounding yourself with like-minded people helps A LOT. You’ll meet some cool new friends and it provides a support group you can fall back on. It may even open up opportunities for you ;)</li>
<li><strong>Write about what you’re learning</strong> — This will help solidify concepts and could help other people on the same path as you. So start your blog (I recommend <a target="_blank" href="https://hashnode.com/">Hashnode</a>) and put yourself out there!</li>
</ul>
<h2 id="heading-resources">Resources</h2>
<p>Now that you know what the challenge is, here are a few resources to get you started:</p>
<h3 id="heading-general-blockchain-and-crypto">General Blockchain and Crypto</h3>
<ul>
<li>Whiteboard Crypto - <a target="_blank" href="https://www.youtube.com/channel/UCsYYksPHiGqXHPoHI-fm5sg">https://www.youtube.com/channel/UCsYYksPHiGqXHPoHI-fm5sg</a></li>
<li>Bitcoin Whitepaper - <a target="_blank" href="https://bitcoin.org/en/bitcoin-paper">https://bitcoin.org/en/bitcoin-paper</a></li>
<li>The Ethereum Network - <a target="_blank" href="https://ethereum.org/en/">https://ethereum.org/</a></li>
</ul>
<h3 id="heading-smart-contract-dapp-decentralized-app-development">Smart Contract / Dapp (Decentralized App) Development</h3>
<ul>
<li><a target="_blank" href="http://LearnWeb3.io">LearnWeb3</a> - <a target="_blank" href="https://www.learnweb3.io/">https://www.learnweb3.io/</a></li>
<li>Get Started With Ethereum Development - <a target="_blank" href="https://ethereum.org/en/developers/">https://ethereum.org/en/developers/</a></li>
<li>Get started with Solana Development - <a target="_blank" href="https://solana.com/news/getting-started-with-solana-development">https://solana.com/news/getting-started-with-solana-development</a></li>
<li>Crypto Zombies - <a target="_blank" href="https://cryptozombies.io/">https://cryptozombies.io/</a></li>
<li>Buildspace 🦄 - <a target="_blank" href="https://buildspace.so/">https://buildspace.so/</a></li>
<li>SpeedRunEthereum - <a target="_blank" href="https://speedrunethereum.com/">https://speedrunethereum.com/</a></li>
<li>16hr Solidity, Blockchain, and Smart Contract Course - <a target="_blank" href="https://www.youtube.com/watch?v=M576WGiDBdQ">https://www.youtube.com/watch?v=M576WGiDBdQ</a></li>
</ul>
<h3 id="heading-front-end-development">Front-End Development</h3>
<ul>
<li>freeCodeCamp - <a target="_blank" href="https://www.freecodecamp.org/">https://www.freecodecamp.org/</a></li>
<li>Traversy Media - <a target="_blank" href="https://www.youtube.com/c/TraversyMedia">https://www.youtube.com/c/TraversyMedia</a></li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>There you have it! You are now armed and ready to start the 100DaysOfWeb3 challenge! Remember, take your time, take breaks, and have fun. This isn’t a competition, so be easy on yourself! Drop a comment below to let me know you’re starting, or you can tag me directly on Twitter <code>@paul_can_code</code> on Day 1 of your challenge. Good luck friend!</p>
]]></content:encoded></item><item><title><![CDATA[What The Heck Is An Airdrop?]]></title><description><![CDATA[Introduction
There’s no doubt, 2021 was an excellent year for Web3 users. If you were browsing crypto Twitter over the holidays, you may have noticed a lot of people talking about an SOS airdrop. Maybe you were one of the lucky ones to actually quali...]]></description><link>https://blog.paulmcaviney.ca/airdrops</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/airdrops</guid><category><![CDATA[Web3]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Mon, 03 Jan 2022 23:52:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1641169474119/Q6f8r7u7hx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>There’s no doubt, 2021 was an excellent year for Web3 users. If you were browsing crypto Twitter over the holidays, you may have noticed a lot of people talking about an <a target="_blank" href="https://nftnewspro.com/what-is-sos-token-airdrop-and-how-to-claim/">SOS airdrop</a>. Maybe you were one of the lucky ones to actually qualify for it? If you are curious about what all the fuss is about, this article is for you! We will go over what exactly an airdrop is, what they are used for, and how you might be able to qualify for one yourself. So strap on your parachutes, let’s jump into it!</p>
<h2 id="heading-so-what-the-heck-is-an-airdrop-anyway">So What The Heck Is An Airdrop Anyway?</h2>
<p>Web3 is full of innovative new technology and people are getting rewarded for being early adopters. Since most of these applications require you to connect your crypto wallet in order to interact with them, it is easy to find out who the users are and compensate them for embracing the tech before anyone else. This reward, usually unannounced, is called an airdrop. It refers to the old WW2 term where food and supplies were dropped by plane to soldiers on the battlefield or dropping supplies in the same manner to victims of a natural disaster. </p>
<p>If you suddenly notice an additional amount of tokens or a fancy new NFT in your crypto wallet and have no idea where they came from, you may have just received an airdrop. Unsolicited airdrops aren’t the only way to receive them, though. </p>
<p>The most common way airdrops are received is through a claiming process. A project might make an announcement that some of its users qualify for a reward based on certain criteria. In the case of the SOS token, people were rewarded as a result of how much they spent on the <a target="_blank" href="https://opensea.io/">OpensSea NFT Marketplace</a>. The recipients were then able to go to <a target="_blank" href="https://www.theopendao.com/">https://www.theopendao.com/</a> and initiate a claim. Some people reported being able to claim up to $500 000 literally for just using the platform.</p>
<p></p><blockquote><p>I’m going to give $30,000 to someone who retweets this tweet because it’s the end of the year and <a href="https://twitter.com/search?q=%24SOS&amp;src=ctag&amp;ref_src=twsrc%5Etfw">$SOS</a> gave me half a million dollar 🆘️! (must be following me so I can dm you if you win). ofc Will show proof! <a href="https://t.co/TJDc5YrU87">pic.twitter.com/TJDc5YrU87</a></p>— Perry Saylor (@PerrySaylor_000) <a href="https://twitter.com/PerrySaylor_000/status/1475073692161871875?ref_src=twsrc%5Etfw">December 26, 2021</a></blockquote> <p></p>
<p>The crazy part? It wasn’t even OpenSea that initiated the airdrop. The unrelated organization OpenDAO took it upon themselves to reward NFT enthusiasts, most likely as a marketing scheme.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641244024075/GQ0mkZ_5i.jpeg" alt="Handout(resized).jpg" /></p>
<p>Airdrops can also be self-initiated. A platform might clearly state that it is handing out a reward for completing certain tasks, such as signing up for a newsletter or finishing a <a target="_blank" href="https://buildspace.so/">coding tutorial</a>. Upon completing the task, the user is compensated for their efforts.</p>
<p>One other notable method of collecting an airdrop is through the <a target="_blank" href="https://www.investopedia.com/terms/h/hard-fork.asp">hardfork of a network</a>, such as when Ethereum split into <a target="_blank" href="https://en.wikipedia.org/wiki/Ethereum_Classic">Ethereum Classic</a> or when Bitcoin split into <a target="_blank" href="https://www.investopedia.com/tech/history-bitcoin-hard-forks/">Bitcoin Cash</a>. To explain a blockchain hardfork simply, it is when one network splits into two different networks. This can happen for various reasons which I won’t get into. All you need to understand is that when it does happen, holders of the token used on the original network receive the same amount of the new token that is used on the forked network.</p>
<p>Airdrops aren’t just for tokens though. It is very common for NFT projects to gift another NFT to the original holders. Bored Ape Yacht Club sent holders a serum NFT which, when combined with their Bored Ape, created an entirely new NFT called a <a target="_blank" href="https://nftevening.com/the-mutant-ape-yacht-club-baycs-mutant-apes-are-a-roaring-success/">Mutant Ape</a>!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641244899985/eLmvDQKqx.jpeg" alt="Ape_complete(resized).jpg" /></p>
<h2 id="heading-what-are-airdrops-used-for">What Are Airdrops Used For?</h2>
<p>One of the main reasons organizations are giving out airdrops to its users is simply to reward them for being the first to interact with their platforms. These early adopters are providing quality user data and feedback in the initial stages of release, as well as potentially spreading the word. What better way to reward these individuals than free stuff!? When people receive free gifts, they usually tend to talk about it, which leads to the second reason an organization might send out an airdrop..</p>
<p>It’s a really great marketing tactic. Almost every time an airdrop has been released it has generated a <a target="_blank" href="https://banklessafrica.com/2021/11/19/airdrop-rumors-result-in-a-swarm-of-activity-on-metamask-swap-and-polygon/">ton of buzz</a> around it. This in turn brings about a lot of brand awareness, which usually leads to more people getting involved. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641247854568/IdkZjJi78.jpeg" alt="graph(resized).jpg" /></p>
<p>Since big platforms such as <a target="_blank" href="https://www.meritline.com/google-ads-new-crypto-policy/">Google</a> and <a target="_blank" href="https://www.facebook.com/policies/ads/restricted_content/cryptocurrency_products_and_services">Facebook</a> have put limits to the types of crypto advertising they allow, these organizations have to find other ways to get the word out about their projects. When something goes viral, everyone wants in on a piece of the action.</p>
<p>Additionally, for newer projects, if they announce they will be doing an airdrop in the future, or even just hint at it, people will be lining up to try out their platform. Considering some people have received airdrops worth thousands of dollars just for being early adopters, the risk to reward ratio is very enticing. </p>
<h2 id="heading-how-do-you-qualify-for-an-airdrop">How Do You Qualify For An Airdrop?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641249631171/_eP2KLMhx.png" alt="wen_token.png" /></p>
<p>Although there usually aren’t many absolute guarantees that an airdrop is on the way, there are a few signs you can look for:</p>
<ul>
<li><strong>If they announce it</strong>: This is obviously the easiest sign to spot. Following Web3 companies on Twitter or subscribing to their newsletters is a surefire way to get notified of an upcoming drop and what you might need to do to qualify.</li>
<li><strong>If an organization is decentralizing</strong>: One of the most common ways for decentralized autonomous organizations (<a target="_blank" href="[https://ethereum.org/en/dao/](https://ethereum.org/en/dao/">DAOs</a>) to facilitate governance is through the use of an ERC-20 token. Who better to do the governing than people actively involved in the project? Start contributing and you could get airdropped some governance tokens. You might also find you enjoy the community, make some friends, and build cool projects along the way!</li>
<li><strong>Prior airdrops</strong>: Based off previous airdrops, it’s a safe bet that users of new protocols and projects could be rewarded for their efforts. Try to go through the actions a platform might want you to take for your highest chance of qualifying. For example: Using the swap feature in your <a target="_blank" href="https://metamask.io/">MetaMask Wallet</a> or trading and minting NFTs with <a target="_blank" href="https://zksync.io/">zkSync</a>.  A lot of people on crypto Twitter are speculating that new Ethereum Layer 2 protocols will be hotspots for incoming airdrops in 2022. This <a target="_blank" href="https://newsletter.banklesshq.com/p/how-to-earn-token-airdrops">Bankless article</a> lists a few potential avenues you could investigate.</li>
</ul>
<h2 id="heading-tread-carefully">Tread Carefully</h2>
<p>With all the hype around airdrops and basically anything else related to cryptocurrency, there are tons of scams out there. Some of them can be <a target="_blank" href="https://www.bsc.news/post/airdrop-scams-minereum-mneb-and-velochain-velo-land-on-binance-smart-chain">quite sophisticated</a> too. If you’re playing around with platforms and trying to get qualified for an airdrop, do some research before aping into it. Brand new projects are popping up every day and some of them undoubtedly have nefarious intentions. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641245201377/2UfqosLcM.jpeg" alt="thief.jpg" /></p>
<p>When first looking at a project, try to find information about the founders. If they are staying anonymous and have no previous reputable work in the public domain, that’s a big red flag. How long has the project been around? What are people saying about it? If the founders are well-established with prior work under their belts, chances are pretty high it’s legit.</p>
<p>Also be very careful when interacting with applications that require the use of your crypto wallet. Know what transactions you are signing and NEVER give anyone your private keys. If you have to enter your private keys to receive an airdrop, it is definitely a scam. If you are still questioning the legitimacy of the airdrop, move anything of value out of your wallet before initiating the claim.</p>
<p>The whole point of an airdrop is to receive something for free. If you are being asked to pay a registration fee or give someone money to be qualified, they are trying to play you. The only fee you might have to pay when claiming an airdrop is the gas fees.</p>
<p>If a large number of folks are receiving an airdrop, try to read into how their experiences are when claiming. Don’t just blindly follow the hype hoping to make a quick buck. Twitter is an excellent source of not only finding out about airdrops, but for reading about how people are reacting to them as well.</p>
<h2 id="heading-good-luck">Good Luck!</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641245775699/xrGUSObdC.jpeg" alt="odds(resized).jpg" /></p>
<p>I hope this article has helped shed some light on airdrops for you. Get involved with Web3 and the potential for rewards can be great. Of course, none of what I’ve posted here should be considered financial advice. <a target="_blank" href="https://youtu.be/wNxUQ2sJtso">Do your own research</a> and be safe out there. </p>
<p>Good luck frens! WAGMI &lt;3</p>
]]></content:encoded></item><item><title><![CDATA[Solidity Basics: Deploy To Ropsten Testnet With Remix]]></title><description><![CDATA[Introduction
If you've written a Solidity smart contract and tested it locally, the next logical step before deploying to mainnet is to try it out on a test network. Since gas fees on mainnet can be quite high, you want to make sure everything is wor...]]></description><link>https://blog.paulmcaviney.ca/deploy-to-ropsten-testnet</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/deploy-to-ropsten-testnet</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Sat, 18 Dec 2021 00:33:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1639769463221/jdLPOPnfx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>If you've written a Solidity smart contract and tested it locally, the next logical step before deploying to mainnet is to try it out on a test network. Since gas fees on mainnet can be quite high, you want to make sure everything is working as intended and optimized in an environment that simulates the real thing before spending your hard earned ETH.</p>
<p>In my <a target="_blank" href="https://blog.paulmcaviney.ca/solidity-interfaces">previous article</a> , we wrote 2 smart contracts and used an interface to test out some interaction between them. In this article, we are going to deploy both of those contracts to the Ropsten testnet and verify functionality there. Arguably, one of the easiest ways to do this is with <a target="_blank" href="https://remix.ethereum.org/">Remix IDE</a>. To do this though, we will need a wallet to hold our test ETH and sign the transactions involved.</p>
<p>If you have your own smart contract you wish to deploy to the Ropsten test network, you can still follow along! We won't be testing the contracts from my previous article until towards the end, so everything else may still be applicable for you.</p>
<hr />
<h3 id="heading-what-you-will-learn">What You Will Learn</h3>
<ul>
<li>What a test network is</li>
<li>How to set up a Metamask Wallet</li>
<li>How to get test Ether from a faucet</li>
<li>How to deploy a smart contract to the Ropsten testnet using Remix</li>
</ul>
<h3 id="heading-what-you-will-need">What You Will Need</h3>
<ul>
<li>A Metamask wallet - <a target="_blank" href="https://metamask.io/">https://metamask.io/</a></li>
<li>Some test Ether in that wallet (We'll go over how to get this)</li>
<li>A smart contract to deploy</li>
</ul>
<h3 id="heading-resources">Resources</h3>
<ul>
<li>MetaMask security tips - <a target="_blank" href="https://metamask.zendesk.com/hc/en-us/articles/360015489591-Basic-Safety-and-Security-Tips-for-Metamask">https://metamask.zendesk.com/hc/en-us/articles/360015489591-Basic-Safety-and-Security-Tips-for-Metamask</a></li>
<li>How To Not Get Rekt: Web3 Wallet Safety - <a target="_blank" href="https://ryanharris.dev/posts/web3-wallet-strategy/">https://ryanharris.dev/posts/web3-wallet-strategy/</a></li>
</ul>
<hr />
<h3 id="heading-what-is-a-test-network">What Is a Test Network?</h3>
<p>If you've been following along with my articles, so far we've only been testing on a devnet. This is a lightweight local instance of the EVM that only exists temporarily. For something that more closely resembles the actual Ethereum Virtual Machine, we'll need to use a testnet.</p>
<p>As mentioned above, a test network is used for trying out smart contracts before deploying them to the Ethereum Mainnet. There are a few different types but all serve the same purpose. Their differences are mainly in how they achieve consensus. Rinkeby, for example, uses the <a target="_blank" href="https://www.coinhouse.com/learn/what-is-proof-of-authority/">proof of authority</a> consensus algorithm, while Ropsten uses <a target="_blank" href="https://www.ledger.com/academy/blockchain/what-is-proof-of-work">proof of work</a>. If you are looking to simulate an environment that is closest to Ethereum Mainnet, you'll want to go with Ropsten since in it's current version, Mainnet is using proof of work.</p>
<p>To participate on these networks you will still need ETH however. There are a couple of ways to acquire some but the easiest is through a web-based service called a faucet. Some networks, like Ropsten, are also built to allow for <a target="_blank" href="https://www.linkedin.com/pulse/how-mine-ropsten-testnet-ether-keir-finlow-bates/">mining</a>, so you could acquire test ETH that way. Aside from these options, you could always ask someone to send you some test ETH directly.</p>
<p>It's also important to note that ETH used on a test network holds no real value. Similar to all currencies, the only reason Mainnet Ether is worth anything is because the community assigns value to it. And because test Ether exists on a separate network, you wouldn't be able to bridge it over to buy your <a target="_blank" href="https://www.cryptokitties.co/">CryptoKitties</a>.</p>
<p>Before we can get any of this test Ether though, we will need a wallet to store it in. For this we will use MetaMask.</p>
<h3 id="heading-how-to-set-up-a-metamask-wallet">How To Set Up A MetaMask Wallet</h3>
<p>Metamask on your PC is set up as a browser extension. It is a digital crypto wallet and you can use it to store ETH and any <a target="_blank" href="https://ethereum.org/en/developers/docs/standards/tokens/erc-20/">ERC20 tokens</a>. Having a wallet like MetaMask installed in your browser allows you to interact with Ethereum dapps.</p>
<p>First thing's first, let's head over to <a target="_blank" href="https://metamask.io/download.html">https://metamask.io/download.html</a>. It should automatically detect which browser you are using and show it as a choice for downloading right at the top but in case it doesn't, the supported browsers are listed just below that. Either way, click on the one that best suits your needs (I am using Chrome) and it will direct you to the install page. Hit the install button to add MetaMask as a browser extension.</p>
<p>Once MetaMask is installed, a new tab should pop up to get you started. If it doesn't, head into your extensions and click on it directly. You should pin it to your taskbar while you're there for easier access moving forward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639785031053/svf9PIdU8F.jpeg" alt="metamask-activate-resized.jpg" /></p>
<p>Okay, once you've clicked on the extension, you should be at the "Get Started" page. If you already have a wallet, this is where you would import it. We are going to create a new wallet though, so click that "Create a Wallet" button and let's proceed. I'll leave it up to you whether you want to agree to anonymous usage data collecting or not.</p>
<p>Next you will be asked to make a password for your wallet. I highly suggest using a password manager - <a target="_blank" href="https://bitwarden.com/">bitwarden</a> is a free, open source one and will help you keep track of your passwords and things you are signed up for. Anyway, create a password and let's move on.</p>
<p>If you've never worked with a crypto currency wallet before, I recommend you watch the short video introduced on the next page. It will explain what a secret recovery phrase is and what it is used for. Your personal phrase will be revealed on the following page. <strong>NEVER SHARE THIS PHRASE WITH ANYONE. PERIOD</strong>. Not even someone at MetaMask. If someone asks you for your secret recovery phrase, they are trying to scam you. Write it down and keep it somewhere safe. See the resources section at the top for additional wallet safety tips.</p>
<p>After you've got your phrase written down somewhere safe, let's proceed to the next page where we are asked to confirm it. Once that's all done, we are finally in our MetaMask wallet!</p>
<p>The first thing we should do is create a new account. I personally like to have a separate account specifically for development stuff, that way I don't send real ETH or accidentally upload the private key for my main account to github. So click on the circle in the top right corner of your screen and let's create a new account. We are going to name this one Dev. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639785163267/MCH36vs63.jpeg" alt="metamask-create-new-account-resized.jpg" /></p>
<p>Awesome! You've now set up your MetaMask wallet and are ready to fill it with some test ETH!</p>
<h3 id="heading-how-to-get-test-eth">How To Get Test ETH</h3>
<p>In order to get some test ETH, we are going to use what is called a faucet. Most faucets are just basic web apps where you input the wallet address you would like to receive test ETH to. We will be using the faucet linked directly from the <a target="_blank" href="https://ethereum.org/en/developers/docs/networks/#testnet-faucets">Ethereum official website</a>. There are other faucets out there, just do some research before using them. Some will ask you to connect your wallet and sign a transaction. Just make sure you know what you are signing before you actually do. For safety's sake, I prefer to use faucets that just require an address.</p>
<p>Let's head over to <a target="_blank" href="https://faucet.ropsten.be/">https://faucet.ropsten.be/</a> and input our wallet address. Click on the MetaMask extension and copy your wallet address.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639786154031/Zvdcgp9GX.jpeg" alt="ropsten-faucet-resized.jpg" /></p>
<p>Paste it into the text field and click the "Send me test Ether" button. It may take a little while to get some ETH transferred to your wallet</p>
<p>If you are unable to get any ETH from the faucet mentioned above, I've had pretty good luck with this one: <a target="_blank" href="https://faucet.dimensions.network/">https://faucet.dimensions.network/</a>.</p>
<p>Once we've got some test Eth for the Ropsten network, we are ready to move on.</p>
<h3 id="heading-accessing-ropsten-from-remix">Accessing Ropsten From Remix</h3>
<p>Using the <a target="_blank" href="https://remix.ethereum.org/">Remix IDE</a>, deploying your smart contracts to a test network is relatively simple. If you've deployed locally with Remix before, the process is much the same. </p>
<p>If you've got your own smart contract you wish to deploy, that's great! If you would like to follow along with the testing we will be doing after deploying, you can use 2 of the smart contracts from my previous articles. The code is posted below. Feel free to deploy them locally and test them out to see how they work.</p>
<p><strong>ChangeState.sol</strong></p>
<pre><code class="lang-jsx"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

contract ChangeState {

    string message;

    <span class="hljs-keyword">constructor</span>() {
        message = <span class="hljs-string">"Hello World!"</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMessage</span>(<span class="hljs-params">string memory newMessage</span>) <span class="hljs-title">public</span> </span>{
        message = newMessage;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> message;
    }
}
</code></pre>
<p><strong>Interact.sol</strong></p>
<pre><code class="lang-jsx"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

interface ChangeState {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMessage</span>(<span class="hljs-params">string memory newMessage</span>) <span class="hljs-title">external</span>;

    <span class="hljs-title">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params"></span>) <span class="hljs-title">external</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>);
}

<span class="hljs-title">contract</span> <span class="hljs-title">Interact</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params">address contractAddress</span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> ChangeState(contractAddress).getMessage();
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeMessage</span>(<span class="hljs-params">address contractAddress, string memory newMessage</span>) <span class="hljs-title">public</span> </span>{
        ChangeState(contractAddress).setMessage(newMessage);
    }
}
</code></pre>
<p>Now that you've got your smart contract ready, head to the <code>Deploy and run transactions</code> tab in Remix. At the very top you'll see the first text field called <code>Environment</code> and it is most likely set on <code>JavaScript VM (London)</code>. </p>
<p>Change this setting to <code>Injected Web3</code> and a MetaMask notification will pop up. It is asking which account you would like to connect to the Remix IDE. Choose your Dev account and press next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639786344490/S0lU4aHJN.jpeg" alt="connect-with-metamask-resized.jpg" /></p>
<p>Once you are connected, Remix will automatically detect which network you are on and will display it under the <code>Injected Web3</code> in the <code>Environment</code> text field. If it doesn't say Ropsten, head into your MetaMask wallet and click on the networks tab. Select Ropsten and now you should be good to go.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639786403935/Ffk-HHa9l.jpeg" alt="change-newtork-resized.jpg" /></p>
<p>Once you you have the Ropsten Network selected, you should see the amount of test ETH you have in your account as well. It will show in your MetaMask wallet, and also in the <code>Account</code> text field in Remix.</p>
<p>Now, the moment we've all been waiting for! Let's deploy our contracts!</p>
<h3 id="heading-deploying-to-the-ropsten-test-network">Deploying To The Ropsten Test Network</h3>
<p>In the <code>Contract</code> selection field, choose the contract you wish to deploy. If you don't see any options there, make sure you saved your contracts and they compiled without any issues. We will do <code>ChangeState.sol</code> first. Select it under the <code>Contract</code> heading and then hit that <code>Deploy</code> button!</p>
<p>MetaMask will immediately pop up with a transaction you can either confirm or reject. It will display important information such as the gas fee and total cost the transaction will be.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639785622463/Jd5wBkYRI.jpeg" alt="confirm-transaction-resized.jpg" /></p>
<p>If everything looks good to you, press <code>Confirm</code>. It will take a couple seconds but another pop up, this time from Chrome itself, will appear saying the transaction was confirmed. You can also view the transaction on <a target="_blank" href="https://ropsten.etherscan.io/">Etherscan</a>. This is proof that our smart contract is now living on the Ropsten Network!</p>
<p>If you weren't able to follow the link in the popup, you can still view the transaction on Etherscan. Just copy the transaction hash from the transaction receipt printed in the console beneath where you write the code in Remix and paste the value in the URL <code>https://ropsten.etherscan.io/tx/)/YOUR_TRANSACTION_HASH_HERE</code></p>
<p>So in my case it would be: <a target="_blank" href="https://ropsten.etherscan.io/tx/0xd2d08ab6071f0e10ef3c17e092ba47c87b3472bda8e13a0429f6cc8bf4ea3124"><code>https://ropsten.etherscan.io/tx/0xd2d08ab6071f0e10ef3c17e092ba47c87b3472bda8e13a0429f6cc8bf4ea3124</code></a></p>
<p>Repeat the process for the <code>Interact.sol</code> contract. Again, the transaction will take a little time because it actually needs to be mined and confirmed on the Ropsten Network, just how it would be with Ethereum Mainnet.</p>
<p>You should now see both contracts under the <code>Deployed Contracts</code> section in Remix. That means they are ready to test!</p>
<h3 id="heading-testing-our-smart-contracts">Testing Our Smart Contracts</h3>
<p>Nothing really changes in regards to the way we test the functions on our contract now that it is on Ropsten. As such, we will be following the same testing procedures as my <a target="_blank" href="https://blog.paulmcaviney.ca/solidity-interfaces">last article</a>.</p>
<ol>
<li>First, let's check that the contract was initialized with the correct value of the <code>message</code> variable. On the <code>ChangeState.sol</code> contract, click the <code>getMessage</code> button and it should return the value <code>Hello World!</code></li>
<li><p>Next we'll make sure the <code>Interact.sol</code> contract is retrieving the correct value from our <code>ChangeState.sol</code> contract. Copy the address for the <code>ChangeState.sol</code> contract and paste it into the <code>getMessage</code> field on the <code>Interact.sol</code> contract. Click the <code>getMessage</code> button and it should also return with a value of <code>Hello World!</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639785734073/APPuA2zU6.jpeg" alt="copy-address-resized.jpg" /></p>
</li>
<li><p>So far so good! Next, we will test out the <code>changeMessage</code> function on the <code>Interact.sol</code> contract. Copy the same address as the previous step into the <code>changeMessage</code> field followed by a comma. After the comma, insert whatever message you want to change it to. </p>
<p> Once you click the button to operate the function, MetaMask should pop up with another transaction to approve or reject. Once it is approved on the Ropsten Network you will be able to view the transaction on etherscan using the same method as above. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639785886512/_f_pH7Jwe.jpeg" alt="successful-change-resized.jpg" />  </p>
</li>
</ol>
<p>Congratulations! You just utilized the Ropsten test network to change the state of another smart contract! Feels pretty cool, doesn't it? For some extra fun, you can enter the address for the contract I uploaded and interact with that one! Be warned though, I don't have any filters set up and won't be actively monitoring the <code>message</code> so it could be anything, even swear words!!!!</p>
<p>Here's the address for my contract: <code>0xa67CD790Bf3A0358155DAE55e2232601D57Fef39</code></p>
<h3 id="heading-finishing-up">Finishing Up</h3>
<p>Thank you for taking the time to read my article! I hope it has helped you with getting a MetaMask wallet set up and deploying contracts on a testnet. Also, if you have followed along with this series from the beginning, congrats! You should now have an understanding of some of the important basic concepts of a Solidity smart contract and are now ready to move on to more complicated things. </p>
]]></content:encoded></item><item><title><![CDATA[Solidity Basics: Interfaces]]></title><description><![CDATA[One of the most promising features of Web3 and the technologies surrounding it is composability. This allows for innovation on top of already existing tech, saving time and making things much more efficient. Open source interoperability is beneficial...]]></description><link>https://blog.paulmcaviney.ca/solidity-interfaces</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/solidity-interfaces</guid><category><![CDATA[Web3]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Ethereum]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Mon, 29 Nov 2021 23:28:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638300450079/Rb0FbwnJLG.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the most promising features of Web3 and the technologies surrounding it is composability. This allows for innovation on top of already existing tech, saving time and making things much more efficient. Open source interoperability is beneficial because a specific problem only needs to be solved once. Other builders can utilize the solution or build upon it at their own discretion in a completely permissionless way.</p>
<p>In this article we will be exploring the concept of composability using interfaces in Solidity smart contracts. Although there are other ways to achieve this, such as inheriting from abstract contracts, interfaces are well suited for simple tasks. We'll interact with the functions of one contract from a completely different contract! If that sounds exciting to you then let's get into it!</p>
<hr />
<h3 id="heading-what-you-will-learn">What You Will Learn</h3>
<ul>
<li>How to use an interface to interact with another smart contract</li>
</ul>
<h3 id="heading-what-you-will-need">What You Will Need</h3>
<ul>
<li>An idea of how functions work in Solidity</li>
<li>Basic familiarity with the online IDE Remix - <a target="_blank" href="https://remix.ethereum.org/">https://remix.ethereum.org/</a></li>
</ul>
<h3 id="heading-resources">Resources</h3>
<ul>
<li>A great article on Composability by Packy McCormick - <a target="_blank" href="https://www.notboring.co/p/idea-legos">https://www.notboring.co/p/idea-legos</a></li>
</ul>
<hr />
<h3 id="heading-lets-get-started">Let's Get Started</h3>
<p>If you followed along with my <a target="_blank" href="https://blog.paulmcaviney.ca/state-variables">last article</a>, you will be able to re-use the smart contract we wrote. We are just going to add a little something for initializing the <code>message</code> variable. </p>
<p>For those of you who didn't read my last article, it's a pretty simple contract. Head over to <a target="_blank" href="https://remix.ethereum.org">https://remix.ethereum.org</a> and write the following code into a new file named <code>ChangeState.sol</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

contract ChangeState {
    string message;

    <span class="hljs-keyword">constructor</span>() {
        message = <span class="hljs-string">"Hello World!"</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMessage</span>(<span class="hljs-params">string memory newMessage</span>) <span class="hljs-title">public</span> </span>{
        message = newMessage;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> message;
    }
}
</code></pre>
<p>What we added to the contract below our declaration of the <code>message</code> state variable and above the declaration of the <code>setMessage</code> function, is called a constructor. It's an optional function that is only executed once when the contract is deployed and is used to initialize contract state. In this case we are initializing our <code>message</code> variable with the value of <code>Hello World!</code>. If there is no constructor defined, a default one will be created behind the scenes upon deployment.</p>
<p>Try deploying the contract and pressing the button for the <code>getMessage</code>function. If you aren't sure how to do this, refer to my <a target="_blank" href="https://blog.paulmcaviney.ca/state-variables">previous article</a>! You'll notice that before we even do anything, the value of our <code>message</code> variable is already <code>Hello World!</code> Sweet!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638055784537/fcGI6XpwQ.png" alt="interfaces-1-smaller.png" /></p>
<p>Now that we've got a working ChangeState contract, let's make a new contract to interact with it!</p>
<h3 id="heading-implementing-the-interface">Implementing The Interface</h3>
<p>We could just create a new contract underneath the ChangeState contract on the same file, but to emphasize that we are actually interacting from a separate contract, let's create a new file.</p>
<ol>
<li>Open up the File Explorers tab and create a new file. We'll name this one <code>Interact.sol</code>. </li>
<li><p>Write the following code in your new contract file:</p>
<pre><code class="lang-jsx"> <span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
 pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

 interface ChangeState {
     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMessage</span>(<span class="hljs-params">string memory newMessage</span>) <span class="hljs-title">external</span>;

     <span class="hljs-title">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params"></span>) <span class="hljs-title">external</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>);
 }

 <span class="hljs-title">contract</span> <span class="hljs-title">Interact</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params">address contractAddress</span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
         <span class="hljs-keyword">return</span> ChangeState(contractAddress).getMessage();
     }

     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeMessage</span>(<span class="hljs-params">address contractAddress, string memory newMessage</span>) <span class="hljs-title">public</span> </span>{
         ChangeState(contractAddress).setMessage(newMessage);
     }  
 }
</code></pre>
<p> Before we declare our contract, we are introducing something called an <code>interface</code>. This is what we will be using to interact with our <code>ChangeState.sol</code> contract and, in this case, what facilitates composability. It is <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.10/style-guide.html?highlight=interface#order-of-layout">best practice</a> to declare interfaces in between pragma statements and contracts.</p>
<p> You'll also notice we have two of the functions from our <code>ChangeState.sol</code> contract in the interface and that both are declared as external. With an interface, we only need to state the functions we want to interact with. The external access modifier is required to convey that the functions will only be called from outside of the interface. More information on interfaces can be found in the <a target="_blank" href="https://docs.soliditylang.org/en/latest/contracts.html?highlight=interfaces#interfaces">Solidity Docs</a>.</p>
<p> Inside our <code>Interact.sol</code> contract, you'll notice that we pass an address argument into both of the functions. This is the address of the smart contract deployed on the blockchain whos functions we wish to use. So in our case, we would deploy our original <code>ChangeState.sol</code> contract, get the address it was deployed to and then pass that as an argument for the functions in our <code>Interact.sol</code> contract.</p>
<p> Then in the lines with <code>ChangeState(contractAddress).{name_of_function}()</code> we are using the functions of our other contract.</p>
<p> Cool! Now that we understand what it's supposed to do, let's test it out locally in Remix and make sure it works!</p>
</li>
</ol>
<hr />
<h3 id="heading-testing-locally">Testing Locally</h3>
<ol>
<li>Let's save our <code>Interact.sol</code> contract and then deploy it. We should now have two contracts deployed, <code>ChangeState.sol</code> and <code>Interact.sol</code>.</li>
<li>First, let's read the value of our <code>message</code> variable in the <code>ChangeState.sol</code> contract. Click on the <code>getMessage</code> button in that contract and it should display <code>Hello World!</code> which is what we initialized that variable to.</li>
<li><p>Next let's grab the value of that same variable but this time from our <code>Interact.sol</code> contract. To do this we will need to get the address that our <code>ChangeState.sol</code> contract was deployed to. Next to the name of the deployed contract, you will see an icon to copy the value to the clipboard. Copy that address and paste it into the text field next to the <code>getMessage</code> function in our Interact contract. Hit the button and it will display the value for us. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638056434001/0JZgKeyeg.png" alt="interfaces-2-smaller.png" /></p>
</li>
<li><p>Let's do a quick test again before we move on. Use the setMessage function in our <code>ChangeState.sol</code> contract to change our message variable to something new. Press the getMessage button from our <code>Interact.sol</code> contract again and you will see that it displays the new value! So cool!</p>
</li>
<li>Now let's test that <code>changeMessage</code> function in our <code>Interact.sol</code> contract! Paste the <code>ChangeState.sol</code> contract address you copied in step 6. into the text field followed by a comma. Then input whatever you want to change the <code>message</code> variable to. Don't worry if you forgot to wrap your text in quotation marks. Remix knows that argument is supposed to be a string so adds them automatically on the backend if you didn't.</li>
<li>Now for the moment of truth! Click on the <code>getMessage</code> button for either contract (or both!) and witness the magic. The <code>message</code> variable's value has been changed from a completely different contract! How cool is that?!</li>
</ol>
<hr />
<h3 id="heading-finishing-up">Finishing Up</h3>
<p>You know what would be even cooler? Deploying these contracts to test network so we can see how it works in an environment that simulates the actual Ethereum Virtual Machine! If that's something that interests you, keep your eyes peeled for my next article or even better, hit that subscribe button!</p>
<p>Thanks for taking the time to read my article. Hopefully you now have a better understanding of how we can implement an interface in one smart contract to use the functions in another. Any questions or comments, feel free to drop them below!</p>
]]></content:encoded></item><item><title><![CDATA[Solidity Basics: State & State Variables]]></title><description><![CDATA[One of the great things about blockchains are their ability to store data in their distributed ledger systems. This is typically done through transactions, and once accepted, they form part of a block and then permanently become part of the blockchai...]]></description><link>https://blog.paulmcaviney.ca/state-variables</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/state-variables</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Web3]]></category><category><![CDATA[coding]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Sat, 06 Nov 2021 00:16:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636157369865/tK5tc3YOW.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the great things about blockchains are their ability to store data in their distributed ledger systems. This is typically done through transactions, and once accepted, they form part of a block and then permanently become part of the blockchain. When the information is part of the blockchain it is immutable, meaning there is a permanent record of that transaction that can never be deleted or modified.</p>
<p>The Ethereum Blockchain however is more advanced than this. It can store blocks of code called smart contracts and through the  <a target="_blank" href="https://ethereum.org/en/developers/docs/evm">Ethereum Virtual Machine</a>  (EVM) can execute the code stored in these contracts. This effectively allows for the modification of the EVM's state from block to block. Due to the immutability aspect, the previous state is still in the records of the blockchain, albeit in the form of hexadecimal hashes instead of human-readable text.</p>
<p>In this article we will write a simple smart contract with a function we can use to change its state. Before we get into coding though, it is important to understand a few concepts around contract state and transactions. </p>
<hr />
<h3 id="heading-what-you-will-learn">What You Will Learn</h3>
<ul>
<li>What state and state variables are in Solidity</li>
<li>Transactions and changing the state of a state variable</li>
<li>General information about variables in Solidity</li>
</ul>
<h3 id="heading-what-you-will-need">What You Will Need</h3>
<ul>
<li>Basic knowledge of smart contracts — You can get caught up here → <a target="_blank" href="https://blog.paulmcaviney.ca/hello-world">https://blog.paulmcaviney.ca/hello-world</a></li>
</ul>
<h3 id="heading-resources">Resources</h3>
<ul>
<li>Blockchain for beginners → <a target="_blank" href="https://101blockchains.com/blockchain-for-beginners/">https://101blockchains.com/blockchain-for-beginners/</a></li>
<li>The Ethereum Virtual Machine → <a target="_blank" href="https://ethereum.org/en/developers/docs/evm/">https://ethereum.org/en/developers/docs/evm/</a></li>
<li>Solidity Style Guide → <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.9/style-guide.html">https://docs.soliditylang.org/en/v0.8.9/style-guide.html</a></li>
</ul>
<hr />
<h3 id="heading-why-does-state-matter">Why Does State Matter?</h3>
<p>The internet as we know it today is stateless. State refers to information. Since there isn't a native mechanism for keeping track of or changing state built into the current internet, We rely on centralized authorities to act as intermediaries for the transfer of value and maintaining state. </p>
<p>Workarounds such as cookies have been implemented, but they are created by companies who may not have the best intentions when it comes to your data. It often leads to the mishandling of user data and can also be an enticing target for hackers looking for credit card information. </p>
<p>The ability to track and maintain state on Ethereum takes the power out of these institution's hands and gives it back to the people. State of the network is then collectively maintained. We no longer need to rely on these companies to settle payments or keep track of our sessions online.   </p>
<h3 id="heading-so-what-is-state-in-solidity">So What Is State in Solidity?</h3>
<p>This just refers to the data being stored on the blockchain at a particular block. There are two types of data that can be stored on the Ethereum Blockchain: permanent data and ephemeral data. </p>
<p>Once permanent data is stored, you guessed it, it's permanent. It can't be modified or deleted. An example of this would be a transaction hash. The simplest transaction would be sending ETH from one account to another and would include information such as the recipient, the amount of ETH sent, and a signature to identify the sender. This data is then <a target="_blank" href="https://whiteboardcrypto.com/what-is-a-cryptographic-hashing-function/">hashed</a> and stored on the blockchain. </p>
<p>Ephemeral data refers to information that could change from block to block, such as the balance of a particular account or the value of a variable stored inside a smart contract.</p>
<h3 id="heading-state-variables">State Variables</h3>
<p>There are three types of variables in the Solidity coding language:</p>
<ul>
<li>Local Variables - A temporary value that is declared inside of a function, cannot be accessed outside and is only present until that function is finished executing.</li>
<li>Global Variables - Special variables that hold information about transactions and blockchain properties (eg: msg.sender, tx.origin).</li>
<li>State Variables - Values that are permanently stored in contract storage and hold data related to the contract state.</li>
</ul>
<p>Through the manipulation of state variables, we can effectively change the data being stored in a smart contract. State variables are declared inside contract scope and outside of function scope, meaning they would be one of your first declarations in a contract before declaring functions. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636155836202/tJqqgGGYF.jpeg" alt="variables(resized).jpg" /></p>
<h3 id="heading-transactions">Transactions</h3>
<p>In order to change the value of a state variable, you need to send a transaction. Although reading the value of this variable is free, it will cost a gas fee to send the transaction to change it. I won't go into what gas fees are in this post, but it is important to note that any transaction that changes the state of the Ethereum Virtual Machine will cost some amount of ETH. </p>
<p>There are also many factors that go into the calculation of gas fees such as the variable type, its size and even the order it is declared in relation to other variables. If you are deploying smart contracts onto Ethereum mainnet, gas fee optimization will play an important role. To learn more about gas fees check out the <a target="_blank" href="https://ethereum.org/en/developers/docs/gas/">Ethereum Docs</a>.</p>
<p>Now that you've got a basic understanding of what state is in Solidity and what it takes to change it, let's write our own smart contract to see it in action!</p>
<hr />
<h3 id="heading-the-code">The Code</h3>
<p>I'm going to assume you know the basic structure of a Solidity smart contract, so I won't be explaining anything pertaining to that. If you need to get caught up, you can do so here → <a target="_blank" href="https://blog.paulmcaviney.ca/hello-world">https://blog.paulmcaviney.ca/hello-world</a></p>
<ol>
<li>Head over to <a target="_blank" href="https://remix.ethereum.org/">https://remix.ethereum.org/</a> </li>
<li>Click on the <code>Create New File</code> button and let's name our new file <code>ChangeState.sol</code></li>
<li><p>Enter the following code:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

contract ChangeState {

  string message;

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMessage</span>(<span class="hljs-params">string memory newMessage</span>) <span class="hljs-title">public</span> </span>{
      message = newMessage;
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getMessage</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
      <span class="hljs-keyword">return</span> message;
  }

}
</code></pre>
<ul>
<li><p>The line <code>string message;</code> is declaring the state variable that will be saved in contract storage.</p>
</li>
<li><p>The function <code>setMessage()</code> allows us to change the value of <code>message</code> and is set to public so any one can access it.</p>
</li>
<li><p>The function <code>getMessage()</code> is a getter function that returns whatever the value of <code>message</code> is at the time it is called. You should be aware that if you were to declare the state variable <code>message</code> as public, Solidity automatically creates a getter function with the same name. I just wrote it out like this for the sake of clarity. It would look like <code>string public message;</code> otherwise.</p>
</li>
</ul>
<p>Alright, so now we have this fancy bit of code and understand what it's supposed to do, let's test it out and see if it actually works!</p>
<hr />
<h3 id="heading-testing-the-code">Testing The Code</h3>
</li>
<li><p>Hit <code>ctrl+s</code> to save and compile the code. If all goes well, you should have a little green checkmark next to the <code>Solidity compiler</code> icon on the left side navigation bar. If there was an issue, the line number with the issue will be highlighted red and hovering over it will give you an idea of what the error might be.</p>
</li>
<li><p>Click on the <code>Deploy &amp; run transactions</code> icon. You should then see the name of our contract <code>ChangeState - ChangeState.sol</code> underneath the Contract heading and directly underneath that there will be an orange Deploy button.   </p>
</li>
<li><p>Click on the orange Deploy button and our contract should appear under the Deployed Contracts heading at the bottom. If you click on the little arrow beside <code>CHANGESTATE</code> it will reveal buttons for the two functions in our smart contract - <code>setMessage</code> and <code>getMessage</code>. These are the buttons that will allow us to test if everything is working properly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636155950758/glXjTiSfV.jpeg" alt="deployed-contract(resized).jpg" /></p>
<p>Remix does something cool here. Notice how the two function buttons are different colors? The orange <code>setMessage</code> button represents a transaction that is not payable. This means the function does not transfer ETH from one account to another, just the gas fees associated with the transaction. Transactions that are payable will appear as red. They will transfer ETH and also cost gas fees. The blue <code>getMessage</code> button represents a call function, meaning it is just trying to read some data from a contract. </p>
<p>So just remember, orange and red buttons mean it costs gas, blue means it does not. Hovering over the buttons will display this as well.</p>
<p>Now let's actually test these functions and see what's going on.</p>
</li>
<li><p>First, click on the <code>getMessage</code> button and it will reveal the default value for our <code>message</code> state variable. This will display <code>0: string:</code> underneath the button, meaning it just returned an empty string. </p>
<ul>
<li><strong>Side Note</strong>  - Each declared variable will have a default value based on its type - there is no concept of undefined or null in Solidity.</li>
</ul>
</li>
<li><p>Next let's test the <code>setMessage</code> button. Enter in a new message in the text input that you'd like to assign to our <code>message</code> state variable. After clicking the button, you will notice that some new information was added in the console, which is located right underneath where we wrote our smart contract code. Click on the arrow beside the <code>Debug</code> button and let's check out what it says.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636154988571/xWnTAM_MU.png" alt="setmessage-transaction.png" /></p>
<p>Remember how in order to change the value of our state variable we need to send a transaction? This new message in the console is what's called a transaction receipt. It contains information about where the transaction came from, where it was going to and the amount of gas it cost. Interacting with any function that costs gas will produce a transaction receipt. </p>
<p>More on transaction receipts → <a target="_blank" href="https://medium.com/remix-ide/the-anatomy-of-a-transaction-receipt-d935aacc9fcd">https://medium.com/remix-ide/the-anatomy-of-a-transaction-receipt-d935aacc9fcd</a></p>
</li>
<li><p>The last step in testing our contract is clicking on the <code>getMessage</code> button one more time. This time, you will see that the message was updated to whatever you set the message as! It read the value of the <code>message</code> variable from its location in contract storage on the blockchain and displayed it for you to see in all its glory! </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636156030765/BUX1qmxJX.jpeg" alt="final-message(resized).jpg" /></p>
<p>Since we are accessing the value of our state variable through a function in our own smart contract, you might not see the significance here. To really get an idea of how awesome this is we should deploy our contract to a testnet and interact with it there through another contract! This will be the subject of my next article.</p>
</li>
</ol>
<h3 id="heading-more-on-variables">More On Variables</h3>
<p>Before I conclude this article, I want to leave you with some of the basic rules associated with variables:</p>
<ul>
<li>Variable scope can be defined to control who can use them<ul>
<li>Public - anyone can get the value of this variable</li>
<li>External - only external functions can get the value - <strong>not used on state variables</strong></li>
<li>Internal - only functions in this contract and related contracts can get the values of these variables</li>
<li>Private - can only be accessed by functions from the current contract</li>
</ul>
</li>
<li>Variable names are case sensitive.</li>
<li>There are  <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.9/cheatsheet.html?highlight=reserved keywords#reserved-keywords">reserved keywords</a> you should not use as variable names</li>
<li>Solidity variables can't start with a number, they should start with a letter or an underscore.</li>
<li>Solidity is a statically typed language, meaning the variable types need to be specified when declaring them</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>One of the greatest aspects of the Ethereum Blockchain is its ability to manage state through the EVM. You were able to successfully create a state variable, update its value which is placed in contract storage on the blockchain and retrieve that value. You should now have a basic understanding of how this is accomplished through the use of state variables and transactions. Congratulations! You are one step closer to mastering the fundamentals of Solidity!</p>
<p>Thanks for taking the time to read this article! I hope it helped you learn a little more about how Solidity works. If you would like me to write an article about a specific topic related to Solidity or Web3 in general, drop a comment or hit me up on  <a target="_blank" href="https://twitter.com/paul_can_code">Twitter</a>!</p>
]]></content:encoded></item><item><title><![CDATA[Hello World! An Introduction To Solidity Smart Contracts]]></title><description><![CDATA[Hello World!
Solidity is a high level programming language used to interact with the Ethereum Blockchain with what are called "smart contracts". These contracts store the logic intended to run on the  Ethereum Virtual Machine (EVM) and can modify the...]]></description><link>https://blog.paulmcaviney.ca/hello-world</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/hello-world</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Web3]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Hello World]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Fri, 22 Oct 2021 20:23:05 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World!</h2>
<p>Solidity is a high level programming language used to interact with the Ethereum Blockchain with what are called "smart contracts". These contracts store the logic intended to run on the  <a target="_blank" href="https://ethereum.org/en/developers/docs/evm/">Ethereum Virtual Machine (EVM)</a> and can modify the state of accounts on the blockchain. It is similar in looks to other coding languages such as JavaScript or C++ and supports inheritance and libraries, among other things.</p>
<p>With this blog post, we are going to write a basic smart contract. The function of this contract will be to say "Hello World!", a classic first challenge when learning a new programming language. All the code will be written in an online text editor called <a target="_blank" href="http://remix.ethereum.org/">Remix</a> so as long as you've got an internet connection (if you're reading this, I assume that you do) you will be able to follow along.</p>
<h4 id="heading-what-we-will-learn">What We Will Learn</h4>
<ul>
<li>Basic structure of a Solidity smart contract</li>
</ul>
<h4 id="heading-what-you-will-need">What You Will Need</h4>
<ul>
<li>Access to the internet</li>
<li>An insatiable drive for knowledge</li>
</ul>
<h4 id="heading-other-resources">Other Resources</h4>
<ul>
<li>Solidity Documentation - <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.9/">https://docs.soliditylang.org/en/v0.8.9/</a></li>
<li>Remix IDE Documentation -<a target="_blank" href="https://remix-ide.readthedocs.io/">https://remix-ide.readthedocs.io/</a></li>
</ul>
<h3 id="heading-lets-get-started">Let's Get Started</h3>
<p>Our first step will be to navigate to <a target="_blank" href="http://remix.ethereum.org">remix.ethereum.org</a>. Remix is an open source code editor that can be run from a browser or locally on a desktop. It has built in functionality for writing, testing, debugging and deploying smart contracts and is a great place to play around while learning Solidity.</p>
<p>Under the <code>default_workspace</code> heading on the left, you will find a button to create a new file. Click it and let's name our new file <code>HelloWorld.sol</code>. This will open up the editor and give us a space to write our code. In case it doesn't automatically open up the editor, just click on the newly created HelloWorld.sol file and you should be good to go.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1634931759303/FOfDFkyoG5U.png" alt="Click Create New File button and name it HelloWorld.sol" /></p>
<p>Click the Create New File button and name it HelloWorld.sol</p>
<h3 id="heading-the-code">The Code</h3>
<p>Next we will get to the good stuff.. Writing code! Since the code for this project won't be too complicated, we'll write it all out then test it and then I will break it down line by line to explain what everything means. </p>
<pre><code class="lang-jsx"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

contract HelloWorld {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHello</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello World!"</span>;
    }
}
</code></pre>
<p>Awesome! You have just written your first smart contract! Definitely something to be proud of! Okay so now how do we check if it works?</p>
<p>First, hit <code>ctrl + s</code>  to save your work. You should notice a little green check mark on the left hand side of your screen on the Solidity Compiler icon. This is just signifying that everything compiled without warnings or errors.</p>
<p>Next, click on the icon below that one labelled <code>Deploy &amp; run transactions</code> . You should see the name of your contract, <code>HelloWorld - HelloWorld.sol</code>, under the Contract Heading and directly underneath that, an orange Deploy button. Click that button and your contract should then appear under the Deployed Contracts heading at the bottom.</p>
<p>You can see the details of the deployment of your contract in the built in console if you like. It will tell the address deployed to and gas cost, among other things</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1634932207394/MEaDmalaQ.png" alt="Click on the little arrow beside HELLOWORLD to expose our sayHello function." /></p>
<p>Clicking on the little arrow beside HELLOWORLD under Deployed Contracts will open up a dropdown menu which exposes a nice little button with our function name on it <code>sayHello</code>. Click that button, and VOILA! The fruits of our labor! The contract just returned a string with the contents of "Hello World!"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1634932390596/eeOHPAb3W.png" alt="Hello World!" /></p>
<p>Congratulations! You have successfully written and deployed your first functioning smart contract! Now that we can see what a basic smart contract looks like and that it is working properly, let's break the code down to get a better understanding of what's going on.</p>
<h3 id="heading-the-code-step-by-step">The Code Step By Step</h3>
<p>The very first line in our smart contract is the following:</p>
<p><code>// SPDX-License-Identifier: UNLICENSED</code></p>
<p>As of Solidity version 0.6.8, the first line in every smart contract is the SPDX License Identifier. SPDX stands for Software Package Data Exchange. The two forward slashes are how you comment out a line so it's not treated as part of the contract code.</p>
<p>Having the source code available helps establish trust that the contract isn't doing anything it's not supposed to. It is best practice to include a type of license that the code you are writing can be used under. Since this is just a quick example and we won't actually be publishing this contract we aren't going to supply an open source license. In this case it is good practice to substitute the license for the term <code>UNLICENSED</code>. The compiler will give you a warning if you don't have an SPDX License Identifier and will throw an error if you have more than one.</p>
<ul>
<li>A list of the usable SPDX licenses can be found at <a target="_blank" href="https://spdx.org/licenses/">https://spdx.org/licenses/</a></li>
</ul>
<hr />
<p>The next line in our contract will be:</p>
<p><code>pragma solidity ^0.8.7;</code></p>
<p>This line is used by the compiler to check if the source code is compatible with its (the compiler's) current version. This directive is always local to the file it is written in, meaning you would have to add another pragma directive to every other Solidity contract in your project.</p>
<p>The portion <code>^0.8.7</code> is telling the compiler that this contract is compatible with versions from 0.8.7 up to but not including 0.9.0. More complex rules for the compiler version can be specified, following similar syntax rules used by npm. These can be found here → <a target="_blank" href="https://docs.npmjs.com/cli/v6/using-npm/semver">https://docs.npmjs.com/cli/v6/using-npm/semver</a></p>
<p>The last piece of that line is the semicolon <code>;</code>. Similar to other coding languages, a semicolon is used to indicate the end of a coding statement.</p>
<hr />
<p>The next line is:</p>
<p><code>contract HelloWorld {</code> </p>
<p>This is defining our contract and is closed off by the curly brace <code>}</code> at the bottom of our code on line 8. Everything inside of these curly braces is an element of our smart contract and will reside at a specific address on the blockchain. This can include functions and data related to its state on the blockchain called state variables.</p>
<hr />
<p>Inside of our contract declaration, the first line is:</p>
<p><code>function sayHello() public pure returns (string memory) {</code></p>
<p>You will notice it is indented from the left, this is to promote readability and state that this code block is inside of the contract HelloWorld. Like our statement defining our contract, this function is also closed off by the other curly brace on line 7.</p>
<p>There is a lot going on in this line of the contract so let's break it down</p>
<ul>
<li><code>function</code> is how we state that the following code will be a function. It will then be able to be executed as such by calling it elsewhere in our code. The Remix IDE also picks up on these functions and creates a button for us to more easily test them.</li>
<li><code>sayHello()</code> is the name of our function and inside the parenthesis is where we would put any arguments for the function, which is beyond the scope of this article.</li>
<li><code>public</code> means that this function is accessible to the public, anyone can execute it. It's opposite would be <code>private</code> which means that the function is only able to be called by code in the contract itself.</li>
<li><code>pure</code> is the type of function. It means that this function doesn't read or modify the state of the contract. Other keywords such as <code>view</code>, <code>external</code>, <code>payable</code> and others all have different uses.</li>
<li><code>returns (string memory)</code> indicates that we want this function to return a string (an array of characters such as a sentence) and that we want to store it in memory as a temporary value. Memory variables are erased between function calls.</li>
</ul>
<hr />
<p>The line inside of our function is:</p>
<p><code>return "Hello World!";</code></p>
<p>This line is where the magic happens. It is telling our contract to return the string "Hello World!" whenever the function <code>sayHello()</code> is called. When declaring a string, it is important to wrap it in quotation marks. This expresses the boundary of the string so it doesn't get mistaken with the rest of the code.</p>
<hr />
<p>I hope this article has helped you understand the basic structure of a Solidity smart contract. It might be a little more in depth than your usual "Hello World!" post but I wanted to make sure you understand what is happening instead of just copying the code that was written. </p>
<p>In my next article we will go over what a state variable is and change "Hello World!" into anything we want! This new state will be saved to the blockchain so anyone can see what we have our variable set as. How exciting!</p>
]]></content:encoded></item><item><title><![CDATA[What Is Web3?]]></title><description><![CDATA[There has been a lot of hype around Web3 lately, and rightfully so. It is a fast and exciting new thing that seems extremely promising. It is my intention with this blog post to give a high level understanding of what Web3 is, its benefits and also i...]]></description><link>https://blog.paulmcaviney.ca/what-is-web3</link><guid isPermaLink="true">https://blog.paulmcaviney.ca/what-is-web3</guid><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Paul McAviney]]></dc:creator><pubDate>Fri, 15 Oct 2021 18:56:20 GMT</pubDate><content:encoded><![CDATA[<p>There has been a lot of hype around Web3 lately, and rightfully so. It is a fast and exciting new thing that seems extremely promising. It is my intention with this blog post to give a high level understanding of what Web3 is, its benefits and also its drawbacks. Although there have been many of these types of posts already, I am writing this for my own understanding. If reading this happens to help someone else, all the better!</p>
<p>The internet as we know it has almost completely ingrained itself into our everyday life. People have been able to connect in ways never known before, while online shopping has changed the face of commerce forever. While all this is great, the current architecture favors big companies that have the resources required to run the networks we rely on so heavily. These companies ultimately control the data flow which means they are the ones with all the power.</p>
<p>Web3 is a paradigm shift, the natural evolution of the internet. A decentralized network without a single point of failure and unable to be censored. What does this all mean? In order to understand exactly what Web3 is and the problems it solves, we first need to understand it's predecessors. </p>
<h2 id="web1-vs-web2-vs-web3">Web1 vs Web2 vs Web3</h2>
<h3 id="web-10">Web 1.0</h3>
<p>The first iteration of the web began roughly around 1991 and lasted to about 2004. In this time, developers would make a website that users could navigate to and take in the information, usually just in text or image format. So the average user was just a consumer of content and could not upload their own. It was a very one-way interaction. </p>
<h3 id="web-20">Web 2.0</h3>
<p>Web2 marks an era where users could participate in the creation of content online. Where we are at currently, you don't have to be a developer in order to post your ideas to the web. You could create a video, upload it and have other users interact with it through watching, sharing or commenting. Write a blog post directly online, even create entire websites without touching a line of code. </p>
<p>Through sites such as Facebook and YouTube, people are able to interact in ways that were not possible before. You could make friends with people across the globe and easily communicate with them. This international collaboration created new opportunities for everyone. Businesses are now able to exist entirely online. E-commerce has exploded, making the purchase of goods as easy as pressing a button.</p>
<p>There are a few major drawbacks however. First, the networks these websites run on are entirely centralized. This means that the owners of the network are in complete control of the data flowing in and out. This has resulted in companies selling its user's data for vast amounts of money, while the average user gets nothing in return. </p>
<p>Second, because of this centralization, it creates a single point of failure. All one would have to do to take down an organization's site is to attack its servers. This issue doesn't even have to be an attack. Just recently, Facebook's entire digital infrastructure, including Instagram and WhatsApp, was taken offline apparently due to a  <a target="_blank" href="https://interestingengineering.com/insiders-posted-about-the-cause-of-facebooks-fall-heres-the-details">configuration change</a>. Millions of people who rely on these services for everyday communication were unable to access them for up to 12 hours.   </p>
<p>Thirdly, the operators of these platforms have the power to censor anyone who uses them. They are in control of deeming what is appropriate for users to interact with. If Twitter decides your content doesn't match its guidelines, it could get taken down or worse, you could be banned.</p>
<p>Thankfully, Web3 aims to solve these massive issues and bring us into a new era of interactivity online. </p>
<h3 id="web-30">Web 3.0</h3>
<p>Web3 is essentially a decentralized version of Web2 which aims to give power back to the people that use it. </p>
<p>It is decentralized in the sense that the entire network, called a blockchain, exists on many computers around the globe, not just a few server locations. In order for any changes to be made to the blockchain they need to be agreed upon by the people running the network. This makes the whole system more democratic, as anyone can operate a node and participate in this process. </p>
<blockquote>
<p>It's important to note that blockchain technology itself is not Web3. It is just a tool to help facilitate this new era of internet.</p>
</blockquote>
<p>This inherent decentralization forces companies to find a new way to make money online instead of harvesting its users data. They would no longer be the sole holder of this information, thus making it impossible to monetize. </p>
<p>Because the network is spread out over a vast array of computers, this also eliminates the vulnerability of having a single point of failure. In order to take the network down, someone would have to attack all the computers in the network at the same time, which is virtually impossible. </p>
<p>As for censorship, since all the data lives on the blockchain, it can never be taken down or covered up. The data is not controlled by any one party, it exists on every single node of the network so anyone can see what was uploaded by which address and when. </p>
<h2 id="improvements">Improvements</h2>
<p>Not only does Web3 aim to fix issues with the existing architecture of the internet, it also seeks to add improvements to the experience as a whole. </p>
<p>One major improvement is the use of cryptocurrencies as a payment gateway. Currently, if you want to send someone money across the globe it is a huge process involving a mediary such as a bank. You have to physically go to the bank, pay them a fee, sometimes answer questions about why you are sending money in the first place, and after all that, it can still take a few days for your money to reach its destination. </p>
<p>With cryptocurrency being native to the internet, once you have the coins in your wallet, all it takes to send someone money is to paste in their wallet address, choose the amount you want to give them, then hit send. That's it. Depending on the cryptocurrency used, this could take a few seconds or minutes. Not days. </p>
<p>Outside of sending cryptocurrency, in order to interact with Web3 sites, a user will need to set up a wallet. The two most common ones are Coinbase Wallet and  <a target="_blank" href="https://metamask.io/">Metamask</a>. These wallets basically act as a single sign-in for the entire Web3. You only need to make one account, click the button to connect your wallet, and you are good to go. </p>
<p>This makes things so much easier for the average user. You only need to manage one password for the entire web and if you want to pay for something, your wallet is already connected so it's just a few button clicks. On top of that, no personal data is required to login to these sites and anyone can get a wallet and use the network, making it permission-less.</p>
<h2 id="drawbacks">Drawbacks</h2>
<p>All that being said, there are some drawbacks to this new era of internet in its current state. Primarily, it is quite difficult for the average user to get into it. Signing up for a wallet is a process that many people will not be used to, and for those not technologically inclined it can seem very daunting.</p>
<p>The space is also full of scammers looking to prey on new users of the Web3 architecture. A common issue is for someone to post in a public forum seeking help and a scammer will pose as tech support for the specific platform. They would then ask for the seed phrase for your wallet (a series of 12 or more words used to gain access or reactivate your wallet) and once they have that, drain your account for everything that's in there. (NEVER GIVE YOUR SEED PHRASE TO ANYONE.)</p>
<p>Another major drawback is the challenge of scalability. In order to serve the masses, Web3 and its technologies will need to be able to handle thousands of transactions per second. In its current state, the Ethereum blockchain - which can be considered the backbone of Web3 - can only handle around 30. To put that into perspective, Visa handles roughly 1700 transactions per second.</p>
<p>Additionally, it costs money to carry out these transactions in what is called "gas fees". Storing large amounts of information on the blockchain is quite expensive and the fees involved are very volatile. In order for this technology to be used at scale, things will have to be much cheaper and more predictable.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Although there are still many technological challenges with bringing about the wide adoption of this new era of internet, I am convinced it will be accomplished. The benefits from using this technology are just too vast and world changing for it not to be the way things are done in the future. On top of that, these challenges are being tackled by some of the world's strongest minds. </p>
<p>What we are seeing now is just the very beginning of something huge. In 5 to 10 years time, we will be living in a world where technology is more strongly ingrained with the fabric of society, making it easier for people to interact online and distributing the power and wealth generated more evenly to the average user.</p>
]]></content:encoded></item></channel></rss>