DeveloperBreeze

Creating a Decentralized Application (dApp) with Solidity, Ethereum, and IPFS: From Smart Contracts to Front-End

Introduction

The rise of blockchain technology has led to the development of decentralized applications (dApps), which operate on a peer-to-peer network rather than relying on centralized servers. dApps provide increased security, transparency, and resistance to censorship. In this tutorial, we'll walk through the process of building a dApp using Solidity, Ethereum, and IPFS. We’ll cover everything from writing smart contracts to deploying them on the Ethereum blockchain, and then integrating them with a front-end built with modern web technologies.

1. Setting Up the Development Environment

Step 1: Install Node.js and npm

To start, ensure you have Node.js and npm installed on your machine. You can download them from the Node.js website.

Step 2: Install Truffle and Ganache

Truffle is a development framework for Ethereum that makes it easier to build and deploy smart contracts. Ganache is a personal blockchain for Ethereum development.

npm install -g truffle
npm install -g ganache-cli

Step 3: Create a New Truffle Project

Initialize a new Truffle project:

mkdir my-dapp
cd my-dapp
truffle init

This will create a basic project structure with directories for contracts, migrations, and tests.

2. Writing the Smart Contract with Solidity

Step 1: Create a New Solidity Contract

Navigate to the contracts directory and create a new file called MyDapp.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyDapp {
    string public message;

    event MessageChanged(string newMessage);

    constructor(string memory initialMessage) {
        message = initialMessage;
    }

    function setMessage(string memory newMessage) public {
        message = newMessage;
        emit MessageChanged(newMessage);
    }

    function getMessage() public view returns (string memory) {
        return message;
    }
}

This contract stores a message on the blockchain and allows users to update and retrieve it. It also emits an event whenever the message is changed.

Step 2: Compile and Migrate the Contract

Compile the contract using Truffle:

truffle compile

Next, deploy the contract to the local blockchain (Ganache):

Create a new migration file in the migrations directory:

const MyDapp = artifacts.require("MyDapp");

module.exports = function (deployer) {
  deployer.deploy(MyDapp, "Hello, world!");
};

Then, start Ganache and migrate the contract:

ganache-cli

In another terminal window:

truffle migrate

3. Interacting with the Smart Contract in a Front-End

Step 1: Set Up React for the Front-End

Create a React application in the project directory:

npx create-react-app client
cd client
npm install web3

Web3.js is a JavaScript library that allows you to interact with the Ethereum blockchain.

Step 2: Connect to the Smart Contract

In your React application, create a component Dapp.js that connects to the smart contract:

import React, { useState, useEffect } from 'react';
import Web3 from 'web3';
import MyDapp from './contracts/MyDapp.json';

function Dapp() {
  const [message, setMessage] = useState('');
  const [newMessage, setNewMessage] = useState('');
  const [web3, setWeb3] = useState(null);
  const [contract, setContract] = useState(null);
  const [account, setAccount] = useState('');

  useEffect(() => {
    const init = async () => {
      const web3 = new Web3(Web3.givenProvider || 'http://localhost:7545');
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = MyDapp.networks[networkId];
      const contractInstance = new web3.eth.Contract(
        MyDapp.abi,
        deployedNetwork && deployedNetwork.address,
      );
      const accounts = await web3.eth.getAccounts();
      setWeb3(web3);
      setContract(contractInstance);
      setAccount(accounts[0]);
      const initialMessage = await contractInstance.methods.getMessage().call();
      setMessage(initialMessage);
    };
    init();
  }, []);

  const updateMessage = async () => {
    await contract.methods.setMessage(newMessage).send({ from: account });
    const updatedMessage = await contract.methods.getMessage().call();
    setMessage(updatedMessage);
    setNewMessage('');
  };

  return (
    <div>
      <h1>Current Message: {message}</h1>
      <input
        type="text"
        value={newMessage}
        onChange={(e) => setNewMessage(e.target.value)}
      />
      <button onClick={updateMessage}>Update Message</button>
    </div>
  );
}

export default Dapp;

Step 3: Run the Front-End

Navigate to the client directory and start the React application:

npm start

Now, your React app should be connected to the Ethereum blockchain, allowing you to interact with the deployed smart contract.

4. Storing Data on IPFS

Step 1: Install IPFS

Install IPFS on your machine following the instructions from the IPFS documentation.

Step 2: Add Files to IPFS

Start the IPFS daemon and add a file to IPFS:

ipfs init
ipfs daemon
ipfs add <file-path>

The output will include a unique hash that represents the file on the IPFS network.

Step 3: Integrate IPFS with the Smart Contract

Modify your smart contract to store and retrieve IPFS hashes. For simplicity, we'll store the hash of a file uploaded to IPFS.

Update MyDapp.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyDapp {
    string public ipfsHash;

    event IPFSHashChanged(string newIPFSHash);

    function setIPFSHash(string memory newIPFSHash) public {
        ipfsHash = newIPFSHash;
        emit IPFSHashChanged(newIPFSHash);
    }

    function getIPFSHash() public view returns (string memory) {
        return ipfsHash;
    }
}

