以太坊作为全球领先的智能合约平台,不仅仅是一种加密货币,更是一个去中心化的应用(Dapp)生态系统,它允许开发者通过编写智能合约,在区块链上创建各种不可篡改、自动执行的应用程序,本教程将带你从零开始,逐步了解并掌握以太坊智能合约的编写过程。
为什么选择以太坊编写智能合约?

在开始之前,我们首先要明白为什么以太坊是编写智能合约的热门选择:
准备工作:开发环境搭建
在开始编写智能合约之前,你需要准备以下开发环境:
代码编辑器:
Node.js 和 npm/yarn:
npm install -g yarn)。以太坊客户端/开发框架:
MetaMask 钱包:
你的第一个智能合约:一个简单的投票合约

让我们通过编写一个简单的投票合约来入门。
创建Hardhat项目: 打开终端,运行以下命令:
mkdir hardhat-vote-demo cd hardhat-vote-demo npm init -y npm install --save-dev hardhat npx hardhat
在交互式界面中,选择 "Create a JavaScript project"(或其他你熟悉的语言,如TypeScript),然后一路回车使用默认配置(或根据需要修改)。
编写智能合约: Hardhat会创建一个 contracts 目录,在此目录下创建一个新文件 Vote.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract Vote {
// 定义候选人结构体
struct Candidate {
string name;
uint256 voteCount;
}
// 存储候选人数组
Candidate[] public candidates;
// 存储投票地址,防止重复投票
mapping(address => bool) public hasVoted;
// 构造函数,初始化候选人
constructor(string[] memory candidateNames) {
for (uint i = 0; i < candidateNames.length; i ) {
candidates.push(Candidate({
name: candidateNames[i],
voteCount: 0
}));
}
}
// 投票函数
function vote(uint256 candidateIndex) public {
require(!hasVoted[msg.sender], "You have already voted.");
require(candidateIndex < candidates.length, "Invalid candidate index.");
hasVoted[msg.sender] = true;
candidates[candidateIndex].voteCount ;
}
// 获取候选人数量
function getCandidatesCount() public view returns (uint256) {
return candidates.length;
}
// 获取候选人信息
function getCandidate(uint256 index) public view returns (string memory, uint256) {
require(index < candidates.length, "Invalid candidate index.");
return (candidates[index].name, candidates[index].voteCount);
}
} 理解合约代码:
SPDX-License-Identifier 和 pragma solidity:许可证和Solidity版本声明。contract Vote:定义名为 Vote 的智能合约。struct Candidate:定义候选人结构体,包含名字和票数。Candidate[] public candidates:动态数组存储所有候选人。mapping(address => bool) public hasVoted:映射记录每个地址是否已投票。constructor:合约部署时执行的构造函数,用于初始化候选人列表。vote(uint256 candidateIndex):投票函数,检查投票资格后增加对应候选人的票数。getCandidatesCount() 和 getCandidate(uint256 index):视图函数,用于查询候选人数和具体候选人信息。编译合约: 在终端中运行:
npx hardhat compile
如果编译成功,Hardhat会在 artifacts 目录下生成编译后的合约字节码和ABI(Application Binary Interface)。
测试你的智能合约

测试是确保智能合约正确性的关键步骤。
编写测试脚本: 在 test 目录下创建 vote.test.js 文件(如果使用TypeScript,则是 .ts):
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Vote Contract", function () {
it("Should allow voting and tally votes correctly", async function () {
// 获取签名者
const [owner, addr1, addr2] = await ethers.getSigners();
// 部署合约
const Vote = await ethers.getContractFactory("Vote");
const voteContract = await Vote.deploy(["Alice", "Bob"]);
await voteContract.deployed();
// 初始票数应为0
expect(await voteContract.getCandidate(0)).to.deep.equal(["Alice", 0]);
expect(await voteContract.getCandidate(1)).to.deep.equal(["Bob", 0]);
// addr1投票给Alice (index 0)
await voteContract.connect(addr1).vote(0);
expect(await voteContract.getCandidate(0)).to.deep.equal(["Alice", 1]);
expect(await voteContract.hasVoted(addr1.address)).to.equal(true);
// addr2投票给Bob (index 1)
await voteContract.connect(addr2).vote(1);
expect(await voteContract.getCandidate(1)).to.deep.equal(["Bob", 1]);
// addr1不能重复投票
await expect(voteContract.connect(addr1).vote(1)).to.be.revertedWith(
"You have already voted."
);
// 投票给无效候选人index应revert
await expect(voteContract.connect(owner).vote(2)).to.be.revertedWith(
"Invalid candidate index."
);
});
}); 运行测试: 在终端中运行:
npx hardhat test
如果所有测试通过,说明你的合约逻辑基本正确。
部署合约到测试网
为了在真实的以太坊环境中测试你的合约,你需要部署到测试网(如Ropsten, Goerli, Sepolia)。
获取测试ETH: 从测试网水龙头获取免费的测试ETH,例如Goerli测试网的 faucet。
配置Hardhat网络: 在 hardhat.config.js 中添加测试网配置(以Goerli为例,你需要安装 @nomicfoundation/hardhat-network 和 @nomicfoundation/hardhat-ethers,以及 dotenv 来管理环境变量):
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const GOERLI_URL = process.env.GOERLI_URL;
module.exports = {
solidity: "0.8.9",
networks: {
goerli: {
url: GOERLI_URL,
accounts: [PRIVATE_KEY],
},
},
}; 在项目根目录创建 .env 文件,填入你的私钥(从MetaMask导出,注意安全!)和Goerli RPC URL(可以从 [Infura](https://
免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com