以太坊,作为全球最大的去中心化应用(DApp)平台,其核心魅力在于智能合约,智能合约是运行在以太坊虚拟机(EVM)上的自动执行程序,它们在没有第三方干预的情况下,定义和执行合约条款,对于任何希望进入Web3世界的开发者来说,掌握智能合约的开发与部署都是一项必备的核心技能,本文将为您详细梳理从编写、测试到部署以太坊智能合约的完整流程。
开发环境准备:工欲善其事,必先利其器
在开始编码之前,我们需要搭建一个完整的开发环境,以下是几个关键工具:

以太坊,作为全球最大的去中心化应用(DApp)平台,其核心魅力在于智能合约,智能合约是运行在以太坊虚拟机(EVM)上的自动执行程序,它们在没有第三方干预的情况下,定义和执行合约条款,对于任何希望进入Web3世界的开发者来说,掌握智能合约的开发与部署都是一项必备的核心技能,本文将为您详细梳理从编写、测试到部署以太坊智能合约的完整流程。
在开始编码之前,我们需要搭建一个完整的开发环境,以下是几个关键工具:

我们将使用 Solidity 语言来编写智能合约,Solidity是一种面向合约的高级编程语言,其语法类似于JavaScript和C++。
创建项目并安装依赖:
打开终端,创建一个新的项目目录并初始化一个npm项目。
mkdir my-first-contract cd my-first-contract npm init -y npm install --save-dev hardhat
在项目目录下运行 npx hardhat,选择 "Create a basic sample project" 来快速生成一个包含示例合约的框架。
编写合约代码:
进入 contracts 目录,你会看到一个名为 Lock.sol 的示例文件,我们可以基于此进行修改,或者创建一个全新的合约,这里我们创建一个简单的 HelloWorld 合约。
打开 contracts/HelloWorld.sol,输入以下代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**HelloWorld
* @dev 一个简单的合约,用于存储和返回一条问候语。
*/
contract HelloWorld {
// 声明一个状态变量来存储字符串
string private _greeting;
// 构造函数,在合约部署时执行一次
constructor(string memory initialGreeting) {
_greeting = initialGreeting;
}
// 一个公共函数,用于获取当前的问候语
function greet() public view returns (string memory) {
return _greeting;
}
// 一个公共函数,用于更新问候语
function setGreeting(string memory newGreeting) public {
_greeting = newGreeting;
}
}
代码解析:
SPDX-License-Identifier 和 pragma solidity 是每个Solidity文件的标准头部。contract HelloWorld { ... } 定义了一个名为 HelloWorld 的智能合约。string private _greeting; 定义了一个私有状态变量,用于存储字符串。constructor 是合约的构造函数,仅在合约首次部署时调用,用于初始化状态变量。function greet() public view returns (string memory) 是一个公共函数,view 关键字表示它只会读取数据而不会修改状态,因此不会消耗Gas。function setGreeting(string memory newGreeting) public 是另一个公共函数,用于修改 _greeting 的值。代码写好后,我们需要确保它能被以太坊网络正确理解和执行。
编译合约:
Hardhat会在 hardhat.config.js 文件中配置编译选项,它会自动找到我们编写的合约并进行编译,在终端中运行:
npx hardhat compile
如果一切顺利,你会在 artifacts/contracts/ 目录下看到编译后的输出文件(如 HelloWorld.json),这些文件是EVM可以读取的二进制格式和ABI(应用程序二进制接口),ABI是与合约交互的“说明书”。
编写测试脚本:
测试是确保合约安全可靠的关键,Hardhat内置了 Mocha 和 Chai 测试框架,在 test 目录下,创建一个 hello-world.test.js 文件:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("HelloWorld", function () {
it("Should return the new greeting once set", async function () {
// 1. 部署合约
const HelloWorld = await ethers.getContractFactory("HelloWorld");
const helloWorld = await HelloWorld.deploy("Hello, initial world!");
await helloWorld.waitForDeployment();
// 2. 测试初始值
expect(await helloWorld.greet()).to.equal("Hello, initial world!");
// 3. 调用setGreeting函数并测试新值
const setGreetingTx = await helloWorld.setGreeting("Hola, mundo!");
// 等待交易被确认
await setGreetingTx.wait();
expect(await helloWorld.greet()).to.equal("Hola, mundo!");
});
});
运行测试:
在终端中执行以下命令来运行所有测试:
npx hardhat test
如果所有测试通过,恭喜你,你的合约逻辑是正确的!
在本地测试无误后,我们可以将合约部署到以太坊的测试网上,测试网是用于测试的公共区块链,其代币(如Goerli网的ETH)没有真实价值,但功能与主网完全相同。
获取测试网ETH: 在部署合约时,你需要支付Gas费,你需要从水龙头 免费获取一些测试网的ETH。
配置Hardhat连接测试网:
打开 hardhat.config.js 文件,添加测试网的配置信息,你需要使用自己的MetaMask助记词来创建一个部署账户,但切勿将主网私钥或助记词暴露在任何代码或公开环境中,这里我们使用 环境变量 来安全地管理私钥。
安装 dotenv 包:
npm install --save-dev dotenv
然后在项目根目录创建 .env 文件,填入你的测试网私钥和Alchemy(或其他节点服务商)提供的RPC URL:
PRIVATE_KEY=你的测试网私钥
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/你的Alchemy_API_KEY
修改 hardhat.config.js 文件:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.20",
networks: {
sepolia: {
url: process.env.SEPOLIA_RPC_URL,
accounts: [process.env.PRIVATE_KEY],
},
},
};
编写部署脚本:
在 scripts 目录下创建一个 deploy.js 文件:
async function main() {
// 获取合约工厂
const HelloWorld = await hre.ethers.getContractFactory("HelloWorld");
// 部署合约,传入构造函数参数
const helloWorld = await HelloWorld.deploy("Hello from Sepolia!");
await helloWorld.waitForDeployment();
// 输出合约地址
console.log(`HelloWorld contract deployed to: ${helloWorld.target}`);
}
// 执行主函数并捕获错误
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
执行部署:
在终端中运行部署脚本,并指定网络为 sepolia:
npx hardhat run scripts/deploy.js --network sepolia
如果部署成功,你将在终端看到合约的地址。请务必复制并保存这个地址,它就是你智能合约在以太坊区块链上的唯一身份。
部署到测试网后,你可以将合约源代码与地址进行关联,这样任何人都可以在像 Etherscan 或 SepoliaScan 这样的区块浏览器上查看你的合约代码,增加透明度和可信度。
大多数区块链浏览器都支持通过 Flattener 或 Standard JSON Input 方式进行验证,Hardhat有现成的插件