5

practice collation (1) Basic knowledge of
Ethereum practice finishing (2) Geth client
practice finishing (3) Remix development and deployment of smart contracts
practice finishing (4) Truffle smart contract development framework
practice finishing (5) DApp development process record (
practice finishing (5) DApp development process record (Part 2)
practice sorting (6) file decentralized storage


Geth

There are many Ethereum clients, developed based on various languages, which is related to the value of openness advocated by the blockchain. Geth (full name go-ethereum) is a client developed by the official Ethereum community, and it is the leader in the client. We can use Geth commands to build an Ethereum private chain, or we can interact with the Ethereum network environment based on the interactive command console provided by Geth.

Geth install

Geth is a client written based on GO language, you need to install goland first.

Install Go locale

Download the binary package: go1.4.linux-amd64.tar.gz;

Unzip the downloaded binary package to the /usr/local directory:

$ tar -C /usr/local -zxvf go1.17.linux-amd64.tar.gz

Set environment variables:

$ export PATH=$PATH:/usr/local/go/bin

Effective environment variables:

$ source /etc/profile

verify:

$ go env

compile and install geth from source code

Download the source code:

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

Compile the source code:

$ cd go-ethereum
$ make geth

Domestic users may not be able to access proxy.golang.org during the compilation process, and they can execute after setting the proxy:

$ go env -w GOPROXY=https://goproxy.cn
$ make geth

Set environment variables:

export PATH=$PATH:/usr/local/go-ethereum/build/bin

Effective environment variables:

$ source /etc/profile

verify:

$ geth version

Geth start node

connects to the main chain network

Start a node to connect to the Ethereum main chain and enter the JavaScript interactive console:

$ geth console

After executing the command, enter the following:

Welcome to the Geth JavaScript console!

instance: Geth/v1.10.8-unstable-dfeb2f7e-20210823/darwin-amd64/go1.17
at block: 0 (Thu Jan 01 1970 08:00:00 GMT+0800 (CST))
 datadir: /Users/zhutx/Library/Ethereum
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d

After a while, the console began to continuously output information, indicating that the node is downloading the latest blockchain data and status in Fast-Sync mode. As you can see from the output when you first execute the command, the data is stored in the /Users/zhutx/Library/Ethereum directory by default.

It is impractical to conduct development and testing on the main chain. Now you can stop the node. The blockchain data downloaded by the node will quickly occupy a lot of storage space, and the directory can be deleted

Connect to the test network

The program always needs to be tested during the development phase. We can start the node and connect to the Ethereum test network:

$ mkdir testdir
// 连接Ropsten测试网络,指定存储目录为testdir
$ geth --ropsten --datadir "./testdir" console

If you connect to the test network for development, you still need to pay for gas (Gas) fees for related operations. In addition to mining to allow your account to obtain Ether, we can also directly use the website that provides faucet services (such as: https://faucet. ropsten.be/), enter the account address of your own test chain, and directly obtain ether (the ether of the test chain has no actual value).


There are many parameters for geth, and a few of them will be introduced in the follow-up. I will not give an example one by one here. You can understand it yourself (geth --help).


Geth builds a private chain

Using Geth, we can also build our own Ethereum private chain.

Create a data storage directory

$ mkdir blockchain
$ cd blockchain

Write the genesis block configuration

$ vim gensis.json
{
    "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": {},
    "number": "0x0",
    "gasUsed": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

Genesis block parameter description [TODO]:

parameterdescribe

Initialize the

// 新建一个目录用来存放区块链数据
$ mkdir db
// 初始化区块链
$ geth --datadir "./db" init gensis.json

After the initialization is successful, geth and keystore directories will be produced in the db directory. At this time, the directory structure is as follows:

blockchain
├── db
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.ldb
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── lightchaindata
│   │   │   ├── 000001.log
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   └── keystore
└── gensis.jso

Start private chain

$ geth --rpc --rpcport 8545 --rpccorsdomain "*" --datadir "./db" --port 30303 --rpcapi "eth,net,web3,personal,admin,shh,txpool,debug,miner" --networkid 100000 --rpcaddr=0.0.0.0 --nodiscover --allow-insecure-unlock console 2>> eth.log

The relevant startup parameters can be understood by yourself


Geth's JavaScript console

There are some built-in objects in Geth's JavaScript console, through which we can easily interact with Ethereum:

  • eth: Provides methods for operating the blockchain
  • net: Provides a way to view the status of the p2p network
  • admin: Provides methods for managing nodes
  • miner: Provides methods to start and stop mining
  • personal: Provides a way to manage accounts
  • txpool: Provides a way to view the transaction memory pool
  • web3: In addition to the methods in the above objects, it also contains some unit conversion methods

On the private chain we built above, we use the transfer business to demonstrate some of the operations of the JavaScript console. Just get an understanding:

0. Enter the JavaScript Console environment

If you do not enter the console when starting the node, you can enter the JavaScript command environment of the node through the attach command alone:

cd blockchain
$ geth --datadir "./db" attach ipc:./db/geth.ipc

1. Create a new account

Pass in the account password, and return the public key after successful execution:

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

The generated account file is in the keystore folder. We execute it twice and generate 2 accounts for transfer.

2. View account

> eth.accounts
["0xf05ed6c1bab6800d94ae3af4471b77caf07860f0", "0x8efa17c5646c60d4b67d118445f2b9614d9ea3e7"]

3. Check the balance

> balance = web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
0

eth.getBalance (account public key), returns the balance of the account, the unit is wei, web3.fromWei converts wei to ether.

4.

In order to obtain Ether, you need to start mining first. We set the first account as a mining account:

> miner.setEtherbase(eth.accounts[0])
true

Check whether the setting is successful:

> eth.coinbase
"0xf05ed6c1bab6800d94ae3af4471b77caf07860f0"

Start mining:

> miner.start(1)
null

Dig for a while, make sure that the account has a balance, and then suspend mining, and then open it when the transaction needs to pack the block.

In the blockchain field, operations such as transferring money, deploying smart contracts, and invoking smart contracts are all transactions. Not a narrow trading concept

Close mining:

> miner.stop()

Check the balance again:

> balance = web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
234

There are now 234 Ether in the account. You need to unlock the account before the transfer transaction, otherwise an error will be reported.

5. Unlock account

> personal.unlockAccount(eth.accounts[0], "123456")
true

6. Transaction

Transfer fraction 34 to another account:

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(34, "ether")})
"0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9"

Send a transfer transaction to the blockchain network and return the transaction hash. At this time, the transaction is waiting to be packaged in the transaction pool.

Check the status of the transaction pool:

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

Pending indicates a transaction that has been submitted but has not been processed, and it shows that there is 1 transaction waiting to be packaged.

View pending transaction details:

> txpool.inspect.pending
{
  0xf05ED6C1baB6800D94Ae3af4471B77caf07860f0: {
    0: "0x8eFA17c5646c60D4B67D118445f2B9614D9Ea3e7: 34000000000000000000 wei + 21000 gas × 1000000000 wei"
  }
}

In order for the transaction to be processed, mining must be turned on. To facilitate analysis, stop mining after mining a block:

> miner.start(1);admin.sleepBlocks(1);miner.stop();
INFO [08-24|02:29:13.504] Updated mining threads                   threads=1
INFO [08-24|02:29:13.504] Transaction pool price threshold updated price=1,000,000,000
INFO [08-24|02:29:13.505] Commit new mining work                   number=118 sealhash=a408a5..244a99 uncles=0 txs=0 gas=0 fees=0 elapsed="146.423µs"
INFO [08-24|02:29:13.505] Commit new mining work                   number=118 sealhash=ed24ca..e08e23 uncles=0 txs=1 gas=21000 fees=2.1e-05 elapsed="350.824µs"
INFO [08-24|02:29:15.927] Successfully sealed new block            number=118 sealhash=ed24ca..e08e23 hash=c0b43c..28c921 elapsed=2.422s
INFO [08-24|02:29:15.927] 🔨 mined potential block                  number=118 hash=c0b43c..28c921
INFO [08-24|02:29:15.927] Commit new mining work                   number=119 sealhash=e9df41..7397c0 uncles=0 txs=0 gas=0     fees=0       elapsed="187.308µs"

Check the balances of the transferor and transferor separately:

> balance = web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
202
> balance = web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
34

It can be seen that the transfer account eth.accounts[1] has 34 Ether, but the transfer account eth.accounts[0] has an account balance of not 200, because the account has mining income;

7. Block

View transaction details:

> eth.getTransaction("0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9")
{
  blockHash: "0xc0b43c476fc4406b4db342beed0ed0b0d4bad02330b2b353a354b558bc28c921",
  blockNumber: 118,
  from: "0xf05ed6c1bab6800d94ae3af4471b77caf07860f0",
  gas: 21000,
  gasPrice: 1000000000,
  hash: "0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9",
  input: "0x",
  nonce: 0,
  r: "0xe1d9e0678c2a67c0fcec81cab407f20caca4ff617fbc697249409d3d78a74ef0",
  s: "0x6db176315eebaafc07c695549fccbfed0dbe1317a3ffbbf398d9c3aa6b8bb250",
  to: "0x8efa17c5646c60d4b67d118445f2b9614d9ea3e7",
  transactionIndex: 0,
  type: "0x0",
  v: "0x557",
  value: 34000000000000000000
}

The above command is to view the details when the transaction is initiated. If you want to view the details when the transaction is packaged into the block, use the following command:

> eth.getTransactionReceipt("0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9")
{
  blockHash: "0xc0b43c476fc4406b4db342beed0ed0b0d4bad02330b2b353a354b558bc28c921",
  blockNumber: 118,
  contractAddress: null, // 如果是合约创建交易,则返回合约地址,其他情况返回null
  cumulativeGasUsed: 21000, // 累计话费的gas总值
  effectiveGasPrice: 1000000000,
  from: "0xf05ed6c1bab6800d94ae3af4471b77caf07860f0",
  gasUsed: 21000, // 执行当前这个交易单独话费的gas
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: "0x8efa17c5646c60d4b67d118445f2b9614d9ea3e7", // 如果是合约创建交易,返回null
  transactionHash: "0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9",
  transactionIndex: 0, // 交易在区块里的序号
  type: "0x0"
}

The following are other commands for querying blocks:

View the total number of current blocks:

> eth.blockNumber
118

View the latest block:

> eth.getBlock('latest')
{
  difficulty: 131886,
  extraData: "0xd683010a08846765746886676f312e3137856c696e7578",
  gasLimit: 5273553,
  gasUsed: 21000,
  hash: "0xc0b43c476fc4406b4db342beed0ed0b0d4bad02330b2b353a354b558bc28c921",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xf05ed6c1bab6800d94ae3af4471b77caf07860f0",
  mixHash: "0x009c9034e94034344fc03dd6914d3753a8b98b8a3b0e3b5d11d473d9ad5a1402",
  nonce: "0x66f00bbbcd357270",
  number: 118,
  parentHash: "0xa475ef4ac3b9c1d9b8390e5044a1d11186c57b6c369756b642420f345b7ec82f",
  receiptsRoot: "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 649,
  stateRoot: "0x798af7bcb3bd31b18c955c05e694ae342d1db654681b1703b817ff6e02639d69",
  timestamp: 1629743353,
  totalDifficulty: 15897610,
  transactions: ["0x47872d357a318f0213e63d40311a990cb0d467ad2bb79a6d8c82a9b667a079b9"],
  transactionsRoot: "0x979e07128c057ff81e2eaaba45b3704be371ffcb794876f570f88e88e00cd313",
  uncles: []
}

eth.getBlock(blockNumber|blockHash)) can get the information of a specific block.


