:2026-03-13 18:39 点击:1
在区块链世界中,以太坊作为最成熟的智能合约平台,让开发者能够通过代码创建自动执行的信任机制,无论是发行代币、构建去中心化应用(DApp),还是设计金融协议,智能合约都是核心载体,以太坊合约究竟怎么设置?本文将从开发环境搭建、合约编写、编译部署到交互测试,带你一步步掌握智能合约的完整设置流程。
在编写智能合约前,需要先准备好必要的开发工具,这些工具如同“工坊里的锤子与锯子”,能让你高效、安全地构建合约。
智能合约开发离不开JavaScript生态,而Node.js是运行JavaScript代码的环境,npm(Node Package Manager)则是包管理工具。
node -v和npm -v,若显示版本号则安装成功。Solidity是以太坊智能合约的编程语言,类似于JavaScript,但专为区块链设计,我们需要安装Solc来将Solidity代码编译成以太坊虚拟机(EVM)可执行的字节码。
npm install -g solc,安装完成后输入solcjs --version验证。 npm install solc安装项目本地版本,避免不同环境编译器版本不一致的问题。Hardhat是以太坊开发中最流行的框架之一,它提供了编译、测试、调试、部署等一站式工具链,能极大简化开发流程。
mkdir my-contract && cd my-contract,初始化npm项目:npm init -y。 npm install --save-dev hardhat。 npx hardhat,选择“Create a basic sample project”(创建基础示例项目),按提示操作即可生成包含合约、测试脚本等基础结构的目录。npm install -g ganache安装命令行版本。 智能合约的本质是一段部署在以太坊上的代码,定义了参与者之间的权利与义务,下面以一个简单的“投票合约”为例,讲解Solidity合约的编写。
在Hardhat项目中,合约文件通常存放在contracts/目录下,创建contracts/Voting.sol文件,文件名需与合约名一致(非强制,但推荐)。
// SPDX-License-Identifier: MIT // 指定许可证标识,避免法律风险
pragma solidity ^0.8.20; // 指定Solidity版本,^表示兼容0.8.x及更高版本(不包含0.9.0)
/**Voting 投票合约
* @dev 实现候选人注册、投票、查询投票结果功能
*/
contract Voting {
// 定义候选人结构体,包含姓名和得票数
struct Candidate {
string name;
uint256 voteCount;
}
// 状态变量:存储候选人列表(地址到候选人的映射)
mapping(address => Candidate) public candidates;
// 状态变量:存储已投票的地址(避免重复投票)
mapping(address => bool) public hasVoted;
// 状态变量:投票截止时间
uint256 public votingDeadline;
// 事件:投票时触发,方便前端监听
event Voted(address indexed voter, address indexed candidate);
// 构造函数:合约部署时执行,初始化候选人列表和截止时间
constructor(string[] memory candidateNames) {
uint256 deadline = block.timestamp + 7 days; // 设置投票截止时间为7天后
votingDeadline = deadline;
for (uint256 i = 0; i < candidateNames.length; i++) {
address candidateAddress = address(uint160(uint256(keccak256(abi.encodePacked(candidateNames[i])))));
candidates[candidateAddress] = Candidate({
name: candidateNames[i],
voteCount: 0
});
}
}
// 投票函数:为指定候选人投票
function vote(address candidateAddress) public {
require(block.timestamp < votingDeadline, "Voting has ended"); // 检查投票是否已截止
require(!hasVoted[msg.sender], "You have already voted"); // 检查是否已投票
require(candidates[candidateAddress].name != "", "Invalid candidate"); // 检查候选人是否存在
hasVoted[msg.sender] = true; // 标记已投票
candidates[candidateAddress].voteCount += 1; // 候选人得票数+1
emit Voted(msg.sender, candidateAddress); // 触发投票事件
}
// 获取候选人信息
function getCa
ndidate(address candidateAddress) public view returns (string memory name, uint256 voteCount) {
return (candidates[candidateAddress].name, candidates[candidateAddress].voteCount);
}
}
pragma solidity ^0.8.20:指定Solidity版本,不同版本语法差异较大,需明确版本。 candidates、hasVoted,每个节点都会备份。 require()用于检查条件,不满足时 revert(回滚交易);public表示函数可被外部调用。 Voted事件可在投票时触发。 Solidity代码需要编译成EVM能识别的字节码(Bytecode)和ABI(Application Binary Interface,应用程序二进制接口),才能部署到以太坊网络。
在Hardhat项目中,打开终端运行:
npx hardhat compile
首次运行会自动安装依赖(如@nomicfoundation/hardhat-toolbox),编译成功后,会在artifacts/contracts/目录下生成Voting.json文件,其中包含:
bytecode:合约的字节码,部署时发送给EVM。 abi:合约的接口描述,包含函数签名、参数类型等,前端通过abi与合约交互。 若编译失败,Hardhat会提示错误原因,常见问题包括:
uint256与uint32混用); 编译成功后,即可将合约部署到以太坊网络,部署的本质是将合约的bytecode发送到区块链,并由网络中的节点执行,生成合约地址。
Hardhat默认使用scripts/deploy.js作为部署脚本,编辑该文件,编写部署逻辑:
const { ethers } = require("hardhat");
async function main() {
// 获取部署者账户(默认为Hardhat Network的第0个账户)
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
// 定义候选人列表
const candidateNames = ["Alice", "Bob", "Charlie"];
// 部署Voting合约
const Voting = await ethers.getContractFactory("Voting");
const voting = await Voting.deploy(candidateNames);
await voting.waitForDeployment(); // 等待部署完成
// 输出合约地址
console.log("Voting contract deployed to:", await voting.getAddress());
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Hardhat支持多种网络
本文由用户投稿上传,若侵权请提供版权资料并联系删除!