Ethereum Study Notes: Private Chain Construction Operation Guide

Original link: https://my.oschina.net/u/2349981/blog/865256
(The content of the explanation is very detailed, I am familiar with the relevant operations of building an Ethereum private chain, and I have learned it!)

Abstract: Explain in detail the process of building a private chain of Ethereum and some common operations.

Although Ethereum is a public chain system, we can run our own private chain nodes by setting some parameters. Development and testing on our own private chain do not require synchronizing public chain data, nor do we need to spend money to buy ether. , save storage space and cost, and is very flexible and convenient. This article introduces the operation steps of using the geth client to build a private chain, and also explains the meaning and function of each command and option used in this process, and finally introduces some common functions in geth's Javascript Console.


Systems and Software

Build a private chain

1. Prepare the genesis block configuration file

Ethereum supports a custom genesis block. To run a private chain, we need to define our own genesis block. The genesis block information is written in a json-formatted configuration file. First save the following content to a json file such as genesis.json.

{
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x400",
  "extraData" : "0x0"
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0xdeadbeefdeadbeef",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00",
  "alloc"      : {}
}


2. Initialization: write to the genesis block

After preparing the genesis block configuration file, you need to initialize the blockchain and write the above genesis block information into the blockchain. First, create a new directory to store blockchain data. Suppose the newly created data directory is ~/privatechain/data0, and genesis.json is stored in ~/privatechain. At this time, the directory structure should be as follows:

privatechain
├── data0
└── genesis.json

Next, enter the privatechain and execute the initialization command:

$ cd privatechain
$ geth --datadir data0 init genesis.json

The main body of the above command is geth initto initialize the blockchain. The command can have options and parameters, where the --datadiroption is followed by a directory name. Here data0, it means that the specified data storage directory is data0, which genesis.jsonis initthe parameter of the command.

Running the above command will read the genesis.json file and write the genesis block into the blockchain according to the content. If you see the following output, the initialization was successful.

I0322 10:52:44.585282 cmd/geth/chaincmd.go:131] successfully wrote genesis block and/or chain rule set: b240e0678c2a8f87cf350225b528e3d97688aad6d4d84ee84e405c7fc9e37e4e

After the initialization is successful, two folders, geth and keystore, will be generated in the data directory data0. At this time, the directory structure is as follows:

privatechain
├── data0
│   ├── geth
│ │ └──'s
│   │       ├── 000002.log
│   │       ├── CURRENT
│   │       ├── LOCK
│   │       ├── LOG
│   │       └── MANIFEST-000003
│   └── keystore
└── genesis.json

The block data is stored in geth/chaindata, and the account data is stored in keystore.


3. Start the private chain node

After the initialization is completed, you will have your own private chain. After that, you can start your own private chain node and do some operations. Enter the following command in the terminal to start the node:

$ geth --datadir data0 --networkid 1108 console

The main body of the above command is geth consoleto start the node and enter the interactive console. --datadirThe option specifies the use data0as the data directory. --networkidThe option is followed by a number, here is 1108, which means that the network id of the specified private chain is 1108. The network id will be used when connecting to other nodes. The network id of the Ethereum public network is 1. In order not to conflict with the public chain network, you must specify your own network id when running a private chain node.

After running the above command, the blockchain node is started and the Javascript Console is entered:

...
Welcome to the Geth JavaScript console!

instance: Geth/v1.5.6-stable/linux/go1.7.3
 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

>

This is an interactive Javascript execution environment where Javascript code can be executed, which >is the command prompt. There are also built-in Javascript objects for manipulating Ethereum in this environment, and these objects can be used directly. These objects mainly include:

  • eth: contains some methods related to operating the blockchain
  • net: Contains the following methods to view the status of the p2p network
  • admin: contains some methods related to managing nodes
  • miner: contains some methods to start & stop mining
  • personal: mainly includes some methods of managing accounts
  • txpool: contains some methods to view the transaction memory pool
  • web3: Contains the above objects, as well as some unit conversion methods


Explore the Javascript Console

After entering the Ethereum Javascript Console, you can use the built-in objects to do some operations. These built-in objects provide rich functions, such as viewing blocks and transactions, creating accounts, mining, sending transactions, and deploying smart contracts. Next, several common functions are introduced. In the following operations, the preceding >commands indicate the commands executed in the Javascript Console.

1. Create an account

I just built a private chain in the front, and I don't have my own account. You can enter it in the js console eth.accountsto verify:

> eth.accounts
[]

Next use the personalobject to create an account:

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

会提示输入密码和确认密码,输入密码不会有显示,只要输入就可以了,之后就会显示新创建的账户地址。

可以创建多个账户,我们再来创建一个账户:

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

接下来就可以查看到刚才创建的两个账户了:

> eth.accounts
["0xc232e2add308136571bb8f9197ba4ae4e5ba9836", "0x814d39aa21f3eed069f2b21da7b5f857f7343afa"]

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

data0
├── geth
│   ├── chaindata
│   ├── LOCK
│   ├── nodekey
│   └── nodes
├── geth.ipc
├── history
└── keystore
    ├── UTC--2017-03-22T09-06-47.766993033Z--c232e2add308136571bb8f9197ba4ae4e5ba9836
    └── UTC--2017-03-22T09-09-42.041015656Z--814d39aa21f3eed069f2b21da7b5f857f7343afa

小提示:命令都可以按Tab键自动补全。


二、查看账户余额

eth对象提供了查看账户余额的方法:

> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0

目前两个账户的以太币余额都是0,要使账户有余额,可以从其他账户转账过来,或者通过挖矿来获得以太币奖励。


三、启动&停止挖矿

通过miner.start()来启动挖矿:

