How to Deploy Your First dApp

1. Environment Setup and Toolchain Configuration

1.1 Development Environment Requirements

  • Node.js v18+ (recommended to use nvm for version management)

  • Go 1.24+ (for Cosmos SDK-relat4ed toolchain)

  • MetaMask wallet (configured with custom RPC)

  • Git (version control)

1.2 Chain Node Configuration

git clone https://github.com/eni-chain/go-eni.git
cd go-eni
make install

1.3 MetaMask Network Configuration

  1. Open MetaMask -> Networks -> Add Network

  2. Fill in the parameters:

  • Network Name: ENI Mainnet

  • RPC URL: https://rpc.eniac.network

  • ChainID: 173

  • Symbol: ENI

  • Block Explorer: https://scan.eniac.network

1.4 Development Tools Installation

# Install Hardhat
npm install --save-dev hardhat
npx hardhat init
# Select TypeScript template

2. Smart Contract Development and Deployment

2.1 Creating a Sample Contract

// contracts/MoodDiary.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract MoodDiary {
    string private mood;

    event MoodUpdated(address indexed user, string newMood);

    function setMood(string memory _mood) public {
        mood = _mood;
        emit MoodUpdated(msg.sender, _mood);
    }

    function getMood() public view returns (string memory) {
        return mood;
    }
}

2.2 Deployment Configuration (hardhat.config.ts)

import { HardhatUserConfig } from "hardhat/config";

const config: HardhatUserConfig = {
  solidity: "0.8.20",
  networks: {
    yourchain: {
      url: "https://rpc.eniac.network",
      accounts: [process.env.PRIVATE_KEY!],
      chainId: 173,
    }
  }
};

2.3 Deployment Script

// scripts/deploy.ts
import { ethers } from "hardhat";

async function main() {
  const MoodDiary = await ethers.getContractFactory("MoodDiary");
  const moodDiary = await MoodDiary.deploy();

  await moodDiary.waitForDeployment();
  console.log("Contract deployed to:", await moodDiary.getAddress());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

2.4 Execute Deployment

# Compile the contract
npx hardhat compile

# Deploy to mainnet (requires PRIVATE_KEY environment variable configured beforehand)
npx hardhat run scripts/deploy.ts --network $NETWORK_NAME

Example output: Contract deployed to: 0x3c45B8...dC7


3. Frontend Integration Development

3.1 Initialize React Project

npx create-react-app dapp-frontend --template typescript
cd dapp-frontend
npm install ethers @metamask/providers

3.2 Core Interaction Logic

// src/services/contract.ts
import { ethers } from "ethers";

const contractAddress = "0x3c45B8...dC7";
const abi = [...]; // Obtained from artifacts/contracts/MoodDiary.sol/MoodDiary.json

export async function getMood() {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const contract = new ethers.Contract(contractAddress, abi, provider);
  return await contract.getMood();
}

export async function setMood(newMood: string) {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const contract = new ethers.Contract(contractAddress, abi, signer);
  const tx = await contract.setMood(newMood);
  return tx.wait();
}

3.3 Wallet Connection Component

// src/components/WalletConnect.tsx
import { useState } from 'react';
import { ethers } from 'ethers';

export default function WalletConnect() {
  const [account, setAccount] = useState<string>("");

  const connectWallet = async () => {
    if (window.ethereum) {
      try {
        await window.ethereum.request({ method: 'eth_requestAccounts' });
        const provider = new ethers.BrowserProvider(window.ethereum);
        const signer = await provider.getSigner();
        setAccount(await signer.getAddress());
      } catch (error) {
        console.error("User denied account access");
      }
    } else {
      alert("Please install MetaMask!");
    }
  };

  return (
    <button onClick={connectWallet}>
      {account ? `Connected: ${account.slice(0,6)}...` : "Connect Wallet"}
    </button>
  );
}

4. Testing and Validation

4.1 Claim Test Tokens

  1. Visit the chain’s test faucet website

  2. Enter your wallet address to receive test ENI tokens

4.2 Functional Testing Process

  1. Start the frontend: npm start

  2. Connect the wallet (switch to ENI Testnet)

  3. Test scenarios:

  • Set Mood: Enter any string and submit

  • Get Mood: Verify the return value matches the blockchain state

  • Check Transaction Hash: Verify transaction details on the block explorer


5. Advanced Deployment Options

5.1 Deploying Contracts Using Cosmos CLI (Alternative)

# Upload contract ABI and bytecode to the chain
enid tx evm deploy <bytecode> --from <key-name> --chain-id $CHAIN_ID

5.2 Calling Chain-Specific Enhanced Features

// Example of accessing Cosmos SDK features
interface ICosmosPrecompile {
    function queryValidator(address valAddr) external view returns (uint256 votingPower);
}

contract ValidatorInfo {
    function getVotingPower(address valAddr) public view returns (uint256) {
        return ICosmosPrecompile(0x000000000000000000001).queryValidator(valAddr);
    }
}

6. Best Practice Recommendations

  1. Security Auditing: Use Slither or MythX for static contract analysis

  2. Gas Optimization: Leverage Cosmos SDK’s batch transaction features to reduce fees

  3. State Monitoring: Integrate Tendermint RPC for real-time event subscriptions

  4. Cross-Chain Integration: Interact with other Cosmos ecosystem chains via the IBC protocol

Last updated