从零开始:以太坊私有链搭建与智能合约部署全指南

·

关键词:以太坊私有链、智能合约部署、geth、Solidity 编译、合约调用

背景与目标

很多朋友在学习区块链开发时,常因高昂的主网 Gas 费用而却步。搭建一条本地以太坊私有链,不仅能零成本实验,还能完整体验从节点初始化到智能合约上线的全流程。本文将手把手带你完成:

  1. 源码获取与可执行文件编译
  2. 自定义初始状态(genesis 配置)
  3. 节点启动与账户创建
  4. 私有链挖矿与 ETH 转账
  5. Solidity 合约编写、编译、部署及交互

👉 点此跳出阅读疲劳,直抵完整源码仓库快照


第一步:获取和编译 Geth

1.1 克隆源码

git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum

1.2 编译

make geth

完成后把 ./build/bin/geth 加入 PATH

export PATH=$PWD/build/bin:$PATH
Tip:在 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" }
  }
}

参数说明:

初始化数据目录

geth init --datadir data genesis.json

第三步:启动节点并进入交互式控制台

geth --datadir data --nodiscover --mine console

在控制台中,可使用 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")
196

4.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(); // 返回 0

8.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

安全与维护小贴士

  1. 私钥备份
    data/keystore 文件夹内 JSON 文件即为加密私钥,务必离线备份、且密码牢记。
  2. 重复测试脚本化
    使用 Node.js 脚本 + web3.js 可一键复现以上步骤,减少手动交互中的拼写错误。
  3. 资源回收
    测试完毕后,rm -rf data 即可重置链数据;如需克隆环境,复制 genesis.json 重新初始化即可。

附录:术语速查


常见问题汇总

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 自动输入口令即可实现一键私有链沙箱。