常常听到“公链拥堵、手续费飙升”,却苦于没有可控环境做深度测试?从零构建以太坊私有链,可以在本地或内网独立运行一条与主网逻辑一致的区块链:挖矿秒级确认、手续费为零、数据库随时回滚,DApp调试或企业链改都更安全高效。本文用一台 Ubuntu 主机为示例,手把手带你完成环境准备、节点启动、创世区块定制、多节点互联,并最终部署一个可查询票据信息的智能合约。关键操作均附带命令行截图级细节,复制粘贴即可复现。
环境清单与前置检查
| 要素 | 推荐配置 |
|---|---|
| 操作系统 | Ubuntu 16.04/18.04 |
| CPU & 内存 | 双核 2 G 以上 |
| Go-Ethereum | 1.8.1-stable 及以上 |
| Node.js & npm | 用于安装 solc 编译器 |
低于 2 G 内存仍能运行,但挖矿时会出现 out-of-memory,性能测试会失真,强烈建议一步到位。
快速安装 Geth 客户端
打开终端,复制下列命令一次性完成:
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum安装结束后运行 geth -h,正常会弹出几十行帮助文档,ethereum 与 geth 命令就已就绪。
三分钟启动私链(dev 模式)
1. 创建数据目录
mkdir privatechain && cd privatechain2. 一键脚本 init.sh
nano init.sh填入内容(按环境把 --rpcaddr 改成你自己的内网 IP):
#!/bin/bash
geth --networkid 123 --dev --datadir data \
--rpc --rpcaddr 0.0.0.0 --rpcport 8545 --port 30303 \
--nodiscover --allow-insecure-unlock consolechmod +x init.sh
./init.sh你会看到类似:
INFO [xx-xx|xx:xx:xx] HTTP endpoint opened: http://0.0.0.0:8545自此 JSON-RPC 已就绪,MetaMask 或在 Remix 里选择 Web3 Provider 即可直接连。
3. 连接控制台
重开一个终端,输入:
geth attach ipc:./data/geth.ipc出现 > 提示即进入交互式 JavaScript 环境,可执行 eth, personal, miner 等 API。
核心交互速查表
| 任务 | 命令 |
|---|---|
| 新建账户 | personal.newAccount("密码") |
| 查看所有账户 | eth.accounts |
| 查询余额 | eth.getBalance(eth.accounts[0]) |
| 解锁账户发币 | personal.unlockAccount(eth.accounts[0]) |
| 单笔转账 | eth.sendTransaction({from:..., to:..., value:...}) |
| 开始/停止挖矿 | miner.start(); miner.stop() |
| 查看交易收据 | eth.getTransactionReceipt(txHash) |
用 Mist 钱包所见即所得
Mist(又称 Ethereum Wallet)既可发交易又可可视化部署合约:
# 根据实际路径调整
/path/to/mist --rpc ./data/geth.ipc首次打开可能会显示“No accounts”,前往控制台执行 personal.newAccount() 即可同步出现。
动手写第一个智能合约
下面示例合约完成“票据 Ticket”的链上增删改查,兼具转账功能,可在 DAO 项目、供应链金融等多种场景落地。
pragma solidity ^0.5.4;
contract SimpleTicket {
uint public ticketIndex;
mapping(uint => Ticket) public tickets;
struct Ticket {
uint id;
string name;
string content;
address issuer;
}
function addTicket(string memory _name, string memory _content) public {
ticketIndex += 1;
tickets[ticketIndex] = Ticket(ticketIndex, _name, _content, msg.sender);
}
function getTicket(uint _id) public view returns(uint, string memory, address) {
Ticket memory t = tickets[_id];
return (t.id, t.name, t.issuer);
}
}命令行编译 + 部署全流程
安装编译器后,依次执行:
npm install -g solc
solcjs --bin --abi SimpleTicket.sol复制 .bin 与 .abi 文件内容后,回到 Geth 控制台:
var bytecode = "0x6080..."; // 粘贴二进制
var abi = [/* 粘贴 ABI */];
var myContract = web3.eth.contract(abi);
var estimate = web3.eth.estimateGas({data: bytecode});
personal.unlockAccount(eth.coinbase);
var contractInstance = myContract.new({from: eth.coinbase, data: bytecode, gas: estimate + 50000});记下 contractInstance.transactionHash 并挖矿确认:
miner.start(1); // 单线程挖矿
// 等待数次出块
miner.stop();
// 确认结果
eth.getTransactionReceipt('上述 txHash').contractAddress成功后即可调用:
var ticket = myContract.at('合约地址');
ticket.addTicket('Invoice-001', 'Content demo', {from: eth.accounts[0], gas: 200000});
ticket.getTicket.call(1);多节点互连与持久化网络
1. 同一台机器启动两个节点
# 数据目录、端口均不冲突
geth --networkid 123 --datadir data2 --port 30304 --rpcport 8546 console在新窗口查看本节点信息并邀请对端:
> admin.nodeInfo.enode
"enode://[email protected]:30304"
# 在另一个节点中执行:
admin.addPeer("enode://[email protected]:30304")体验 net.peerCount、admin.peers 看连接状态。
2. 使用 genesis.json 初始化创世区块
创建 genesis.json:
{
"config": {
"chainId": 2025,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc": {
"0xbC9a3eCe02d7cb31Cf63DFDFc48dB0b82770d014": { "balance": "300000000000000000000" },
"0x457e7D69FD3AC576aa744228e6B3319CDE768473": { "balance": "400000000000000000000" }
},
"difficulty": "0x20000",
"gasLimit": "0x7A1200"
}执行:
geth init genesis.json --datadir data-custom
geth --networkid 123 --datadir data-custom console预置账户余额即刻生效,便于开发期免挖矿发交易。
FAQ:私有链实战常见疑惑
Q1:RPC 端口已开,外部仍连不上?
A:9090 以上端口可能受限于防火墙或安全组,确保云主机已放行对应 UDP/TCP,且 --rpcaddr 0.0.0.0 参数已启用。
Q2:estimateGas 返回的 gas 值为何总比实际小?
A:合约构造器或存储写入会额外消耗 gas,一般上浮 10%–20% 即可避免 out of gas。
Q3:Mist 无法显示合约函数?
A:合约版本需与 Mist 内置的 solidity 编译器一致;或直接在 Remix 切到“Injected Web3”方式远程调用。
Q4:想一键重置区块链怎么办?
A:删除 --datadir 指定的整个文件夹,重新 geth init 即清空全部历史,无需重新安装。
Q5:如何在同一局域网内让 A、B 两台电脑互通?
A:确保 --networkid 相同,A 把自己 enode://...@LAN_IP:PORT 通过 admin.addPeer 在 B 添加即可;若仍失败,检查路由是否屏蔽 30303/UDP。
进阶路径与资源延伸
到这里你已掌握:
- 独立节点、多节点互联、持久化创世配置
- JavaScript 控制台、Mist 钱包、Remix 三种交互方式
- Solidity 编译、字节码 + ABI 部署、函数调用全流程
接下来你可以:
- 将 Ganache 换成 Geth + PoA Clique,实现 5 秒出块。
- 使用 web3.js 在浏览器里发交易,前端直接调用私链。
- 引入 Docker 与 docker-compose,一条命令启动“节点 + 浏览器 + 后端”完整开发栈。
👉 24 小时内学会定制共识机制并迁移到私有链的完整图文教程
关键词:以太坊私有链、以太坊私网、geth 安装、智能合约部署、区块链 DApp 实战、创世区块配置