zoukankan      html  css  js  c++  java
  • geth搭建以太坊私链及常用操作

    一、下载安装geth客户端

    https://www.ethereum.org/

    二、搭建私有链

    1、准备创世区块配置文件

    要运行私有链,我们就需要定义自己的创世区块,创世区块信息写在一个json格式的配置文件中。首先将下面的内容保存到一个json文件中,例如genesis.json。

    {
      "config": {
            "chainId": 10,
            "homesteadBlock": 0,
            "eip155Block": 0,
            "eip158Block": 0
        },
      "coinbase"   : "0x0000000000000000000000000000000000000000",
      "difficulty" : "0x20000",
      "extraData"  : "",
      "gasLimit"   : "0xffffffff",
      "nonce"      : "0x0000000000000042",
      "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "timestamp"  : "0x00",
      "alloc"      : {}
    }
    初始化命令作用
    mixhash 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。
    nonce nonce就是一个64位随机数,用于挖矿。
    difficulty 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
    alloc 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。
    coinbase 矿工的账号,随便填
    timestamp 设置创世块的时间戳
    parentHash 上一个区块的hash值,因为是创世块,所以这个值是0
    extraData 附加信息,随便填,可以填你的个性信息
    gasLimit 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。

    2、初始化:写入创世区块

    准备好创世区块配置文件后,需要初始化区块链,将上面的创世区块信息写入到区块链中。首先要新建一个目录用来存放区块链数据,假设新建的数据目录为/privatechain/data0,genesis.json保存在/privatechain中,此时目录结构应该是这样的:

    privatechain
    ├── data0
    └── genesis.json
    初始化命令作用
    identity 区块链的标示,随便填写,用于标示目前网络的名字
    init 指定创世块文件的位置,并创建初始块
    datadir 设置当前区块链网络数据存放的位置
    rpc 启动rpc通信,可以进行智能合约的部署和调试
    rpcport HTTP-RPC服务器监听端口(default: 8545)
    rpcapi 设置允许连接的rpc的客户端,默认只有eth,net,web3
    networkid 设置当前区块链的网络ID,用于区分不同的网络,是一个数字
    console 启动命令行模式,可以在Geth中执行命令
    rpccorsdomain 指定一个可以接收请求来源的以逗号间隔的域名列表(浏览器访问的话,要强制指定该选项)

    接下来进入privatechain中,执行初始化命令:

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

    上面的命令的主体是geth init,表示初始化区块链,命令可以带有选项和参数,其中--datadir选项后面跟一个目录名,这里为data0,表示指定数据存放目录为data0,genesis.json是init命令的参数。

    运行上面的命令,会读取genesis.json文件,根据其中的内容,将创世区块写入到区块链中。如果看到以下的输出内容,说明初始化成功了。

    Successfully wrote genesis state... 

    初始化成功后,会在数据目录data0中生成geth和keystore两个文件夹,此时目录结构如下:

    privatechain
    ├── data0
    │   ├── geth
    │   │   └── chaindata
    │   │       ├── 000001.log
    │   │       ├── CURRENT
    │   │       ├── LOCK
    │   │       ├── LOG
    │   │       └── MANIFEST-000000
    │   └── keystore
    └── genesis.json 

    其中 geth/chaindata中存放的是区块数据,keystore中存放的是账户数据。

    3、启动私有链节点

    $ geth --datadir data0 --networkid 1108 console

    运行上面的命令后,就启动了区块链节点并进入了Javascript Console:

    Welcome to the Geth JavaScript console!
     
    instance: Geth/v1.7.3-stable-4bb3c89d/windows-amd64/go1.9
     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
     
    >

    这是一个交互式的Javascript执行环境,在这里面可以执行Javascript代码,其中>是命令提示符。在这个环境里也内置了一些用来操作以太坊的Javascript对象,可以直接使用这些对象。这些对象主要包括:

    • eth:包含一些跟操作区块链相关的方法
    • net:包含以下查看p2p网络状态的方法
    • admin:包含一些与管理节点相关的方法
    • miner:包含启动&停止挖矿的一些方法
    • personal:主要包含一些管理账户的方法
    • txpool:包含一些查看交易内存池的方法
    • web3:包含了以上对象,还包含一些单位换算的方法

    其中常用命令有:

    • personal.newAccount():创建账户;
    • personal.unlockAccount():解锁账户;
    • eth.accounts:枚举系统中的账户;
    • eth.getBalance():查看账户余额,返回值的单位是 Wei(Wei - 是以太坊中最小货币面额单位,类似比特币中的聪,1 ether = 10^18 Wei);
    • eth.blockNumber:列出区块总数;
    • eth.getTransaction():获取交易;
    • eth.getBlock():获取区块;
    • miner.start():开始挖矿;
    • miner.stop():停止挖矿;
    • web3.fromWei():Wei 换算成以太币;
    • web3.toWei():以太币换算成 Wei;
    • txpool.status:交易池中的状态;
    • admin.addPeer():连接到其他节点;

    三、探索Javascript Console

    进入以太坊Javascript Console后,就可以使用里面的内置对象做一些操作,这些内置对象提供的功能很丰富,比如查看区块和交易、创建账户、挖矿、发送交易、部署智能合约等。 接下来介绍几个常用功能,下面的操作中,前面带>的表示在Javascript Console中执行的命令。

    1、创建账户

    前面只是搭建了私有链,并没有自己的账户,可以在js console中输入eth.accounts来验证:

    > eth.accounts
    []

    接下来使用personal对象来创建一个账户:

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

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

    可以创建多个账户。

    账户默认会保存在数据目录的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

    2、查看账户余额

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

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

    3、启动&停止挖矿

    • 通过miner.start()来启动挖矿
    • 通过miner.stop()来停止挖矿

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

    矿工账户: 挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做coinbase,默认情况下coinbase是本地账户中的第一个账户,通过miner.setEtherbase()可将其他账户设置成coinbase。

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

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

    4、发送交易

    可以通过发送一笔交易,从A账户转移N个以太币到B账户;

    注意:

    在交易过程中,无论交易的代币是什么,都需要把这些代币转为 wei 存储在以太坊区块链中。

    amount = web3.toWei(5,'ether')
    "5000000000000000000"

    账户默认是锁住的,想要发送交易,必须先解锁账户,由于我们要从账户0发送交易,所以要解锁账户0:

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

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

    eth.sendTransaction({from:eth.accounts[0],to:"0xc9194a8ea28d76389af4c7e9c81222386a6ab47a",value:amount})
    INFO [11-19|22:56:00] Submitted transaction                    fullhash=0x8f489255235e7008047605b170a4fa5ef7ef951dcbd9ac909f93fd585241e524 recipient=0xC9194A8ea28D76389Af4c7e9C81222386A6aB47A
    "0x8f489255235e7008047605b170a4fa5ef7ef951dcbd9ac909f93fd585241e524"

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

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

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

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

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

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

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

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

    > web3.fromWei(eth.getBalance("0xc9194a8ea28d76389af4c7e9c81222386a6ab47a"),'ether')
    15

    5、查看交易和区块

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

    查看当前区块总数:

    > eth.blockNumber
    180

    通过区块号(高度)查看区块信息,通过交易hash查看交易:

    eth.getBlock(180)
    {
      difficulty: 131072,
      extraData: "0xd783010703846765746885676f312e398777696e646f7773",
      gasLimit: 3744718,
      gasUsed: 21000,
      hash: "0xb6d1170493e84f9f4b7b6631011c9841d9b6263955621d812891efbf63736ad2",
      logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      miner: "0xc16af1f2a86b6d94c44da3c3dbab59f0ef04ad36",
      mixHash: "0xb93b0ce1b706c03fda4690076753dd38d1d5c6d0aa4379b78a06ec63e44ed572",
      nonce: "0x7f23d7e8f136ee0a",
      number: 180,
      parentHash: "0x5881c87a6b38a6a341740f2062724945fb239693234fd8a5b99ac127f5455518",
      receiptsRoot: "0x9b15dee17d0b464e884beee2ae85d2dac54439ed6cd59f84c0acde080d6cf7bd",
      sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      size: 650,
      stateRoot: "0xe5a6c4f89ccb5df8012a2c298b1b5daff46d5db55020271d15fa5a75ac223ef0",
      timestamp: 1542639406,
      totalDifficulty: 24333549,
      transactions: ["0x8f489255235e7008047605b170a4fa5ef7ef951dcbd9ac909f93fd585241e524"],
      transactionsRoot: "0x88572d4389a5f897aafda1176d4398c0023824092024acf5fdec8e513786b7ae",
      uncles: []
    }
    > eth.getTransaction("0x8f489255235e7008047605b170a4fa5ef7ef951dcbd9ac909f93fd585241e524")
    {
      blockHash: "0xb6d1170493e84f9f4b7b6631011c9841d9b6263955621d812891efbf63736ad2",
      blockNumber: 180,
      from: "0x675fda0eac2af486c0b8778ce386150af5140458",
      gas: 90000,
      gasPrice: 18000000000,
      hash: "0x8f489255235e7008047605b170a4fa5ef7ef951dcbd9ac909f93fd585241e524",
      input: "0x",
      nonce: 1,
      r: "0xcba2a0ab3326d0ceb42b42cae8d19dadd54830baa38c5af09bcd33a128e20e3f",
      s: "0x1c9d15e8c1236a7e125fc1095188c73ddbc9151d64327297fe5b59d9fcfceb5f",
      to: "0xc9194a8ea28d76389af4c7e9c81222386a6ab47a",
      transactionIndex: 0,
      v: "0x38",
      value: 15000000000000000000

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

    6、连接到其他节点

    可以通过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可以查看已连接到的节点数量。

    通过多节点验证keystore中的json文件包含账户地址和加密后的私钥。

  • 相关阅读:
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    springboot 整合flowable 项目源码 mybiats vue.js 前后分离 跨域
    flowable Springboot vue.js 前后分离 跨域 有代码生成器 工作流
    Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    java 企业 网站源码 后台 springmvc SSM 前台 静态化 代码生成器
    java 进销存 商户管理 系统 管理 库存管理 销售报表springmvc SSM项目
    基于FPGA的电子计算器设计(中)
    基于FPGA的电子计算器设计(上)
    FPGA零基础学习:SPI 协议驱动设计
    Signal tap 逻辑分析仪使用教程
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/11211600.html
Copyright © 2011-2022 走看看