Contents

    Guides

    Build a dApp with Ethers and SvelteJS

    Oduah Chigozie

    I am a software engineer and technical writer with experience in blockchain, frontend, and backend technologies.

    Published on

    September 5, 2022
    Build a dApp with Ethers and SvelteJS

    Have you ever thought about how you can create an application, then forget all about it and possibly still make your money? Have you also wondered how you can build an application that doesn't need maintenance whatsoever? Well, the blockchain allows you to do all of that through decentralised applications (or dApps). dApps allow you to develop applications on a blockchain network without providing any resources or servers. They also don’t require your control or maintenance to operate, and are more secure than regular applications.

    In this article, you will learn how to build a decentralised application on the ethereum network with Svelte JS, Ethers and the Truffle framework.

    Prerequisites

    To follow this article, you need the following:

    • An understanding of SvelteJS and Solidity
    • NPM and NodeJS installed in your system

    You don’t need to understand Ethers and Truffle, but understanding them helps.

    What is a dApp?

    A dApp (decentralised application) is an app that runs on a peer-to-peer network like the blockchain. DApps can often be confused with regular apps because they use a similar interface. The only things that separates a dApp from an app is the lack of a central server, and the use of a blockchain network. A popular example of a dApp is OpenSea. It interacts with several blockchain networks, and it isn’t hosted by a central server.

    Most dApps rely on smart contracts to process data on a blockchain. Smart contracts are very important and are a very secure method for dapp to store and process data collectively. Development of smart contracts varies on all blockchain. Ethereum provides a programming language called Solidity, for creating them.

    Initialising The Project

    Before building the application, let’s start by setting up our. Make sure you have truffle and ganache installed in your system. If they are not installed, run this command to install them:

    $ npm install -g truffle ganache

    Truffle is a framework for building, compiling and deploying smart contracts. And Ganache allows you to create a local development blockchain in your computer system.

    You can confirm that the packages were installed with these commands:

    $ truffle version
    $ ganache version

    Now, start up the local development blockchain with ganache:

    $ ganache

    The environment allows you to deploy and experiment with smart contracts on a simulated local blockchain.

    Now, you can initialize the project with this command:

    $ truffle init svelte-dapp

    This will create a svelte-dapp directory with the following tree structure:

    svelte-dapp
    ├── contracts/
    │   └── Migrations.sol
    ├── migrations/
    │   └── 1_initial_migration.js
    │   └── src/
    │       ├── App.svelte
    │       └── main.js
    ├── test/
    └── truffle-config.js

    Open the svelte-dapp folder in your terminal and create the svelte frontend project with this command:

    $ npx degit sveltejs/template dapp-frontend

    In your terminal, enter into dapp-frontend and run the command below to install the dependencies:

    $ npm install

    Finally, install ethers because it allows the dApp to interact with the Ethereum blockchain:

    $ npm install ethers

    The Solidity Contract

    Now that you have your project setup, you can build the smart contract. To build a smart contract, create a new file inside the contracts folder. For this project, create a StoreMessage.sol file with the below in it:

    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8;
    
    contract StoreMessage {
      string public message;
      
      constructor () {
        message = "Hello, There";
      }
    
      function setMessage (string memory _message) public {
        message = _message;
      }
    
    }

    The smart contract is a simple solidity script that:

    1. Tells the compiler which version of Solidity to use
    pragma solidity ^0.8;
    1. declares a public variable called message:
    string public message;
    1. Initializes the message variable with “Hello, There!” when the contract is deployed:
    constructor () {
      message = "Hello, There";
    }
    1. Creates a setMessage method that allows you to change the message variable:
    function setMessage (string memory _message) public {
        message = _message;
      }

    This smart contract has two interfaces when you deploy it:

    • message, allows anyone to get the message string
    • setMessage, allows anyone to change the message string

    Compile the smart contract

    Before compiling the contract, make sure that the version of your compiler is the same as the smart contract ( 0.8 ) in the truffle-config.js file:

    View of the compiler

    To compile this contract, run the command below:

    $ truffle compile

    Note: you need an active internet connection. Truffle has to download the solidity compiler before compiling.

    Deploy the smart contract

    After compiling, the next thing to do is to deploy the contract. To deploy the contract, create a migration script. The migration script allows you to execute operations before and after deploying the contract. To create the migration, open the migrations folder and create a new 2_deploy_message_contract.js file with the following in it:

    const StoreMessage = artifacts.require("StoreMessage");
    
    module.exports = function (deployer) {
      deployer.deploy(StoreMessage);
    };

    Here's a breakdown of the script:

    1. Import the StoreMessage contract to the script:
    const StoreMessage = artifacts.require("StoreMessage");
    1. Create an anonymous function and assign to module.export:
    module.exports = function (deployer) {...
    1. Use deployer argument to deploy the StoreMessage contract:
      deployer.deploy(StoreMessage);

    After creating the migration, open the truffle-config.js file and uncomment the development object:

    View of the development object

    Truffle uses the development entry to connect to the local development node at “http://127.0.0.1:8545”. To deploy the smart contract, run this command:

    $ truffle deploy --network development

    When you run the deploy command, truffle executes the migration files in the order of their name.

    Interact with the contract

    To interact with the smart contract from truffle, run this command:

    $ truffle console

    The truffle console command spins up a console that allows you to interact with smart contracts. To create the instance of the deployed StoreMessage contract, run:

    truffle(development)> contract = await StoreMessage.deployed()

    You can get the contract’s address with:

    truffle(development)> contract.address

    You can also call the contract methods:

    truffle(development)> contract.message()
    truffle(development)> contract.setMessage("Hi, There!")

    With the contract ready, you can start building the front-end for the dApp. Do not close the ganache terminal. This terminal will act as a blockchain network for the frontend.

    The frontend application

    A dApp’s front-end provides the ability to interact with a blockchain to non-technical users. The front-end is an intuitive interface that doesn’t require any specialized knowledge before use.

    Paste the code below into the svelte’s project src/App.svelte file:

    <script>
     
      import { ethers } from 'ethers';
      import { abi, address } from './contractData.js';
     
      let connectedAccount = "";
      let contractMessage = "";
      const provider = new ethers.providers.Web3Provider(window.ethereum);
    
      async function connectWallet() {
        if (window.ethereum) {
          await window.ethereum.request({ method: 'eth_requestAccounts' })
          const signer = provider.getSigner();
          connectedAccount = await signer.getAddress();
        } else {
          alert('You need to install metamask');
        }
      }
    
      async function callContract() {
        const contract = new ethers.Contract(address, abi, provider);
        contractMessage = await contract.message();
      }
    </script>
     
    <main>
      <div>Connected Account: {connectedAccount}</div>
      <div>Contract Message: { contractMessage }</div>
     
      <button on:click={connectWallet}>Connect wallet</button>
      <button on:click={callContract}>Call Contract</button>
    </main>
    

    You also need to create a contractData.js file inside the src folder, and paste the following into it:

    export const abi = [
      {
        inputs: [],
        stateMutability: "nonpayable",
        type: "constructor",
      },
      {
        inputs: [],
        name: "message",
        outputs: [
          {
            internalType: "string",
            name: "",
            type: "string",
          },
        ],
        stateMutability: "view",
        type: "function",
        constant: true,
      },
      {
        inputs: [
          {
            internalType: "string",
            name: "_message",
            type: "string",
          },
        ],
        name: "setMessage",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
      },
    ];
    export const address = "contract address";

    Note: Replace the value of address (“contract address”) with the address of your deployed contract. You can find the contract’s address in the output of truffle deploy.

    How the contract address looks like in the output of the truffle deploy

    The App.svelte component provides a basic interface that looks like the below:

    View of basic interface as a result provided by the App.svelte component

    Connecting the wallet

    To interact with the blockchain network, this dApp needs the users to connect their Ethrereum wallet. The wallet pays the fees required to interact with certain functionalities like calling some types of smart contract functions and making other types of transactions.

    async function connectWallet() {
      if (window.ethereum) {
        await window.ethereum.request({ method: 'eth_requestAccounts' });
        const signer = provider.getSigner();
        connectedAccount = await signer.getAddress();
      } else {
        alert('You need to install metamask');
      }
    }

    When the user clicks the “Connect Wallet” button, the browser calls the connectWallet function. And the following happens:

    1. Checks that the window.ethereum object is present
    if (window.ethereum) {
    1. Triggers metamask’s wallet-connect to connect the users wallet:
    await window.ethereum.request({ method: 'eth_requestAccounts' });
    1. Accesses the user’s connected account (signer)
    const signer = provider.getSigner();
    1. Stores the account’s address in connectAddress:
    connectedAccount = await signer.getAddress();

    If Metamask is installed on the user’s browser, there will be a window.ethereum object. You can use this fact to check that Metamask is installed.

    Interacting with the smart contract

    One of the operations that happen in a dApp is interacting with smart contracts. The dApp uses a contract instance to interact with a contract. You create this instance by passing its address on the network and its ABI (Application Binary Interface). The ABI is an encoded description of a smart contract’s interface.

    async function callContract() {
      const contract = new ethers.Contract(address, abi, provider);
      contractMessage = await contract.message();
    }

    When the user clicks the “Call Contract” button, the browser calls the callContract function. And the following happens:

    1. Creates an instance of the smart contract with its ABI, address, and provider
    const contract = new ethers.Contract(address, abi, provider);
    1. Stores the result of calling the contract’s message:
    contractMessage = await contract.message();

    Running the dApp

    After building your dApp, you need to see how well it runs. To run the dApp, you need a browser with the Metamask extension installed, and a metamask wallet account.

    Open http://localhost:8080 in the browser to view the dApp. Then connect Metamask to the development node by opening the extension at the top-right, then Selecting “Localhost 8545” in the network drop-down:

    View of the network dropdown

    Now you can click on connect wallet, you should see a metamask pop-up requesting to connect your wallet. And after connecting the wallet, click on call contract, to get the contract message.

    Note: Make sure that the contract address in contractData.json is equal to the deployed contract address.

    Conclusion

    In this tutorial, you learned how to build a dApp using Svelte and Ethers JS. There’s more that you can learn about building dApps, and you don’t have to stop here:

    You can visit the Truffle docs to learn more about ganache, and truffle. You can also learn how to deploy a smart contract to a public testnet or mainnet. You can learn more about Metamask in its documentation. You can get the final project in this GitHub repo.

    Thanks for reading and happy coding!

    Data-rich bug reports loved by everyone

    Get visual proof, steps to reproduce and technical logs with one click

    Make bug reporting 50% faster and 100% less painful

    Rating LogosStars
    4.6
    |
    Category leader

    Liked the article? Spread the word

    Put your knowledge to practice

    Try Bird on your next bug - you’ll love it

    “Game changer”

    Julie, Head of QA

    star-ratingstar-ratingstar-ratingstar-ratingstar-rating

    Overall rating: 4.7/5

    Try Bird later, from your desktop