> miner.start(1)

其中start的参数表示挖矿使用的线程数。第一次启动挖矿会先生成挖矿所需的DAG文件,这个过程有点慢,等进度达到100%后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。

如果想停止挖矿,在js console中输入miner.stop()

 
   
> miner.stop()
 
   

注意:输入的字符会被挖矿刷屏信息冲掉,没有关系,只要输入完整的miner.stop()之后回车,即可停止挖矿。

挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做coinbase,默认情况下coinbase是本地账户中的第一个账户:

> eth.coinbase
"0xc232e2add308136571bb8f9197ba4ae4e5ba9836"

现在的coinbase是账户0,要想使挖矿奖励进入其他账户,通过miner.setEtherbase()将其他账户设置成coinbase即可:

> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
"0x814d39aa21f3eed069f2b21da7b5f857f7343afa"

我们还是以账户0作为coinbase,挖到区块以后,账户0里面应该就有余额了:

> eth.getBalance(eth.accounts[0])
160000000000000000000

getBalance()返回值的单位是weiwei是以太币的最小单位,1个以太币=10的18次方个wei。要查看有多少个以太币,可以用web3.fromWei()将返回值换算成以太币:

> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
160


四、发送交易

目前,账户一的余额还是0:

> eth.getBalance(eth.accounts[1])
0

可以通过发送一笔交易,从账户0转移5个以太币到账户1:

> amount = web3.toWei(5,'ether')
"5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
Error: account is locked
    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at <anonymous>:1:1

这里报错了,原因是账户每隔一段时间就会被锁住,要发送交易,必须先解锁账户,由于我们要从账户0发送交易,所以要解锁账户0:

> personal.unlockAccount(eth.accounts[0])
Unlock account 0xc232e2add308136571bb8f9197ba4ae4e5ba9836
Passphrase: 
true

输入创建账户时设置的密码,就可以成功解锁账户。然后再发送交易:

> amount = web3.toWei(5,'ether')
"5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
I0322 19:39:36.300675 internal/ethapi/api.go:1047] Tx(0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825) to: 0x814d39aa21f3eed069f2b21da7b5f857f7343afa
"0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825"

此时交易已经提交到区块链,返回了交易的hash,但还未被处理,这可以通过查看txpool来验证:

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

其中有一条pending的交易,pending表示已提交但还未被处理的交易。

要使交易被处理,必须要挖矿。这里我们启动挖矿,然后等待挖到一个区块之后就停止挖矿:

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

miner.stop()返回true后,txpoolpending的交易数量应该为0了,说明交易已经被处理了:

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

此时,交易已经生效,账户一应该已经收到了5个以太币了:

> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
5


五、查看交易和区块

eth对象封装了查看交易和区块信息的方法。

查看当前区块总数:

> eth.blockNumber
33

通过交易hash查看交易:

> eth.getTransaction("0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825")
{
  blockHash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
  blockNumber: 33,
  from: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825",
  input: "0x",
  nonce: 0,
  r: "0x433fe5845391b6da3d8aa0d2b53674e09fb6126f0070a600686809b57e4ef77d",
  s: "0x6b0086fb76c46024f849141074a5bc79c49d5f9a658fd0fedbbe354889c34d8d",
  to: "0x814d39aa21f3eed069f2b21da7b5f857f7343afa",
  transactionIndex: 0,
  v: "0x1b",
  value: 5000000000000000000
}

通过区块号查看区块:

> eth.getBlock(33)
{
  difficulty: 132928,
  extraData: "0xd783010506846765746887676f312e372e33856c696e7578",
  gasLimit: 3244382,
  gasUsed: 21000,
  hash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
  mixHash: "0x09849dff7c8b8467812fa80d1fa2a27bc61f1cf16d5b2c05a6ce1b77ee18f3f1",
  nonce: "0x5b3939449dbdbea0",
  number: 33,
  parentHash: "0xeca34637642f56f7cfe5b699031c7ddbc43aee00fb10c7f054e0a9719cf226da",
  receiptsRoot: "0xd5f5b7ee944e57cbff496f7bdda7ceffd5eedffe6d5be5320008190502adc07a",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 649,
  stateRoot: "0xc7add6b756980ab9e482766e455597ef1583e747ad62e2924a8e66c6f9170112",
  timestamp: 1490183209,
  totalDifficulty: 4358016,
  transactions: ["0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825"],
  transactionsRoot: "0x7335a362b2c3925e7ba1b41bf7772aa9645a13d4f9c12edd5892b87887264232",
  uncles: []
}

还有更多的功能请自行探索...。


六、连接到其他节点

可以通过admin.addPeer()方法连接到其他节点,两个节点要想联通,必须保证网络是相通的,并且要指定相同的networkid。

假设有两个节点:节点一和节点二,networkid都是1108,通过下面的步骤就可以从节点一连接到节点二。

首先要知道节点二的enode信息,在节点二的js console中执行下面的命令查看enode信息:

> admin.nodeInfo.enode
"enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@[::]:30304"

然后在节点一的js console中执行admin.addPeer(),就可以连接到节点二:

> admin.addPeer("enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@127.0.0.1:30304")

addPeer()的参数就是节点二的enode信息,注意要把enode中的[::]替换成节点二的IP地址。连接成功后,节点二就会开始同步节点一的区块,同步完成后,任意一个节点开始挖矿,另一个节点会自动同步区块,向任意一个节点发送交易,另一个节点也会收到该笔交易。

通过admin.peers可以查看连接到的其他节点信息,通过net.peerCount可以查看已连接到的节点数量。

除了上面的方法,也可以在启动节点的时候指定--bootnodes选项连接到其他节点。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325356855&siteId=291194637
Recommended