从零开始构建你的第一个DApp,以太坊开发实战教程全解析

 :2026-02-11 21:57    点击:8  

以太坊,作为全球领先的智能合约平台,不仅开创了去中心化应用(DApps)的新纪元,也为开发者和创业者提供了无限的创新可能,本教程将带你从环境搭建到智能合约编写,再到前端交互,一步步完成一个简单的以太坊DApp开发实战,助你快速入门以太坊开发的世界。

开发环境准备:工欲善其事,必先利其器

在正式开始之前,我们需要准备好一系列开发工具:

  1. Node.js 和 npm:JavaScript 运行时环境和包管理器,建议从 Node.js 官网 下载 LTS 版本。
  2. Truffle Suite:以太坊最受欢迎的开发框架之一,包含开发环境、测试框架和资产管道,它简化了智能合约的编译、测试和部署流程。
    • 安装:npm install -g truffle
  3. Ganache:一款个人区块链,用于快速部署和测试智能合约,它会在本地创建一个区块链网络,并提供预设的测试账户和以太坊。
  4. MetaMask:一款浏览器插件钱包,用于与以太坊区块链交互,在开发中,它可以模拟用户钱包,让我们能够与本地或测试网的智能合约进行交互。
    • 安装:从 MetaMask 官网 或浏览器应用商店安装,并创建一个测试账户。
  5. 代码编辑器:推荐使用 Visual Studio Code (VS Code),并安装 Solidity 插件以获得语法高亮和智能提示。
  6. Git:版本控制工具,用于管理代码。

创建项目结构

  1. 创建一个新的项目文件夹,my-first-dapp,并在终端中进入该文件夹。
  2. 初始化一个新的 Truffle 项目:
    truffle init

    这会生成以下标准目录结构:

    • contracts/:存放 Solidity 智能合约文件。
    • migrations/:存放部署脚本文件。
    • test/:存放测试文件。
    • truffle-config.js:Truffle 配置文件。

编写智能合约

我们的目标是创建一个简单的“存储合约”,允许用户存储和获取一个字符串。

  1. contracts 目录下创建一个新的 Solidity 文件,Storage.sol

  2. 编写以下合约代码:

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    /**
     * @title Storage
     * @dev 一个简单的存储合约,允许用户存储和检索一个字符串。
     */
    contract Storage {
        string private storedData;
        event DataStored(string newData);
        /**
         * @dev 存储一个字符串。
         * @param _data 要存储的字符串。
         */
        function set(string memory _data) public {
            storedData = _data;
            emit DataStored(_data);
        }
        /**
         * @dev 获取存储的字符串。
         * @return 存储的字符串。
         */
        function get() public view returns (string memory) {
            return storedData;
        }
    }

编译智能合约

在终端中,确保你位于项目根目录,运行以下命令编译合约:

truffle compile

如果成功,你会在 随机配图

de>build/contracts 目录下看到编译后的合约 JSON 文件,其中包含合约的 ABI(应用程序二进制接口)和字节码。

编写部署脚本

  1. migrations 目录下创建一个新的迁移脚本文件,2_deploy_storage.js

  2. 编写以下部署代码:

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

部署到本地 Ganache 网络

  1. 确保你的 Ganache 已经启动并运行。
  2. truffle-config.js 中,确保已经配置了本地开发网络,默认情况下,Truffle 会自动检测 Ganache,如果没有,你需要手动添加网络配置:
    module.exports = {
      // ... 其他配置
      networks: {
        development: {
          host: "127.0.0.1",     // Localhost (default: none)
          port: 7545,            // Standard Ethereum port (default: none)
          network_id: "*",       // Any network (default: none)
        },
      },
      // ... 其他配置
    };
  3. 部署合约到本地网络:
    truffle migrate --network development

    如果成功,你会在终端看到部署的合约地址,Ganache 的交易列表中会显示相应的部署交易。

创建前端界面与智能合约交互

  1. 在项目根目录下创建一个 src 文件夹,用于存放前端代码。

  2. src 文件夹下创建 index.htmlapp.js

  3. index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>以太坊存储DApp</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            input, button { padding: 8px; margin: 5px; }
            #result { margin-top: 10px; font-weight: bold; }
        </style>
    </head>
    <body>
        <h1>以太坊存储DApp</h1>
        <div>
            <input type="text" id="dataInput" placeholder="输入要存储的数据">
            <button onclick="setData()">存储数据</button>
        </div>
        <div>
            <button onclick="getData()">获取数据</button>
            <div id="result">结果将显示在这里...</div>
        </div>
        <script src="app.js"></script>
    </body>
    </html>
  4. app.js:

    // 引入 Web3 库 (假设通过 CDN 引入)
    // 在实际项目中,你可以使用 npm install web3
    if (typeof web3 !== 'undefined') {
        web3 = new Web3(web3.currentProvider);
    } else {
        // 如果没有 MetaMask,则连接到本地 Ganache
        web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545"));
    }
    // 合约地址和 ABI (从 build/contracts/Storage.json 复制)
    const contractAddress = '0x...'; // 替换为你的部署合约地址
    const contractABI = [
        // 从 build/contracts/Storage.json 中复制 ABI 数组
        // 
        // {
        //     "constant": false,
        //     "inputs": [
        //         {
        //             "name": "_data",
        //             "type": "string"
        //         }
        //     ],
        //     "name": "set",
        //     "outputs": [],
        //     "payable": false,
        //     "stateMutability": "nonpayable",
        //     "type": "function"
        // },
        // {
        //     "constant": true,
        //     "inputs": [],
        //     "name": "get",
        //     "outputs": [
        //         {
        //             "name": "",
        //             "type": "string"
        //         }
        //     ],
        //     "payable": false,
        //     "stateMutability": "view",
        //     "type": "function"
        // }
    ];
    // 创建合约实例
    const storageContract = new web3.eth.Contract(contractABI, contractAddress);
    // 获取当前账户
    let currentAccount;
    web3.eth.getAccounts().then(accounts => {
        currentAccount = accounts[0];
        console.log("当前账户:", currentAccount);
    });
    // 存储数据
    async function setData() {
        const dataInput = document.getElementById('dataInput').value;
        if (!dataInput) {
            alert("请输入数据!");
            return;
        }
        try {
            await storageContract.methods.set(dataInput).send({ from: currentAccount });
            alert("数据存储成功!");
            document.getElementById('dataInput').value = "";
        } catch (error) {
            console.error("存储数据失败:", error);
            alert("存储数据失败:" + error.message);
        }
    }
    // 获取数据
    async function getData() {
        try {
            const result = await storageContract.methods.get().call();
            document.getElementById('result').innerText = "存储的数据:

本文由用户投稿上传,若侵权请提供版权资料并联系删除!

热门文章