Geth multi-node networking

The current private chain is a single node (node 1). Next, we will connect another node (node 2) to form a simplest Ethereum private chain network.

After node 2 installs the geth client, enter the JavaScript console and enter the following command to obtain node 2 information:

> admin.nodeInfo
{
  enode: "enode://5873af9deabd8f7e40878ce0e3caec0bb86c79cf9bd99781be2aaab8a61e3c24aded28102971a38a7cb0ff2749b3a1b3624232cc96ac4f76dc9f035232629652@127.0.0.1:30303?discport=0",
  enr: "enr:-Ja4QCuP0rodmA2imicnqbuZ14kPiMqPrX-Dp_5z8FU1l1PvcU0IKz4cynQppjEqVguSlU_Tn-UlVkaw_ehxcCsM0XoEg2V0aMfGhJPR68WAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQJYc6-d6r2PfkCHjODjyuwLuGx5z5vZl4G-Kqq4ph48JIRzbmFwwIN0Y3CCdl8",
  id: "37829b9d6cdb1610dca7ba713a1c0647d6474957c686a3b4967b7cd77f0d47a5",
  ip: "127.0.0.1",
  listenAddr: "[::]:30303",
  name: "Geth/v1.10.8-unstable-dfeb2f7e-20210823/linux-amd64/go1.17",
  ports: {
    discovery: 0,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        byzantiumBlock: 0,
        chainId: 666,
        constantinopleBlock: 0,
        eip150Block: 0,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        ethash: {},
        homesteadBlock: 0,
        istanbulBlock: 0,
        petersburgBlock: 0
      },
      difficulty: 15897610,
      genesis: "0xd3d6bb893a6e274cab241245d5df1274c58d664fbb1bfd6e59141c2e0bc5304a",
      head: "0xc0b43c476fc4406b4db342beed0ed0b0d4bad02330b2b353a354b558bc28c921",
      network: 100000
    },
    snap: {}
  }
}