Update the React component to include IPFS integration:

const updateIPFSHash = async () => {
  const ipfsHash = 'Your IPFS hash here';
  await contract.methods.setIPFSHash(ipfsHash).send({ from: account });
  const updatedIPFSHash = await contract.methods.getIPFSHash().call();
  console.log(updatedIPFSHash);
};

5. Deploying the dApp

Step 1: Deploying to the Ethereum Mainnet

To deploy your smart contract to the Ethereum mainnet, you’ll need to configure Truffle to connect to an Ethereum node (e.g., Infura) and provide a wallet with Ether to pay for gas.

Update truffle-config.js with the necessary configurations and deploy:

truffle migrate --network mainnet

Step 2: Hosting the Front-End

You can host your front-end on a decentralized platform like Fleek or Netlify for broader access.

Conclusion

In this tutorial, we built a decentralized application (dApp) using Solidity, Ethereum, and IPFS. We covered the entire process from writing and deploying a smart contract, interacting with the contract through a React-based front-end, to integrating decentralized file storage using IPFS. This dApp architecture provides a foundation for developing more complex decentralized applications, offering users increased security, transparency, and control over their data.

The skills learned here can be extended to more advanced dApp development, including interacting with other decentralized protocols, enhancing security, or integrating with existing blockchain services.

Continue Reading

Discover more amazing content handpicked just for you

Tutorial

Understanding `crypto.randomBytes` and `ethers.randomBytes`: A Comparison

    const { ethers } = require('ethers');
    const randomBytes = ethers.utils.randomBytes(32);
    console.log(randomBytes); // Uint8Array of random bytes
  • crypto.randomBytes is part of Node.js, so it requires no external dependencies. This makes it ideal for Node.js environments where minimal dependencies are desired.
  • ethers.randomBytes requires the installation of the ethers.js library, which is primarily designed for blockchain-related projects. This is useful if you're already working with Ethereum, but it adds an external dependency to the project.

Oct 24, 2024
Read More
Tutorial

Working with `BigNumber` in ethers.js: A Guide for Version 6

  • To Number:
  const numberValue = num.toNumber(); // 12345

Oct 24, 2024
Read More
Tutorial

How to Query ERC-20 Token Balances and Transactions Using Ethers.js and Etherscan API

We will use Ethers.js to interact with the Ethereum blockchain and Axios to make HTTP requests to the Etherscan API.

npm install ethers
npm install axios

Oct 24, 2024
Read More
Tutorial

Etherscan vs Infura: Choosing the Right API for Your Blockchain Application

  • Basic understanding of Ethereum and blockchain concepts.
  • Familiarity with APIs and programming in Node.js or any other language.

Before diving into code examples, it's important to understand the core differences between Etherscan and Infura.

Oct 24, 2024
Read More
Tutorial

Sending Transactions and Interacting with Smart Contracts Using Infura and Ethers.js

Transaction sent: 0xTransactionHash
Transaction confirmed: { transaction details }

Next, let’s interact with a smart contract using Ethers.js and Infura. For this example, we will call a read-only function from an ERC-20 token contract (like querying the balance of a wallet).

Oct 24, 2024
Read More
Tutorial

Understanding and Using the Etherscan API to Query Blockchain Data

npm install axios

Let’s create a Node.js script to query the balance of an Ethereum wallet using the Etherscan API.

Oct 24, 2024
Read More
Tutorial

Getting Wallet Balance Using Ethers.js in Node.js

const ethers = require('ethers');

// Replace this with your Ethereum wallet's private key or mnemonic phrase
const privateKey = 'YOUR_PRIVATE_KEY_OR_MNEMONIC';

// Use a public Ethereum node URL (this is a public node for demonstration purposes)
const publicProvider = new ethers.JsonRpcProvider('https://mainnet.publicnode.com');

// Create a wallet instance using your private key and connect it to the public node provider
const wallet = new ethers.Wallet(privateKey, publicProvider);

// Function to get the balance of the wallet
async function getWalletBalance() {
    // Get the wallet's balance in wei
    const balanceInWei = await wallet.getBalance();

    // Convert the balance from wei to Ether for readability
    const balanceInEther = ethers.utils.formatEther(balanceInWei);

    // Log the results
    console.log(`Wallet Address: ${wallet.address}`);
    console.log(`Wallet Balance: ${balanceInEther} ETH`);
}

// Execute the function
getWalletBalance();
  • Replace 'YOUR_PRIVATE_KEY_OR_MNEMONIC' with your actual Ethereum wallet's private key or mnemonic phrase.
  • For the Infura method, replace 'YOUR_INFURA_PROJECT_ID' with the Infura Project ID you received when you created your Infura account.

Oct 24, 2024
Read More
Tutorial

Understanding 0x000000000000000000000000000000000000dead Address and Token Burns in Ethereum

For example, in token burn events, project developers often send tokens to this address to signal to the community that those tokens are now out of circulation. This is usually followed by a public announcement, detailing the number of tokens burned and the reasons behind the burn.

Token burns are typically done to increase scarcity, and scarcity can lead to a higher token value if demand remains the same or increases. The basic principle of supply and demand comes into play: when the supply of an asset is reduced, it becomes more valuable (assuming demand holds steady).

