This article was written in December 2018
Ethereum learning day1
- demo of blockchain principle
https://anders.com/blockchain/blockchain.html
Use geth to build your own private chain (single node)
Please install geth first and add geth to the environment variable
-
1. In a directory, take C:\Users\yqq\eth\persondata as an example to create the genesis block information file genesis JSON, as follows:
{ "config": { "chainId": 15, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "coinbase": "0x0000000000000000000000000000000000000000", "difficulty": "0x40000", "extraData": "", "gasLimit": "0xffffffff", "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x00", "alloc": {} }
-
2. Initialize geth -- dataDir node1 init genesis JSON, pay special attention: every time you create a new node, you must initialize it first, otherwise there will be various pits later!!!
C:\Users\yqq\eth\persondata>geth --datadir node1 init genesis.json INFO [12-17|23:57:12.910] Maximum peer count ETH=25 LES=0 total=25 INFO [12-17|23:57:12.947] Allocated cache and file handles database=C:\\Users\\yqq\\eth\\persondata\\node1\\geth\\chaindata cache=16 handles=16 INFO [12-17|23:57:12.981] Writing custom genesis block INFO [12-17|23:57:12.984] Persisted trie from memory database nodes=0 size=0.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [12-17|23:57:12.990] Successfully wrote genesis state database=chaindata hash=a0e580...a5e82e INFO [12-17|23:57:12.998] Allocated cache and file handles database=C:\\Users\\yqq\\eth\\persondata\\node1\\geth\\lightchaindata cache=16 handles=16 INFO [12-17|23:57:13.022] Writing custom genesis block INFO [12-17|23:57:13.027] Persisted trie from memory database nodes=0 size=0.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [12-17|23:57:13.031] Successfully wrote genesis state database=lightchaindata hash=a0e580...a5e82e
-
3. Open a cmd window and start the server geth -- dataDir node1 -- ipcpath node1 / geth ipc --networkid 55 --port 10009 --nodiscover
--datadir Specify data storage directory --ipcpath appoint ipc File storage directory, Required for console connection ipc file --networkid Designated network id, If you want to build multiple nodes, The same must be used networkid, otherwise, admin.addPeer Will fail(This is the pit I stepped on!!) --port Specify port, Multiple nodes must use different ports, Otherwise there will be conflict --nodiscover Prevent being discovered by others on the network, But you can pass admin.addPeer Add peer node
-
4. Open another cmd window to connect to the server get attach IPC: \ \ \pipe\node1\geth. ipc
> eth.accounts [] > personal.newAccount("111") //Create user with password "111" "0xe41aa565490e3d7971c25c1c1218e61a48455c92" > > personal.newAccount("111") "0x808fd82922556f0148787e3663ed0181e65c0f61" > > > eth.accounts //View user ["0xe41aa565490e3d7971c25c1c1218e61a48455c92", "0x808fd82922556f0148787e3663ed0181e65c0f61"] > > > eth.getBalance(eth.accounts[0]) 0 > > eth.coinbase //View miners "0xe41aa565490e3d7971c25c1c1218e61a48455c92" > > miner.start(5) //Start five threads and start mining. At this time, the server starts mining and waits patiently for two minutes //Generating DAG in progress epoch = 1 percentage = XXX, when it reaches 100%, you can start to dig the ore null > miner.stop() null > eth.getBalance(eth.accounts[0]) 25000000000000000000 > > eth.blockNumber 5 > > eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(2, "ether")}) //You need to unlock here Error: authentication needed: password or unlock at web3.js:3143:20 at web3.js:6347:15 at web3.js:5081:36 at <anonymous>:1:1 > personal.unlockAccount(eth.accounts[0]) Unlock account 0xe41aa565490e3d7971c25c1c1218e61a48455c92 Passphrase: //Enter password 111 here true > eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(2, "ether")}) "0x7973906595c5b3bd066c126f7f966a4d94b36c0383fc5050a85239af05ccf80a" > > txpool.status //Viewing the status in the transaction pool, you can see that a transaction is pending { pending: 1, queued: 0 } > > miner.setEtherbase(eth.accounts[1]) //Set mining user true > miner.start(5) //Start mining, wait a little, wait until the server shows that the mine has been dug, and then stop mining > eth.blockNumber 9 > eth.blockNumber 9 > eth.blockNumber 10 > miner.stop() null > eth.getBalance(eth.accounts[1]) 52000021000000000000 > web3.fromWei( eth.getBalance(eth.accounts[1]), "ether") 52.000021 Mining income + Transaction fee > >
-
5. Summary: after the above steps, we have realized the mining + transfer transaction of a single node
Use geth to build your own private chain (multi node)
Based on the above, we are creating a new node node2. The command is as follows:
1.initialization(You must initialize before creating a new node!!): geth --datadir node2 init genesis.json 2.Start the server: geth --datadir node2 --ipcpath node2/geth.ipc --networkid 55 --port 10010 --nodiscover //Note: - networkid must be consistent with node1 node!! 3.Open another cmd, Connect the server: geth attach ipc:\\.\pipe\node2\geth.ipc
Add node
-
node1 console
> admin.nodeInfo.enode //View the address of this node "enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0"
-
node2 console
> personal.newAccount("111") "0x48e33e5121497eda40697341e405d4adb8b60984" > > eth.coinbase "0xd18d089990d8d6e8aeeb3965edac1df740fb749e" > > admin.peers [] > > admin.nodeInfo { enode: "enode://72634a41f51c8c75650ec5e416daa5578edb98592ee2898cde6ac1ca50c44b14016bf0a353dbd85cf1ef42c841a06052f5d253de329c2bf5324d211d8756d0c0@163.125.179.72:10010?discport=0", enr: "0xf88fb8408b691c58760e023c9ab87efcec4bd9582c76b2a8f948444bf2262d4f0b0143b638d42ece43c951ccc910c3946222ead456956514e52142890ca4101af375e3f60283636170c6c5836574683f82696482763482697084a37db34889736563703235366b31a10272634a41f51c8c75650ec5e416daa5578edb98592ee2898cde6ac1ca50c44b148374637082271a", id: "11ef6d692fc5ce19e67767bc9661df9088031254304064808e8af5e00e3f2392", ip: "163.125.179.72", listenAddr: "[::]:10010", name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2", ports: { discovery: 0, listener: 10010 }, protocols: { eth: { config: { chainId: 15, eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000", eip155Block: 0, eip158Block: 0, homesteadBlock: 0 }, difficulty: 262144, genesis: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e", head: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e", network: 55 } } } > > > admin.addPeer("enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0 ") / / add node1 true > > admin.peers //You can see that it has been added successfully [{ caps: ["eth/63"], enode: "enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0", id: "6fb555a6ec8b19e3c3c1a4dd2b8a15e6f50dede36dedec6dea4bb905fd082f86", //id of node1 name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2", network: { inbound: false, localAddress: "192.168.10.126:56674", remoteAddress: "163.125.179.72:10009", static: true, trusted: false }, protocols: { eth: { difficulty: 3947161, head: "0x15df03da3ca1c75857fee397d768bb4dab3d924009984020a53fa4b642676ee5", version: 63 } } }] >
transfer accounts
node1 eth.accounts[0] to node2 eth Accounts [0] transfer, node2 eth Accounts [1] is responsible for mining
-
node1
> eth.getBalance(user1) ReferenceError: 'user1' is not defined at <anonymous>:1:16 > eth.getBalance(eth.accounts[0]) 22999979000000000000 > > > eth.sendTransaction({from:eth.accounts[0], to:"0xd18d089990d8d6e8aeeb3965edac1df740fb749e", value:web3.toWei(15, "ether")}) Error: authentication needed: password or unlock at web3.js:3143:20 at web3.js:6347:15 at web3.js:5081:36 at <anonymous>:1:1 > personal.unlockAccount(eth.accounts[0]) Unlock account 0xe41aa565490e3d7971c25c1c1218e61a48455c92 Passphrase: //Enter the password to unlock true > eth.sendTransaction({from:eth.accounts[0], to:"0xd18d089990d8d6e8aeeb3965edac1df740fb749e", value:web3.toWei(15, "ether")}) "0xb7e392e0f8edb744f9c15716e8a4f5fef1c6ce944284e7f6a23abd875b09eb75" > txpool.status { pending: 1, //Transaction pending queued: 0 } > txpool.status { pending: 0, //Transaction completion queued: 0 } > eth.getBalance(eth.accounts[0]) 7999958000000000000 //Reduced 15eth + some handling charges >
-
node2
> admin.peers //View peer node information [{ caps: ["eth/63"], enode: "enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0", id: "6fb555a6ec8b19e3c3c1a4dd2b8a15e6f50dede36dedec6dea4bb905fd082f86", //Information of node 1 name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2", network: { inbound: false, localAddress: "192.168.10.126:56674", remoteAddress: "163.125.179.72:10009", static: true, trusted: false }, protocols: { eth: { difficulty: 3947161, head: "0x15df03da3ca1c75857fee397d768bb4dab3d924009984020a53fa4b642676ee5", version: 63 } } }] > > eth.getBalance( eth.accounts[0]) 0 > eth.accounts[0] "0xd18d089990d8d6e8aeeb3965edac1df740fb749e" > > txpool.status { pending: 1, //The transfer transaction of node1 is already in pending status, waiting for miners to dig queued: 0 } > > > miner.setEtherbase(eth.accounts[1]) //Set up a miner true > > miner.start(5) //Start mining (package the transaction) and specify to start 5 threads null > miner.stop() //Stop mining null > > eth.getBalance(eth.accounts[0]) 15000000000000000000 //Received the money transferred from the 0th user of node1 > eth.getBalance(eth.accounts[1]) 70000021000000000000 //node2 node mining + one transaction handling fee >
Trampled pit
- 1.miner. After start(), it returns null, thinking that the mining has failed. In fact, the server is mining. The first mining needs to wait until the percentage in Generating DAG in progress epoch=1 percentage=XXX is 100 miner.stop() returns null. In fact, you need to wait for a while before you really stop mining
- 2. When starting the server, the -- networkid settings of the two nodes are different, resulting in admin Addpeer() is always unsuccessful!!
- 3. The way of specifying IPC file in window is different from that in linux. Window is \ \ \pipe \ \ please refer to the above example for the directory you specify; linux -- geth in datadir directory ipc
Get + mist build private chain
-
1. Close Mist and initialize a new node in a new directory (take C:\Windows\System32\cmd.exe as an example)
C:\Users\yqq\eth\gethmist>geth --datadir nodeA init genesis.json
-
2. Start the node server and specify the path to create ipc when starting. Mist will use this ipc (i.e. \ \. \ pipe \ get. ipc) to connect with the current node
C:\Users\yqq\eth\gethmist>geth --datadir nodeA --networkid 55 --port 10999 --nodiscover --ipcpath \\.\pipe\geth.ipc
-
3. Start the client console and connect nodeA
C:\Users\yqq\eth\gethmist>geth attach ipc:\\.\pipe\geth.ipc //Specify ipc to connect to the server Welcome to the Geth JavaScript console! instance: Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2 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 > > eth.accounts [] > personal.newAccount("111") //Create a user "0xc1b58d997c122208103a74aa3b12a4a9c73cf4e7" >
-
4. Start Mist and set the network as rinkby. If it is rinkby, it does not need to be set (Mist defaults to Rinbkey, and you can set other networks according to your needs) When Mist starts, you can see the newly created user, as shown in the following figure:
-
5. Start node1 node in C:\Users\yqq\eth\persondata
geth --datadir node1 --networkid 55 --nodiscover --port 10333 --ipcpath node1\geth.ipc geth attach ipc:\\.\pipe\node1\geth.ipc //Start console
-
Add node1 as the opposite node in nodeA, then transfer from nodeA's account to node1's account and start mining. The transfer results are as follows:
Attention
- 1.Mist will open \ \ \pipe\geth.ipc, so -- ipcpath \ \ needs to be specified when starting nodeA node \pipe\geth.ipc