关键词:以太坊私有链、智能合约部署、geth、Solidity 编译、合约调用
背景与目标
很多朋友在学习区块链开发时,常因高昂的主网 Gas 费用而却步。搭建一条本地以太坊私有链,不仅能零成本实验,还能完整体验从节点初始化到智能合约上线的全流程。本文将手把手带你完成:
- 源码获取与可执行文件编译
- 自定义初始状态(genesis 配置)
- 节点启动与账户创建
- 私有链挖矿与 ETH 转账
- Solidity 合约编写、编译、部署及交互
第一步:获取和编译 Geth
1.1 克隆源码
git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum1.2 编译
make geth完成后把 ./build/bin/geth 加入 PATH:
export PATH=$PWD/build/bin:$PATHTip:在 macOS + Homebrew 环境遇到clang报错时,执行xcode-select --install即可解决依赖缺失。
第二步:设计私有链初始状态
创建 genesis.json,指定链 ID 及创世区块参数:
{
"config": {
"chainId": 7777,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"ethash": {}
},
"difficulty": "1",
"gasLimit": "8000000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
}
}参数说明:
- chainId 必须唯一,避免与主网/测试网冲突。
- difficulty 置
1方便 CPU 单线程挖矿。 - gasLimit 足够大,防止测试合约 Gas 不足。
初始化数据目录
geth init --datadir data genesis.json第三步:启动节点并进入交互式控制台
geth --datadir data --nodiscover --mine console--nodiscover:关闭 P2P 自动发现,确保纯粹私有链。--mine:默认就开启挖矿,为交易快速出块。
在控制台中,可使用 JavaScript API 进行后续操作。
常见问题 FAQ
Q1: 控制台提示端口 30303 被占用?
本地若同时运行多条链或主网节点,可添加参数 --port 30304。
Q2: Linux 运行 geth 报 “permission denied”?
chmod +x build/bin/geth 赋予执行权限即可。
第四步:创建账户与快速挖矿
4.1 新建账户
> personal.newAccount()
Passphrase:
"0x45281eb7bbaa41fef62d40ae881378c14335c1cf"4.2 挖矿与收获 196 ETH
> miner.start()
// 等待 2–3 分钟
> miner.stop()
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
1964.3 在账户间转账
先解锁发送账户:
> personal.unlockAccount(eth.accounts[0])
> eth.sendTransaction({
from: eth.accounts[0],
to: eth.accounts[1],
value: web3.toWei(10, 'ether')
})再挖一个块以打包交易:
> miner.start(1); admin.sleepBlocks(1); miner.stop()验证接收方余额:
> web3.fromWei(eth.getBalance(eth.accounts[1]), 'ether')
10第五步:用 Solidity 编写首个智能合约
创建 demo.sol:
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}第六步:编译合约并拿到 ABI 与字节码
安装 Solidity 编译器:
npm install -g solc执行编译:
solc --optimize --combined-json abi,bin demo.sol > compiled.json在控制台中导入结果:
var compiled = JSON.parse(cat("compiled.json"));
var abi = compiled.contracts["demo.sol:SimpleStorage"].abi;
var bin = "0x" + compiled.contracts["demo.sol:SimpleStorage"].bin;第七步:部署合约到私有链
7.1 创建合约对象
var storageContract = eth.contract(abi);
var deployTx = { from: eth.accounts[0], data: bin, gas: 1000000 };7.2 部署
var instance = storageContract.new(deployTx);此时通过 txpool.status 可见 1 笔待处理交易。继续快速挖块:
> miner.start(1); admin.sleepBlocks(1); miner.stop()获取合约地址:
var receipt = eth.getTransactionReceipt(instance.transactionHash);
var contractAddress = receipt.contractAddress;
console.log("合约地址: " + contractAddress);第八步:与合约互动
8.1 读取初始状态
var contract = storageContract.at(contractAddress);
contract.get.call(); // 返回 08.2 写入新数值并上链
contract.set.sendTransaction(77, {
from: eth.accounts[0],
gas: 1000000
});
// 再次挖矿确认交易
> miner.start(1); admin.sleepBlocks(1); miner.stop()8.3 验证结果
contract.get.call(); // 已变为 77安全与维护小贴士
- 私钥备份
data/keystore文件夹内 JSON 文件即为加密私钥,务必离线备份、且密码牢记。 - 重复测试脚本化
使用 Node.js 脚本 + web3.js 可一键复现以上步骤,减少手动交互中的拼写错误。 - 资源回收
测试完毕后,rm -rf data即可重置链数据;如需克隆环境,复制genesis.json重新初始化即可。
附录:术语速查
- Genesis Block:链的创世块,配置错误将导致节点永远无法同步。
- Gas & GasPrice:私有链能将 GasPrice 设为 0,但调大 GasLimit 可避免合约部署失败。
- ABI:Application Binary Interface,描述如何与已部署的字节码交互。
常见问题汇总
Q3:编译时报 “Warning: SPDX license identifier not provided”?
A:在文件头加 // SPDX-License-Identifier: UNLICENSED 即可消除警告,不影响功能。
Q4:合约部署卡在 pending?
A:确认节点确实在挖矿;若使用 miner.start() 需再调用 admin.sleepBlocks(1) 等它挖出新区块。
Q5:Mac M1 芯片编译失败?
A:使用 Go 1.17+ 版本,并确保 XCode Command Line Tools 已正确安装。
Q6:能否一条命令把所有步骤跑完?
A:将以上流程做成一条 Bash 脚本,配合 expect 自动输入口令即可实现一键私有链沙箱。