从零开始构建你的第一个以太坊智能合约Demo,入门与实践指南

 :2026-02-16 4:36    点击:8  

以太坊,作为区块链2.0的杰出代表,不仅仅是一种加密货币,更是一个去中心化的应用平台,其核心魅力在于智能合约——一种运行在以太坊虚拟机(EVM)上,能够自动执行合约条款的计算机程序,对于想要踏入区块链开发领域的新手来说,亲手编写并部署一个以太坊智能合约Demo,是理解其工作原理的最佳途径,本文将带你一步步完成这个过程。

什么是智能合约?

智能合约是一种“那么”(If-This-Then-That)式的自动化协议,它被部署在区块链上,一旦预设的条件被触发,合约就会自动执行约定的操作,且整个过程透明、不可篡改,以太坊智能合约通常使用Solidity语言编写。

为何需要一个Demo?

一个Demo(演示程序)能够将抽象的概念具体化,通过构建一个简单的Demo,你可以:

  1. 理解核心概念:如账户、地址、余额、交易、Gas等。
  2. 熟悉开发流程:从环境搭建、合约编写、编译、部署到与合约交互。
  3. 获得实践经验随机配图
g>:理论知识结合动手实践,印象更深刻。
  • 建立开发信心:完成第一个Demo后,你将有能力探索更复杂的智能合约应用。
  • 我们的Demo目标:一个简单的“投票”合约

    为了演示智能合约的基本功能,我们将创建一个简单的投票合约,这个合约将允许:

    • 创建者(合约部署者)添加多个投票选项。
    • 地址(每个地址限一次)可以对其中一个选项进行投票。
    • 查询各选项的当前得票数。

    构建Demo前的准备:开发环境搭建

    在开始编写合约之前,你需要准备以下工具和环境:

    1. MetaMask钱包:一个浏览器插件钱包,用于管理你的以太坊账户、私钥,并与以太坊网络交互,从MetaMask官网下载并安装,创建一个新钱包并妥善保存助记词。
    2. 以太坊测试网ETH:为了在测试网络上部署和交互合约,你需要免费的测试网ETH,你可以从水龙头(Faucet)网站获取,如Sepolia测试网的Faucet。
    3. VS Code:一个流行的代码编辑器,建议安装Solidity插件,它提供语法高亮、代码提示等功能。
    4. Hardhat:一个流行的以太坊开发环境,用于编译、测试、部署智能合约,它提供了强大的插件系统和调试功能。
      • 安装Node.js和npm(或yarn)。
      • 在终端中运行 npx hardhat 初始化一个新的Hardhat项目。

    编写智能合约(Solidity)

    在Hardhat项目中,你会在 contracts/ 目录下找到 Lock.sol 文件(默认模板),我们可以将其重命名并修改为 Voting.sol,然后编写如下代码:

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    contract Voting {
        // 定义一个投票选项的结构体
        struct Candidate {
            string name;
            uint256 voteCount;
        }
        // 存储投票选项的映射,选项名称到Candidate结构体
        mapping(string => Candidate) public candidates;
        // 存储地址是否已投票的映射,防止重复投票
        mapping(address => bool) public hasVoted;
        // 投票选项的数组
        string[] public candidateNames;
        // 构造函数,在部署合约时调用,用于初始化投票选项
        constructor(string[] memory _candidateNames) {
            candidateNames = _candidateNames;
            for (uint i = 0; i < _candidateNames.length; i++) {
                candidates[_candidateNames[i]] = Candidate({
                    name: _candidateNames[i],
                    voteCount: 0
                });
            }
        }
        // 投票函数
        function vote(string memory candidateName) public {
            // 检查投票者是否已经投过票
            require(!hasVoted[msg.sender], "You have already voted.");
            // 检查候选选项是否存在
            require(bytes(candidates[candidateName].name).length > 0, "Candidate does not exist.");
            // 记录投票
            hasVoted[msg.sender] = true;
            candidates[candidateName].voteCount += 1;
        }
        // 获取候选人的得票数
        function getVoteCount(string memory candidateName) public view returns (uint256) {
            return candidates[candidateName].voteCount;
        }
        // 获取所有候选人的名称
        function getCandidateNames() public view returns (string[] memory) {
            return candidateNames;
        }
    }

    代码解释:

    • SPDX-License-Identifierpragma solidity:Solidity合约的标准头部信息,指定许可证和编译器版本。
    • contract Voting:定义了一个名为 Voting 的智能合约。
    • struct Candidate:定义了候选人结构体,包含名字和得票数。
    • mapping(string => Candidate) public candidates:一个映射,通过选项名称快速找到对应的候选人信息,并设为 public 以便区块链浏览器访问。
    • mapping(address => bool) public hasVoted:记录每个地址是否已投票。
    • string[] public candidateNames:存储所有候选选项名称的数组。
    • constructor:合约部署时执行的构造函数,用于初始化候选人列表。
    • vote(string memory candidateName):核心投票函数,包含权限检查(是否已投票、候选人是否存在),然后更新投票状态和得票数。
    • getVoteCountgetCandidateNames:查询函数,分别获取特定候选人的得票数和所有候选人名称。

    编译与部署合约

    1. 编译合约: 在Hardhat项目根目录的终端中运行:

      npx hardhat compile

      如果成功,你会在 artifacts/contracts/ 目录下看到编译后的合约文件(如 Voting.json)。

    2. 编写部署脚本: 在 scripts/ 目录下,创建一个新的部署脚本,deploy.js

      async function main() {
        // 获取合约工厂
        const Voting = await ethers.getContractFactory("Voting");
        // 部署合约,这里我们传入几个候选人名称作为示例
        const candidateNames = ["Alice", "Bob", "Charlie"];
        const voting = await Voting.deploy(candidateNames);
        // 等待合约部署完成
        await voting.deployed();
        console.log("Voting contract deployed to:", voting.address);
      }
      main()
        .then(() => process.exit(0))
        .catch((error) => {
          console.error(error);
          process.exit(1);
        });
    3. 配置网络: 在 hardhat.config.js 文件中,你需要配置你想要部署到的测试网(如Sepolia),你需要安装 @nomicfoundation/hardhat-toolbox 插件,并配置你的MetaMask私钥(注意:不要将私钥提交到代码仓库,建议使用环境变量)。

      require("@nomicfoundation/hardhat-toolbox");
      require('dotenv').config(); // 引入dotenv包来管理环境变量
      /** @type import('hardhat/config').HardhatUserConfig */
      module.exports = {
        solidity: "0.8.20",
        networks: {
          sepolia: {
            url: process.env.SEPOLIA_URL, // 从.env文件中获取
            accounts: [process.env.PRIVATE_KEY] // 从.env文件中获取
          }
        },
        etherscan: {
          apiKey: process.env.ETHERSCAN_API_KEY // 可选,用于验证合约
        }
      };

      创建 .env 文件,并添加你的测试网RPC URL(可以从Alchemy或Infura获取)和MetaMask私钥。

    4. 部署合约: 确保你的MetaMask钱包连接到了正确的测试网(如Sepolia Test Network),并且有足够的测试ETH。 在终端中运行部署脚本:

      npx hardhat run scripts/deploy.js --network sepolia

      部署成功后,终端会输出合约的地址,复制这个地址,你可以在以太坊测试网浏览器(如 Sepolia Etherscan)上查看你的合约。

    与智能合约交互

    1. 使用Ethers.js: 你可以编写一个简单的Node.js脚本或前端应用(如使用React + Ethers.js)来调用合约的方法。 创建一个 interact.js 脚本:

      const hre = require("hardhat");
      async function main() {
        // 替换为你的合约地址
        const contractAddress = "YOUR_CONTRACT_ADDRESS_HERE";
        // 获取合约实例
        const Voting = await hre.ethers.getContractFactory("Voting");
        const voting = await Voting.attach

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