In fact, only the enode information in node 2 is used, and enode can be obtained directly:

> admin.nodeInfo.enode
"enode://5873af9deabd8f7e40878ce0e3caec0bb86c79cf9bd99781be2aaab8a61e3c24aded28102971a38a7cb0ff2749b3a1b3624232cc96ac4f76dc9f035232629652@127.0.0.1:30303?discport=0"

Execute the command at node 1 to connect to node 2:

Change 127.0.0.1 to the public network address of node 2
> admin.addPeer("enode://5873af9deabd8f7e40878ce0e3caec0bb86c79cf9bd99781be2aaab8a61e3c24aded28102971a38a7cb0ff2749b3a1b3624232cc96ac4f76dc9f035232629652@127.0.0.1:30303?discport=0")
true

After the connection is successful, node 2 will start to synchronize the block of node 1. After the synchronization is completed, any node will start mining, another node will synchronize the block, send a transaction to one node, and the other node will also receive the pen trade.

The following command can view the connected remote nodes:

> admin.peers

practice finishing (1) Basic knowledge of
Ethereum practice finishing (2) Geth client
practice collation (3) Remix development and deployment of smart contracts
practice finishing (4) Truffle smart contract development framework
practice finishing (5) DApp development process record (part 1)
practice finishing (5) DApp development process record (part 2)
Practice Arrangement (6) File


zhutianxiang
1.5k 声望328 粉丝