Oct 24, 2024
Read More
Tutorial

ETH vs WETH: Understanding the Difference and Their Roles in Ethereum

WETH essentially bridges the gap between ETH and the broader ERC-20 ecosystem, allowing ETH to function seamlessly in DeFi, token swaps, and other smart contract interactions.

Wrapping ETH into WETH is a simple process that can be done through various decentralized exchanges or applications. Here’s a typical process:

Oct 24, 2024
Read More
Cheatsheet
solidity

Blockchain Libraries Cheatsheet

  npm install bitcore-lib

Aug 23, 2024
Read More
Cheatsheet
solidity

Blockchain Development Tools, Libraries, and Frameworks Cheatsheet

Blockchain development is a rapidly growing field with a wide range of tools, libraries, and frameworks available to facilitate the development, testing, and deployment of decentralized applications (DApps) and smart contracts. This cheatsheet provides a comprehensive overview of the most important blockchain development tools, libraries, and frameworks.

  • Description: A development framework for Ethereum that provides a suite of tools for writing, testing, and deploying smart contracts.
  • Key Features:
  • Built-in smart contract compilation, linking, deployment, and binary management.
  • Scriptable deployment & migrations framework.
  • Network management for deploying to different networks.
  • Interactive console for direct contract interaction.
  • Testing framework using Mocha and Chai.
  • Website: Truffle

Aug 23, 2024
Read More
Tutorial
solidity

Writing an ERC-20 Token Contract with OpenZeppelin

  • Use libraries like Web3.js or Ethers.js to build a front-end that interacts with your token contract. Connect the front-end to MetaMask to allow users to interact with the contract.

If you’ve deployed your contract to a public testnet or the mainnet, you might want to verify the contract on Etherscan.

Aug 22, 2024
Read More
Cheatsheet
solidity

Solidity Cheatsheet

  • Ganache: Personal blockchain for Ethereum development.

This Solidity cheatsheet covers the essential concepts and syntax needed to start writing and optimizing smart contracts. As you develop more complex contracts, always consider security, gas efficiency, and best practices to ensure your contracts are robust and cost-effective.

Aug 22, 2024
Read More
Tutorial
solidity

Understanding Gas and Optimization in Smart Contracts

Gas is the measure of computational effort required to execute operations on the Ethereum network. Each operation, from simple arithmetic to complex smart contract execution, consumes a specific amount of gas. Users must pay for gas in Ether, which compensates miners for the resources required to process and validate transactions.

Key Points:

Aug 22, 2024
Read More
Tutorial
solidity

Building a Decentralized Application (DApp) with Smart Contracts

  • Start Ganache and configure Truffle to use it by editing the truffle-config.js file.
  • Run truffle migrate to deploy the smart contract to the local blockchain provided by Ganache.

Now that the smart contract is deployed, let’s create a front-end interface to interact with it. We’ll use HTML, JavaScript, and Web3.js to build a simple web page that allows users to set and retrieve the message stored in the contract.

Aug 22, 2024
Read More
Tutorial
solidity

Introduction to Smart Contracts on Ethereum

  • Decentralized: Operates on the blockchain, not controlled by any single entity.
  • Trustless: Executes automatically when conditions are met, without requiring trust between parties.
  • Immutable: Once deployed, the contract's code cannot be changed, ensuring the terms are fixed.

Before writing a smart contract, we need to set up a development environment. Here’s what you need:

Aug 22, 2024
Read More
Tutorial
javascript nodejs

Tracking Solana Address for New Trades and Amounts

Step 2: Connect to the Solana Network

Create a new file called index.js and add the following code to connect to the Solana blockchain:

Aug 09, 2024
Read More
Tutorial
javascript nodejs

Tracking Newly Created Tokens on Solana

Step 3: Fetch New Token Creation Transactions

Solana tokens are created using the SPL Token Program, so we'll track transactions involving this program to identify new tokens. Add the following function to your index.js file:

Aug 09, 2024
Read More
Tutorial
javascript nodejs

Tracking Newly Created Tokens on Ethereum

Step 4: Monitor for New Tokens

You can run this script periodically to monitor for new token creation events. Consider setting up a cron job or a scheduled task to execute the script at regular intervals.

Aug 09, 2024
Read More
Tutorial
javascript json

Fetching Address Details from Solana

Next, let's fetch the balance of a specific wallet address. Add the following function to your index.js file:

async function getWalletBalance(walletAddress) {
  try {
    const publicKey = new solanaWeb3.PublicKey(walletAddress);
    const balance = await connection.getBalance(publicKey);
    console.log(`Wallet Balance: ${balance / solanaWeb3.LAMPORTS_PER_SOL} SOL`);
  } catch (error) {
    console.error('Error fetching wallet balance:', error);
  }
}

// Replace with your Solana wallet address
const walletAddress = 'YourWalletAddressHere';
getWalletBalance(walletAddress);

Aug 09, 2024
Read More

Discussion 0

Please sign in to join the discussion.

No comments yet. Start the discussion!