前言
为了与区块链进行通信,我们必须使用区块链客户端。客户端是能够与其他客户建立p2p通信信道,签署和广播交易,挖掘,部署和与智能合约交互等的软件。客户端通常被称为节点。
安装Geth
安装Geth有多种方式,这里给出两种:系统包管理器(apt-get)安装和源码安装。
一、apt-get
sudo apt-get install software-properties-common
sudo add-apt-respository -y poa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
二、源码安装
1、获取最新的软件包源,并添加至当前的apt库
add-apt-repository ppa:longsleep/golang-backports
2、更新 apt库
apt-get update
3、安装go
sudo apt-get install golang-go
4、鉴定是否安装成功
go version
5、克隆github仓库
git clone https://github.com/ethereum/go-ethereum.git
6、从源码构建Geth
cd go-ethereum
make geth
可能出现问题:
go: github.com/Azure/azure-pipeline-go@v0.2.2: Get https://proxy.golang.org/github.com/%21azure/azure-pipeline-go/@v/v0.2.2.mod: dial tcp 172.217.24.17:443: connect: connection refused make: *** [geth] Error 1
解决:
go env -w GOPROXY=https://goproxy.cn
查看geth version:
./build/bin/geth version
启动节点同步
./build/bin/geth --datadir ./data
同步模式
同步模式有三种:”fast”, “full”, or “light”
geth --syncmode "fast" --datadir DataDir
搭建自己的私有链
初始化创世块
新建一个文件genesis.json来放置创世块(第0号区块)的配置信息。
{
"config": {
"chainId": 666,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x00002",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0x1e82968C4624880FD1E8e818421841E6DB8D1Fa4" : {"balance" : "30000000000000000000"}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
- chainId 用于标记一条以太链的ID,它必须和你的代码中交易时的chainId一致。
- alloc 用来预置账号以及账上的币的数量,因为私有链开启挖矿后很简单地就能获得测试所需要的币,所以不需要预置有币的账号
- difficulty 设置挖矿难度,私有链在测试时可将该值设置小点,使得区块容易被挖出来,测试效率更高
- gasLimit GAS 的消耗量限制,用来限制区块能包含的交易信息总和
使用以下命令初始化创世块:
./build/bin/geth --datadir datadir init genesis.json
输出:
bigdata@master:~/geth/go-ethereum$ ./build/bin/geth --datadir ../data init ../genesis.json
INFO [06-30|16:56:22.680] Maximum peer count ETH=50 LES=0 total=50
INFO [06-30|16:56:22.680] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [06-30|16:56:22.681] Set global gas cap cap=25,000,000
INFO [06-30|16:56:22.681] Allocated cache and file handles database=/home/bigdata/geth/data/geth/chaindata cache=16.00MiB handles=16
INFO [06-30|16:56:22.841] Writing custom genesis block
INFO [06-30|16:56:22.841] Persisted trie from memory database nodes=0 size=0.00B time="3.146µs" gcnodes=0 gcsize=0.00B gctime=0s livenode
s=1 livesize=0.00BINFO [06-30|16:56:22.841] Successfully wrote genesis state database=chaindata hash=2615eb..374a30
INFO [06-30|16:56:22.841] Allocated cache and file handles database=/home/bigdata/geth/data/geth/lightchaindata cache=16.00MiB handles
=16INFO [06-30|16:56:22.936] Writing custom genesis block
INFO [06-30|16:56:22.936] Persisted trie from memory database nodes=0 size=0.00B time="2.612µs" gcnodes=0 gcsize=0.00B gctime=0s livenode
s=1 livesize=0.00BINFO [06-30|16:56:22.936] Successfully wrote genesis state database=lightchaindata hash=2615eb..374a30
启动私链
使用以下命令启动私链:
geth --data datadir --networkid 15
注意networdid要与创世块配置里的chainId一致。
输出:
bigdata@master:~/geth/go-ethereum$ ./build/bin/geth --datadir ../data --networkid 15
INFO [06-30|16:59:44.815] Maximum peer count ETH=50 LES=0 total=50
INFO [06-30|16:59:44.815] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [06-30|16:59:44.815] Set global gas cap cap=25,000,000
INFO [06-30|16:59:44.815] Allocated trie memory caches clean=154.00MiB dirty=256.00MiB
INFO [06-30|16:59:44.815] Allocated cache and file handles database=/home/bigdata/geth/data/geth/chaindata cache=512.00MiB handles=524
,288INFO [06-30|16:59:45.135] Opened ancient database database=/home/bigdata/geth/data/geth/chaindata/ancient readonly=false
INFO [06-30|16:59:45.135] Initialised chain configuration config="{ChainID: 15 Homestead: <nil> DAO: <nil> DAOSupport: false EIP150:
<nil> EIP155: <nil> EIP158: <nil> Byzantium: <nil> Constantinople: <nil> Petersburg: <nil> Istanbul: <nil>, Muir Glacier: <nil>, Berlin: <nil>, London: <nil>, Engine: unknown}"INFO [06-30|16:59:45.135] Disk storage enabled for ethash caches dir=/home/bigdata/geth/data/geth/ethash count=3
INFO [06-30|16:59:45.135] Disk storage enabled for ethash DAGs dir=/home/bigdata/.ethash count=2
INFO [06-30|16:59:45.135] Initialising Ethereum protocol network=15 dbversion=<nil>
INFO [06-30|16:59:45.136] Loaded most recent local header number=0 hash=2615eb..374a30 td=2000 age=52y2mo4w
INFO [06-30|16:59:45.136] Loaded most recent local full block number=0 hash=2615eb..374a30 td=2000 age=52y2mo4w
INFO [06-30|16:59:45.136] Loaded most recent local fast block number=0 hash=2615eb..374a30 td=2000 age=52y2mo4w
WARN [06-30|16:59:45.136] Failed to load snapshot, regenerating err="missing or corrupted snapshot"
INFO [06-30|16:59:45.136] Rebuilding state snapshot
INFO [06-30|16:59:45.136] Regenerated local transaction journal transactions=0 accounts=0
INFO [06-30|16:59:45.143] Allocated fast sync bloom size=512.00MiB
INFO [06-30|16:59:45.144] Initialized state bloom items=0 errorrate=0.000 elapsed="16.762µs"
INFO [06-30|16:59:45.144] Gasprice oracle is ignoring threshold set threshold=2
WARN [06-30|16:59:45.144] Error reading unclean shutdown markers error="leveldb: not found"
INFO [06-30|16:59:45.144] Starting peer-to-peer node instance=Geth/v1.10.4-unstable-c73652da-20210526/linux-amd64/go1.13.8
INFO [06-30|16:59:45.144] Resuming state snapshot generation root=56e81f..63b421 accounts=0 slots=0 storage=0.00B elapsed=8.271ms
INFO [06-30|16:59:45.144] Generated state snapshot accounts=0 slots=0 storage=0.00B elapsed=8.437ms
INFO [06-30|16:59:45.268] New local node record seq=1 id=e7b4862fffc81615 ip=127.0.0.1 udp=30303 tcp=30303
INFO [06-30|16:59:45.269] Started P2P networking self=enode://793dee3e84c5f083e28b02648c51d0ea13d1fe9dc66bc341c18c9c9f94276a
c0860743c6bceb621e0d62627b967e71bae43d160b7d3de64abb7d97a24a5704d4@127.0.0.1:30303INFO [06-30|16:59:45.271] IPC endpoint opened url=/home/bigdata/geth/data/geth.ipc
INFO [06-30|16:59:47.211] New local node record seq=2 id=e7b4862fffc81615 ip=183.233.224.164 udp=30303 tcp=30303
控制台操作
启动控制台:
geth --data datadir --networkid 15 console
一直显示looking for peer,可以在启动命令加上--nodiscover
,禁止寻找节点
退出:Ctrl+D
查看基本对象:
> web3
常用命令:
# 查看有哪些账户
> eth.acounts
# 查询账户余额
> web3.fromWei(eth.getBalance(""), 'ether')
# 查询区块
> eth.blockNumber
# 创建账户
> personal.newAccount()
Passphrase:
Repeat passphrase:
INFO [06-30|17:29:03.295] Your new key was generated address=0x085ED72FFC866da7913bD3a32630349626487d08
WARN [06-30|17:29:03.295] Please backup your key file! path=/home/bigdata/geth/data/keystore/UTC--2021-06-30T09-29-01.734622396Z--
085ed72ffc866da7913bd3a32630349626487d08WARN [06-30|17:29:03.295] Please remember your password!
"0x085ed72ffc866da7913bd3a32630349626487d08"
# 转账,交易信息需要被挖矿才算成功
> eth.sendTransaction({from: XX, to: XX ,value: XX})
# 账户默认是锁住的,想要发送交易,必须先解锁账户
> personal.unlockAccount(XX)
# 查看交易池的状态
> txpool.status
# 其中start的参数表示挖矿使用的线程数。第一次启动挖矿会先生成挖矿所需的DAG文件,这个过程有点慢,等进度达到100%后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。
> miner.start(1)
# 停止挖矿
> miner.stop()
# 查看挖到的以太币
> web3.fromWei(eth.getBalance(eth.coinbase))
# 查看区块信息
> eth.getBlock(16)
# 查看交易信息
> eth.getTransaction("0xc6a74142d2b20d48df2c61ce55d06677ea891e3f0bb4231547d21b8799a01701")
# 查看区块有多少个交易
> eth.getBlockTransactionCount(60)
在后台启动geth后,可以通过以下命令进入控制台:
nohup geth --datadir datadir --networkid 15 2>output.log &
geth attach http://localhost:8545
dev模式
使用POA共识网络,默认预分配一个开发者账户并且会自动开启挖矿。
使用以下命令启动开发者模式:
geth --datadir datadir --networkid 15 --dev console 2>output.log
JSON-RPC
以太坊客户端提供了API和一组远程调用(RPC)命令,这些命令被编码为JSON,称为JSON-RPC API。本质上就是一个接口。通常RPC接口作为一个HTTP服务,端口设定为8545。出于安全原因,默认情况下,仅限于接受来自localhost的连接。可通过JavaScript的web3.js或者构建HTTP请求访问JSON-RPC API。
启动RPC:
./build/bin/geth --datadir ../data --nodiscover --networkid 15 --rpc console
输出:
...
INFO [07-01|10:57:37.916] HTTP server started endpoint=127.0.0.1:8545 prefix= cors= vhosts=localhost
...
访问RPC:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "web3_clientVersion", "params": [], "id": 1}' http://localhost:8545
输出:
{"jsonrpc":"2.0","id":1,"result":"Geth/v1.10.4-unstable-c73652da-20210526/linux-amd64/go1.13.8"}
当执行personal.unlockAccount()或在程序中调用personal_unlockAccount接口时,会出现:account unlock with HTTP access is forbidden异常。
解决:可通启动命令中添加参数:
--allow-insecure-unlock
请求对象:
- jsonrpc:指定JSON-RPC协议版本的字符串,必须准确写为“2.0”
- method:包含所要调用方法名称的字符串,以rpc开头的方法名,用英文句号(U+002E or ASCII 46)连接的为预留给rpc内部的方法名及扩展名,且不能在其他地方使用。
- params:调用方法所需要的结构化参数值,该成员参数可以被省略。
- id:已建立客户端的唯一标识id,值必须包含一个字符串、数值或NULL空值。如果不包含该成员则被认定为是一个通知。该值一般不为NULL,若为数值则不应该包含小数。
开启远程调用
./build/bin/geth --datadir ../data --nodiscover --networkid 15 --rpc --rpcaddr X.X.X.X --rpccorsdomain "*" console
- –rpccorsdomain:解决跨域问题
- rpcaddr:指定IP地址访问