以太坊源码分析(三) - 以太坊客户端Geth使用以及私有链测试

geth用法

geth [选项] 命令 [命令选项] [参数…]
geth的常用选项

--datadir "xxxx"  //指定数据目录,用来存放区块链数据,状态数据,keystore数据等。
--cache value    //分配给内部缓存的内存,单位MB,默认为 128

--rpc            //启用HTTP-RPC服务器
--rpcaddr value  //HTTP-RPC服务器接口地址(默认值:“localhost”),默认只允许本地连接,设置为 0.0.0.0 可以接收任何地址发来的连接请求
--rpcport value  //HTTP-RPC服务器监听端口(默认值:8545),可以改为不同的端口

--ws                 // 启用WS-RPC服务器,几乎所有第三方节点都不启动这个服务,而要监听以太坊事件又必须启动这个服务
--wsaddr value       // WS-RPC服务器监听接口地址(默认值:“localhost”)
--wsport value       // WS-RPC服务器监听端口(默认值:8546)

启动geth可以用下面的命令:

geth

即可。

如果想后台启动geth,可以执行:

nohup geth & > nohup.out

如果直接在 shell 终端运行,可以用 CTRL + C 关闭进程,那如何关闭运行在后台的 geth 进程呢,写了个简单的脚本如下:

#!/bin/sh
pid=`ps -ef|grep geth|grep -v grep|awk '{print $2}'`
echo $pid
kill -INT $pid

执行该脚本即可。

创建并测试以太坊私有链

  1. 新建ethTest目录
  2. 在ethTest目录下新建genesis.json文件用以产生创世区块,内容如下:
{
    "nonce":"0x0000000000000042", 
    "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000", 
    "difficulty": "0x4000", 
    "alloc": {}, 
    "coinbase":"0x0000000000000000000000000000000000000000", 
    "timestamp": "0x00", 
    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", 
    "extraData": "0x00000000", 
    "gasLimit":"0xffffffff",	
	"config":{
		"chainId": 666,
		"homesteadBlock": 0,
		"eip155Block": 0,
		"eip158Block": 0
	}
}
  1. 打开命令行进入ethTest目录,执行:
y@ubuntu:~/Desktop/ethTest$ geth --datadir "./" init genesis.json
INFO [11-08|01:12:23.128] Maximum peer count                       ETH=25 LES=0 total=25
INFO [11-08|01:12:23.129] Allocated cache and file handles         database=/home/y/Desktop/ethTest/geth/chaindata cache=16 handles=16
INFO [11-08|01:12:23.217] Writing custom genesis block 
INFO [11-08|01:12:23.218] Persisted trie from memory database      nodes=0 size=0.00B time=6.21µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-08|01:12:23.219] Successfully wrote genesis state         database=chaindata                              hash=84e71d…97246e
INFO [11-08|01:12:23.219] Allocated cache and file handles         database=/home/y/Desktop/ethTest/geth/lightchaindata cache=16 handles=16
INFO [11-08|01:12:23.261] Writing custom genesis block 
INFO [11-08|01:12:23.261] Persisted trie from memory database      nodes=0 size=0.00B time=3.426µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-08|01:12:23.261] Successfully wrote genesis state         database=lightchaindata                              hash=84e71d…97246e
y@ubuntu:~/Desktop/ethTest$ 

初始化创世区块,初始化成功后,会在数据目录ethTest中生成geth和keystore两个文件夹。

  1. 启动私有链
y@ubuntu:~/Desktop/ethTest$ geth --datadir "./" --nodiscover  --networkid 1000 console 2>>geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.13-stable/linux-amd64/go1.10.1
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

–datadir 表示设置当前区块链网络数据存放的位置,因为已经在数据目录下,所以这里值是"./"
–nodiscover 表示禁止被网络中其它节点发现,需要手动添加该节点到网络
–networkid 设置当前区块链的网络ID,用于区分不同的网络,是一个数字

挖矿及交易测试

上述启用私有链进入以太坊Javascript Console后,就可以使用里面的内置对象做一些操作了,这些内置对象提供的功能很丰富,比如查看区块和交易、创建账户、挖矿、发送交易、部署智能合约等。

1.账户创建

创建方式1:
personal.newAccount(“123456”) //创建一个账户 参数为私钥密码 返回值为账户的公钥

> personal.newAccount("123456")
"0x8691c845d349b172e38e7ffdf4123718074ad4b6"

创建方式2:

> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x262919249c4566f25f297217412368368c8b1ba7"

账户默认会保存在数据目录的keystore文件夹中,查看/home/y/Desktop/ethTest/keystore目录,发现多了两个文件,这两个文件就对应刚才创建的两个账户,这是json格式的文本文件,可以打开查看,里面存的是私钥经过密码加密后的信息。

2.查看当前的账户列表

> eth.accounts
["0x8691c845d349b172e38e7ffdf4123718074ad4b6", "0x262919249c4566f25f297217412368368c8b1ba7"]

3.查看指定索引的账户

> eth.accounts[0]
"0x8691c845d349b172e38e7ffdf4123718074ad4b6"
> eth.accounts[1]
"0x262919249c4566f25f297217412368368c8b1ba7"
> eth.accounts[2]
undefined

