美文网首页区块链大学区块链研究区块链
以太坊学习笔记(三)——搭建以太坊私链

以太坊学习笔记(三)——搭建以太坊私链

作者: 古川不爱笑 | 来源:发表于2018-09-04 20:14 被阅读30次

    以太坊私链的搭建可以直接通过下载程序进行安装,也可以通过编译源码安装,本文介绍通过编译源码进行安装。

    编译源码

    1.准备环境

    我们下载的是go语言的源码,首先需要正确的安装go语言环境,如何正确安装go语言环境,大家可以去网上找教程。

    2.下载源码

    可以通过go命令行来下载

    go get github.com/ethereum/go-ethereum
    

    也可以通过git工具或直接去官方git https://github.com/ethereum/go-ethereum 载源码,源码一般放在go的源码文件下。

    3.编译源码
    //进入源码文件夹
    cd /你的路径/go-ethereum
    make geth 或者 make all
    

    提示:在安装编译中可能会报“exec: "gcc": executable file not found in %PATH%”错误,是因为没有GCC环境导致的,搜索报错信息就能找到解决的办法。
    GCC下载

    编译成功如下图所示: 编译成功
    4.配置环境变量

    从编译成功的截图我们可以看到,如果要启动geth需要到相应的路径下执行命令,所以我们需要配置环境变量

    vi ~/.bash_profile
    # 打开配置文件,把以下内容添加到文件中
    export GETH="$GOPATH/src/github.com/ethereum/go-ethereum/build"
    export PATH="$PATH:$GETH/bin"
    

    检查是否安装成功

    geth --help
    
    输出如下内容,则表示安装成功了。 安装成功

    搭建私链

    1.创建私链数据存放目录
    //原则上可以在任何地方创建文件夹,但尽量不要在需要管理员权限的路径下创建文件夹,避免不必要的麻烦
    mkdir /文件路径/ethprivatechain
    //data用于存放账户和区块数据
    mkdir /文件路径/ethprivatechain/data 
    
    2.进入刚刚创建的文件夹,使用命令启动私链
    > geth --datadir data --nodiscover console
    
    启动成功

    geth默认端口为8545和30303,mac下可以使用如下命令查看

    lsof -i :30303
    
    3.创建两个账户

    方便后期测试转账,所以创建两个账户

    > personal.newAccount("111111")
    //出现的一串字符,为创建的账户地址
    "0x16dd83d69d8908109da5ce386a924a2b0fdbe80e"
    
    > personal.newAccount("123456")
    "0xaa33b3a596af305e9618777b921570dd1a25215f"
    
    4.查询余额
    > eth.getBalance(eth.accounts[0])
    //查询结果
    0
    
    5.退出geth控制台
    > exit
    //输出信息
    INFO [09-04|15:13:19.802] IPC endpoint closed                      endpoint=/Users/cyril/Desktop/ethprivatechain/data/geth.ipc
    INFO [09-04|15:13:19.803] Blockchain manager stopped 
    INFO [09-04|15:13:19.803] Stopping Ethereum protocol 
    INFO [09-04|15:13:19.803] Ethereum protocol stopped 
    INFO [09-04|15:13:19.803] Transaction pool stopped 
    INFO [09-04|15:13:19.806] Database closed                          database=/Users/cyril/Desktop/ethprivatechain/data/geth/chaindata
    

    创建创世区块

    1.在ethprivatechain下新建genesis.json
    {  
       "alloc": {  
          "0x16dd83d69d8908109da5ce386a924a2b0fdbe80e": {  
          "balance": "100000000000000000000000000"  
          }  
       },  
        "config":{  
            "chainId":100,  
            "homesteadBlock":0,  
            "eip155Block":0,  
            "eip158Block":0  
        },  
        "nonce":"0x0000000000000042",  
        "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",  
        "difficulty": "0x2000",  
        "coinbase":"0xaa33b3a596af305e9618777b921570dd1a25215f",  
        "timestamp": "0x00",  
        "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",  
        "extraData": "",  
        "gasLimit":"0xffffffff"  
    }  
    

    各参数字段的含义:

    • alloc: 用来预置账号以及账号的以太币数量,因为私链挖矿比较容易,所以我们也可以不预置有币的账号,需要的时候自己创建即可。
    • chainId:链的ID,以太坊公链是1,我们要与其不同,以免冲突
    • nonce: nonce就是一个64位随机数,用于挖矿。
    • mixhash:与nonce配合用于挖矿,由上一个区块的一部分生成的hash。
    • difficulty: 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
    • coinbase: 矿工的账号,随便填
    • timestamp: 设置创世块的时间戳
    • parentHash: 上一个区块的hash值,因为是创世块,所以这个值是0
    • extraData: 附加信息,随便填,可以填你的个性信息
    • gasLimit: 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。
    2.初始化创世区块
    > geth --datadir data init genesis.json 
    //输出信息
    INFO [09-04|15:35:46.767] Maximum peer count                       ETH=25 LES=0 total=25
    INFO [09-04|15:35:46.775] Allocated cache and file handles         database=/Users/cyril/Desktop/ethprivatechain/data/geth/chaindata cache=16 handles=16
    INFO [09-04|15:35:46.777] Writing custom genesis block 
    INFO [09-04|15:35:46.777] Persisted trie from memory database      nodes=1 size=151.00B time=117.527µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
    INFO [09-04|15:35:46.778] Successfully wrote genesis state         database=chaindata                                                hash=0e8bb0…a5a328
    INFO [09-04|15:35:46.778] Allocated cache and file handles         database=/Users/cyril/Desktop/ethprivatechain/data/geth/lightchaindata cache=16 handles=16
    INFO [09-04|15:35:46.780] Writing custom genesis block 
    INFO [09-04|15:35:46.780] Persisted trie from memory database      nodes=1 size=151.00B time=91.399µs  gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
    INFO [09-04|15:35:46.780] Successfully wrote genesis state         database=lightchaindata                                                hash=0e8bb0…a5a328
    

    提示:
    如果在执行上面的命令报错


    先删除原来的创世块geth removedb --datadir data
    再初始化创世区块geth --datadir data init genesis.json

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

     tree
    //输出结果
    .
    ├── data
    │   ├── geth
    │   │   ├── LOCK
    │   │   ├── chaindata
    │   │   │   ├── 000001.log
    │   │   │   ├── CURRENT
    │   │   │   ├── LOCK
    │   │   │   ├── LOG
    │   │   │   └── MANIFEST-000000
    │   │   ├── lightchaindata
    │   │   │   ├── 000001.log
    │   │   │   ├── CURRENT
    │   │   │   ├── LOCK
    │   │   │   ├── LOG
    │   │   │   └── MANIFEST-000000
    │   │   ├── nodekey
    │   │   └── transactions.rlp
    │   ├── history
    │   └── keystore
    │       ├── UTC--2018-09-04T06-55-11.166220891Z--16dd83d69d8908109da5ce386a924a2b0fdbe80e
    │       └── UTC--2018-09-04T06-56-21.455326358Z--aa33b3a596af305e9618777b921570dd1a25215f
    └── genesis.json
    

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

    3.进入geth控制台
    > geth --datadir data --networkid 100 console
    //输出信息
    INFO [09-04|16:08:23.164] Maximum peer count                       ETH=25 LES=0 total=25
    INFO [09-04|16:08:23.173] Starting peer-to-peer node               instance=Geth/v1.8.16-unstable/darwin-amd64/go1.10.2
    INFO [09-04|16:08:23.173] Allocated cache and file handles         database=/Users/cyril/Desktop/ethprivatechain/data/geth/chaindata cache=768 handles=128
    INFO [09-04|16:08:23.189] Initialised chain configuration          config="{ChainID: 100 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Constantinople: <nil> Engine: unknown}"
    INFO [09-04|16:08:23.189] Disk storage enabled for ethash caches   dir=/Users/cyril/Desktop/ethprivatechain/data/geth/ethash count=3
    INFO [09-04|16:08:23.189] Disk storage enabled for ethash DAGs     dir=/Users/cyril/.ethash                                  count=2
    INFO [09-04|16:08:23.189] Initialising Ethereum protocol           versions="[63 62]" network=100
    INFO [09-04|16:08:23.191] Loaded most recent local header          number=0 hash=0e8bb0…a5a328 td=8192
    INFO [09-04|16:08:23.191] Loaded most recent local full block      number=0 hash=0e8bb0…a5a328 td=8192
    INFO [09-04|16:08:23.191] Loaded most recent local fast block      number=0 hash=0e8bb0…a5a328 td=8192
    INFO [09-04|16:08:23.192] Loaded local transaction journal         transactions=0 dropped=0
    INFO [09-04|16:08:23.193] Regenerated local transaction journal    transactions=0 accounts=0
    INFO [09-04|16:08:23.194] Starting P2P networking 
    INFO [09-04|16:08:23.223] Mapped network port                      proto=udp extport=30303 intport=30303 interface=NAT-PMP(192.168.31.1)
    INFO [09-04|16:08:23.230] UDP listener up                          self=enode://9c5d2c3e34f13543af0da28c10a6566d2be0eeff1e73a450e26ab94347cbd96ce096dd27573b3960e94458989c72d57fb0160687bc981fcfed0f24c5738a90de@192.168.114.11:30303
    INFO [09-04|16:08:23.230] RLPx listener up                         self=enode://9c5d2c3e34f13543af0da28c10a6566d2be0eeff1e73a450e26ab94347cbd96ce096dd27573b3960e94458989c72d57fb0160687bc981fcfed0f24c5738a90de@192.168.114.11:30303
    INFO [09-04|16:08:23.233] IPC endpoint opened                      url=/Users/cyril/Desktop/ethprivatechain/data/geth.ipc
    INFO [09-04|16:08:23.244] Mapped network port                      proto=tcp extport=30303 intport=30303 interface=NAT-PMP(192.168.31.1)
    Welcome to the Geth JavaScript console!
    
    instance: Geth/v1.8.16-unstable/darwin-amd64/go1.10.2
    INFO [09-04|16:08:23.335] Etherbase automatically configured       address=0x16dD83D69D8908109Da5ce386A924A2b0FdbE80e
    coinbase: 0x16dd83d69d8908109da5ce386a924a2b0fdbe80e
    at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
     datadir: /Users/cyril/Desktop/ethprivatechain/data
     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
    

    提示:
    networkid为上面设置的100

    4.转账交易

    解锁账户

    > personal.unlockAccount(eth.accounts[0], "111111")
    //输出信息
    true
    

    发送交易

    > amount = web3.toWei(10,'ether')
    "10000000000000000000"
    > eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:amount})
    INFO [09-04|16:16:53.161] Setting new local account                address=0x16dD83D69D8908109Da5ce386A924A2b0FdbE80e
    INFO [09-04|16:16:53.161] Submitted transaction                    fullhash=0x0d681856f3115696460abb8b124425be38e130f7f651c805c04b6ec2ec247784 recipient=0xaA33b3a596Af305e9618777b921570DD1a25215f
    "0x0d681856f3115696460abb8b124425be38e130f7f651c805c04b6ec2ec247784"
    

    此时查询账户余额没发生变化,需要进行挖矿确认打包交易

    > eth.getBalance(eth.accounts[1])
    0
    
    5.启动&停止挖矿

    通过miner.start()启动挖矿

    > miner.start(5)
    INFO [09-04|16:20:29.602] Updated mining threads                   threads=5
    INFO [09-04|16:20:29.603] Transaction pool price threshold updated price=1000000000
    

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

    INFO [09-04|16:23:44.403] Generating DAG in progress               epoch=0 percentage=98 elapsed=3m14.115s
    INFO [09-04|16:23:47.190] Generating DAG in progress               epoch=0 percentage=99 elapsed=3m16.901s
    INFO [09-04|16:23:47.193] Generated ethash verification cache      epoch=0 elapsed=3m16.904s
    INFO [09-04|16:23:53.057] Successfully sealed new block            number=1 sealhash=7d40a9…15a0b8 hash=254822…506ae1 elapsed=3m23.446s
    INFO [09-04|16:23:53.058] 🔨 mined potential block                  number=1 hash=254822…506ae1
    INFO [09-04|16:23:53.058] Commit new mining work                   number=2 sealhash=039ae4…231dbf uncles=0 txs=0 gas=0     fees=0       elapsed=172.398µs
    INFO [09-04|16:23:54.818] Successfully sealed new block            number=2 sealhash=039ae4…231dbf hash=71c750…4afcfc elapsed=1.759s
    

    下面的输出信息表示区块已经上链:

    INFO [09-04|16:24:06.431] 🔗 block reached canonical chain          number=1 hash=254822…506ae1
    

    挖矿完成之后查询账户余额

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

    我们可以看到转账的10eth已经到账

    通过miner.stop()停止挖矿

    > miner.stop()
    

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

    > eth.coinbase
    "0x16dd83d69d8908109da5ce386a924a2b0fdbe80e"
    

    我们可以通过miner.setEtherbase() 将其他账户设置成coinbase

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

    重新启动挖矿,查看eth.accounts[1]是否获得以太币

    > miner.start(5)
    
    //等待几秒后
    > miner.stop()
    

    查询账户余额:

    > web3.fromWei(eth.getBalance(eth.accounts[0]), 'ether')
    100000185
    > web3.fromWei(eth.getBalance(eth.accounts[1]), 'ether')
    75
    

    账户0和1都比之前的以太币多,说明挖矿和miner.setEtherbase()设置成功

    6.查看交易信息

    查看当前区块总数:

    > eth.blockNumber
    52
    

    通过区块号查看区块信息:

    > eth.getBlock(0)
    {
      difficulty: 8192,
      extraData: "0x",
      gasLimit: 4294967295,
      gasUsed: 0,
      hash: "0x0e8bb0047f80e98089fd81dd4e077af8e43ccee0e1c8e1a7439b8e5b95a5a328",
      logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      miner: "0xaa33b3a596af305e9618777b921570dd1a25215f",
      mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
      nonce: "0x0000000000000042",
      number: 0,
      parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
      receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      size: 507,
      stateRoot: "0x62815262f2efc4e22af8ac64adc029ba4f38a74969ec68de7b0714771ca06190",
      timestamp: 0,
      totalDifficulty: 8192,
      transactions: [],
      transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      uncles: []
    }
    

    通过交易hash查看交易,hash可以通过上面的输出信息获取:

    > eth.getTransaction("0x0e8bb0047f80e98089fd81dd4e077af8e43ccee0e1c8e1a7439b8e5b95a5a328")
    null
    

    控制台操作命令介绍

    控制台内置了一些用来操作以太坊的 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():停止挖矿;
    • eth.coinbase:挖矿奖励的账户
    • web3.fromWei():Wei 换算成以太币;
    • web3.toWei():以太币换算成 Wei;
    • txpool.status:交易池中的状态;
    • admin.addPeer():连接到其他节点;

    相关文章

      网友评论

        本文标题:以太坊学习笔记(三)——搭建以太坊私链

        本文链接:https://www.haomeiwen.com/subject/rqxgwftx.html