4.查看账户的以太币余额
当以太坊的私链在挖矿时候,所挖到的以太币都会存入第一个以太坊账户中,即eth.accounts[0] 中,而eth.accounts[1]默认是不会有以太币的。
每个账户的公钥(地址)是一切以太坊账户操作的核心,但地址字符串太长,我们用user0/user1 分别代表accounts[0]和accounts[1]

> user0 = eth.accounts[0]
"0x8691c845d349b172e38e7ffdf4123718074ad4b6"
> user1 = eth.accounts[1]
"0x262919249c4566f25f297217412368368c8b1ba7"
> eth.getBalance(user0)
830000000000000000000
> eth.getBalance(user1)
0

5.查看区块数

> eth.blockNumber
166

6.通过区块号查询区块

> eth.getBlock(165)
{
  difficulty: 140071,
  extraData: "0xd88301080d846765746888676f312e31302e31856c696e7578",
  gasLimit: 3690313,
  gasUsed: 0,
  hash: "0xd7aaaa720d8828fbd12676044e4bb24a95b2b37936676c4c32f82c5f2ca4774b",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x8691c845d349b172e38e7ffdf4123718074ad4b6",
  mixHash: "0x7ae5ebe3cf233e8f686ac2ccf29a8d67fe1537d56dff76b95439e54ba3723bc6",
  nonce: "0x50cfc47b136b7738",
  number: 165,
  parentHash: "0x542383fa3ccd972d67c3da4f94d416db8fa236405092185c5761d92f243212fd",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 537,
  stateRoot: "0x861a29939ba9019c1666f99edb034f0c032981c3b752177ce7aef9b215fd5217",
  timestamp: 1541752326,
  totalDifficulty: 22418407,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

7.两个账户之间进行以太币转换
使用eth.sendTransaction来将1个以太币从user0转移到user1中

> amount = web3.toWei(1,'ether')
"1000000000000000000"
> eth.sendTransaction({from: user0, to: user1, value: amount})
Error: authentication needed: password or unlock
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at :1:1

这个是以太坊的一个保护机制,每隔一段时间账户就会自动锁定,这个时候任何以太币在账户之间的转换都会被拒绝,除非把该账户解锁。
这个时候我们就需要执行 personal.unlockAccount(user0), 并输入密码来解锁user0才可:

> personal.unlockAccount(user0)
Unlock account 0x8691c845d349b172e38e7ffdf4123718074ad4b6
Passphrase: 
true

这个时候我们重新执行命令eth.sendTransaction({from: user0, to: user1, value: amount})进行转账:

> eth.sendTransaction({from: user0, to: user1, value: amount})
"0x488ad5504a46d553f24faa4675925e158fe077bc0ca419848b8506684993bdf1"

结果是该笔交易的交易hash。
然后查询user1的账户余额:

> eth.getBalance(user1)
1000000000000000000

这里如果没有开启挖矿,交易是不会被确认的,可以执行下面命令挖出一个区块后然后停止挖矿:

miner.start(1);admin.sleepBlocks(1);miner.stop();

8.查看交易池状态

> txpool.status
{
  pending: 0,
  queued: 0
}

pending表示待确认的交易数量,

9.通过交易hash查看交易数据
"0x488ad5504a46d553f24faa4675925e158fe077bc0ca419848b8506684993bdf1"是上面那笔转账交易的交易hash

> eth.getTransaction("0x488ad5504a46d553f24faa4675925e158fe077bc0ca419848b8506684993bdf1")
{
  blockHash: "0xd2b1ac47488649358ae02116bd10a0a9a324c8b82e8a4bbf88fe2f108f75a854",
  blockNumber: 192,
  from: "0x8691c845d349b172e38e7ffdf4123718074ad4b6",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x488ad5504a46d553f24faa4675925e158fe077bc0ca419848b8506684993bdf1",
  input: "0x",
  nonce: 1,
  r: "0x40795444efda82f61e51e89c3c184a2743f10e598357bdea44c40f747a43214a",
  s: "0x1b51eb1153743ad6d261e06f73ac34decb1fed990bbfe93bdd996b844262dccb",
  to: "0x262919249c4566f25f297217412368368c8b1ba7",
  transactionIndex: 0,
  v: "0x4f",
  value: 1000000000000000000
}

10.挖矿
geth启动的时候默认是开启CPU挖矿的,挖到一个区块会奖励5个以太币,挖矿所得的奖励会记入矿工的账户,这个账户叫做coinbase,默认情况下coinbase是创建的第一个账户:

> eth.coinbase
"0x8691c845d349b172e38e7ffdf4123718074ad4b6"
> 

可以更改入账的账户:

> miner.setEtherbase(user1)
true
> eth.coinbase
"0x262919249c4566f25f297217412368368c8b1ba7"
> miner.setEtherbase(user0)
true
> eth.coinbase
"0x8691c845d349b172e38e7ffdf4123718074ad4b6"

启动挖矿:

> eth.blockNumber
592
> miner.start(2)
null
> eth.blockNumber
628

停止挖矿:

> miner.stop()
true

参考:
https://github.com/ethereum/go-ethereum/wiki/Private-network

以太坊客户端Geth命令用法-参数详解
以太坊客户端Geth命令用法-参数详解
区块链学堂(8):Geth 基本命令

ubuntu下geth安装及搭建虚拟区块链
搭建Geth本地私有链网络

区块链学堂(第四课):以太坊Geth基本命令

以太坊如何搭建私有连联盟链

你可能感兴趣的:(区块链,以太坊源码分析)