Dapp开发以太坊- Ethereum

以太坊开发(三)使用 Go-Ethereum 1.8.1搭建以太

2018-02-25  本文已影响683人  yuyangray

什么是 Go-Ethereum

Go-Ethereum是由以太坊基金会提供的官方客户端软件。它是用Go编程语言编写的,简称Geth。

Geth是以太坊协议的具体落地实现,通过Geth,你可以实现以太坊的各种功能,如账户的新建编辑删除,开启挖矿,ether币的转移,智能合约的部署和执行等等。

Geth官网:https://geth.ethereum.org/
Geth的Github地址:https://github.com/ethereum/go-ethereum

本文环境:

Mac OS 10.13.3

Homebrew v1.5.4

Geth v1.8.1

Geth的安装

这里使用Homebrew演示在Mac OS上的下载安装

首先安装Homebrew

Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷。

Homebrew官网:https://brew.sh

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装完成后查看版本信息,确认是否安装成功

yuyangdeMacBook-Pro:~ yuyang$ brew -v
Homebrew 1.5.4
Homebrew/homebrew-core (git revision 68c5; last commit 2018-02-19)

安装Geth

brew tap ethereum/ethereum
brew install ethereum

安装完成后,查看版本后确认安装是否成功

yuyangdeMacBook-Pro:~ yuyang$ geth version
Geth
Version: 1.8.1-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: darwin
GOPATH=
GOROOT=/usr/local/opt/go/libexec

如果安装失败

我当时安装一直失败,忘了截图错误原因了。后来查了很久,找到了一篇可能的解决方法(但我不确定我当时就是文中的错误信息)。用了文中方法失败,然后我又尝试运行安装Geth的两条指令,结果安装成功。

Got an error while installing cpp-ethereum using brew.
https://github.com/ethereum/homebrew-ethereum/issues/116

<Install Xcode or the CLI from developer.apple.com/xcode>

brew update
brew upgrade
brew tap ethereum/ethereum
brew reinstall llvm

<At this point, close the terminal, and relaunch it.>

brew install leveldb libmicrohttpd cryptopp
brew install cpp-ethereum --devel --successful --verbose

简单理解就是:

  1. 安装Xcode或者CLI(我是把两个都安装了)
    • Xcode直接去AppStore安装。

    • CLI一款能用命令行自由操作各种软件获取各种系统信息的工具。

      安装命令:

       sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/install)
      

      安装完成后查看是否成功:

      yuyangdeMacBook-Pro:~ yuyang$ Mac list
      
        mac CLI – OS X command line tools for developers
      

      关于CLI的使用可以查看这篇文章

  1. 执行以下命令:

    brew update
    brew upgrade
    brew tap ethereum/ethereum
    brew reinstall llvm

  2. 完成后重启命令行

  3. 执行以下命令:

    brew install leveldb libmicrohttpd cryptopp
    brew install cpp-ethereum --devel --successful --verbose
    

这是解决办法提供者对此的解释:

Running all those commands will install the latest version of the C++ Ethereum client using the develop branch that has successfully passed CI.

创建以太坊私有链

初始化一个创世区块

初始化创世区块时,要先创建一个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的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件
nonce nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件
difficulty 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
alloc 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以
coinbase 矿工的账号,随便填
timestamp 设置创世块的时间戳
parentHash 上一个区块的hash值,因为是创世块,所以这个值是0
extraData 附加信息,随便填,可以填你的个性信息
gasLimit 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大

接下来,创建项目目录,然后使用geth init ./genesis.json --datadir "./chain"命令,来进行创世区块的初始化,当前区块链网络数据存放的位置会保存在chain目录中:

yuyangdeMacBook-Pro:~ yuyang$ mkdir TestGeth
yuyangdeMacBook-Pro:~ yuyang$ cd TestGeth
yuyangdeMacBook-Pro:TestGeth yuyang$ geth init ./genesis.json --datadir "./chain"
INFO [02-24|11:08:41] Maximum peer count                       ETH=25 LES=0 total=25
INFO [02-24|11:08:41] Allocated cache and file handles         database=/Users/yuyang/TestGeth/chain/geth/chaindata cache=16 handles=16
INFO [02-24|11:08:41] Writing custom genesis block 
INFO [02-24|11:08:41] Persisted trie from memory database      nodes=0 size=0.00B time=10.106µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-24|11:08:41] Successfully wrote genesis state         database=chaindata                                   hash=5e1fc7…d790e0
INFO [02-24|11:08:41] Allocated cache and file handles         database=/Users/yuyang/TestGeth/chain/geth/lightchaindata cache=16 handles=16
INFO [02-24|11:08:41] Writing custom genesis block 
INFO [02-24|11:08:41] Persisted trie from memory database      nodes=0 size=0.00B time=1.743µs  gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-24|11:08:41] Successfully wrote genesis state         database=lightchaindata                                   hash=5e1fc7…d790e0

启用私有链

使用以下命令,启用私有链,并创建log日志文件:

geth \
  --datadir "./chain" \
  --nodiscover \
  console 2>>eth_output.log

启动后的效果如下:

yuyangdeMacBook-Pro:TestGeth yuyang$ geth \
>   --datadir "./chain" \
>   --nodiscover \
>   console 2>>eth_output.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.1-stable/darwin-amd64/go1.10
 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
参数名称 参数描述
datadir 设置当前区块链网络数据存放的位置
console 启动命令行模式,可以在Geth中执行命令
nodiscover 私有链地址,不会被网上看到

在当前目录执行tail -f eth_output.log,可以看到输出日志(需要新开命令行)。

yuyangdeMacBook-Pro:~ yuyang$ cd /Users/yuyang/TestGeth 
yuyangdeMacBook-Pro:TestGeth yuyang$ tail -f eth_output.log
INFO [02-24|12:03:49] Disk storage enabled for ethash caches   dir=/Users/yuyang/TestGeth/chain/geth/ethash count=3
INFO [02-24|12:03:49] Disk storage enabled for ethash DAGs     dir=/Users/yuyang/.ethash                    count=2
INFO [02-24|12:03:49] Initialising Ethereum protocol           versions="[63 62]" network=1
INFO [02-24|12:03:49] Loaded most recent local header          number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Loaded most recent local full block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Loaded most recent local fast block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Regenerated local transaction journal    transactions=0 accounts=0
INFO [02-24|12:03:49] Starting P2P networking 
INFO [02-24|12:03:49] RLPx listener up                         self="enode://f49cd7741cb1e91624d284aa7896a3dca1bedfcc36a6a99f05e2f0bdd1c6f830c59391b2c47493eeafd7d9ca6fff0720a1ab5ebc20627b1314cdbc1dfc86c351@[::]:30303?discport=0"
INFO [02-24|12:03:49] IPC endpoint opened                      url=/Users/yuyang/TestGeth/chain/geth.ipc

在私有链中进行操作

帐户的添加和查看

查看帐户,可以看到当前帐户是空的

> web3.eth.accounts
[]

创建帐户的方式有两种,第一种创建帐户时直接初始化密码

> web3,personal.newAccount("123456")
"0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe"

其中返回的0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe是帐户,123456是帐户的密码

第二种方法是先创建账户,然后输入密码

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

这时我们再查看帐户,能够看到刚才创建的两个帐户已经存在了

> web3.eth.accounts
["0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe", "0x69c9e2942557b25e4967672a72ee7b8f8c531a1c"]

开始挖矿和停止挖矿

挖矿执行以下命令:

> miner.start()
null

执行以后,通过刚才查看日志的方法tail -f eth_output.log,能够看到类似下面的日志,说明挖矿已经在进行。

INFO [02-24|12:33:12] Commit new mining work                   number=83 txs=0 uncles=0 elapsed=2.005s
INFO [02-24|12:33:13] Successfully sealed new block            number=83 hash=b72b9d…c117b8
INFO [02-24|12:33:13] 🔗 block reached canonical chain          number=78 hash=85741d…4330d5
INFO [02-24|12:33:13] 🔨 mined potential block                  number=83 hash=b72b9d…c117b8
INFO [02-24|12:33:13] Commit new mining work                   number=84 txs=0 uncles=0 elapsed=165.913µs
INFO [02-24|12:33:13] Successfully sealed new block            number=84 hash=46555c…078e21
INFO [02-24|12:33:13] 🔗 block reached canonical chain          number=79 hash=2d948b…ea81da
INFO [02-24|12:33:13] 🔨 mined potential block                  number=84 hash=46555c…078e21

挖矿会默认保存到创建的第一个帐户0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe中。
block number=79,说明我们已经创建了79个区块。
在以太坊官方的网络上,平均每15秒产生一个区块。

停止挖矿执行以下命令:

> miner.stop()
true

停止挖矿后,以太币则不会产生,同样智能合约、转帐等操作也不会起作用。

查看账户余额

查看帐户余额的方法如下:

> web3.eth.getBalance("0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe")
425000000000000000000
> web3.eth.getBalance("0x69c9e2942557b25e4967672a72ee7b8f8c531a1c")
0

每次记一长串的地址很麻烦,我们可以通过设置变量来acc0表示帐户1
0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe,acc1表示帐户2
0x69c9e2942557b25e4967672a72ee7b8f8c531a1c

> acc0 = web3.eth.accounts[0]
"0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe"
> acc1 = web3.eth.accounts[1]
"0x69c9e2942557b25e4967672a72ee7b8f8c531a1c"
> web3.eth.getBalance(acc0)
425000000000000000000
> web3.eth.getBalance(acc1)
0

使用下面方法可以查看格式化的以太币:

> web3.fromWei(web3.eth.getBalance(acc0))
425

以太币最小的单位是wei(18个0)

因为geth javascript console是基于javascript的,所以也可以创建js函数,查看所有帐户余额。

> function checkAllBalances() {
...      var totalBal = 0;
...      for (var acctNum in eth.accounts) {
......          var acct = eth.accounts[acctNum];
......          var acctBal = web3.fromWei(eth.getBalance(acct), "ether");
......          totalBal += parseFloat(acctBal);
......          console.log("  eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether");
......      }
...      console.log("  Total balance: " + totalBal + " ether");
...  };
undefined
> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 425 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 0 ether
  Total balance: 425 ether
undefined

转帐操作

从帐户0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe转3个以太币到0x69c9e2942557b25e4967672a72ee7b8f8c531a1c,如果不指定单位ether,默认转的是wei。

> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"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

当直接执行此方法时会抛出异常,显示帐号被锁。

解锁转帐帐户:

> web3.personal.unlockAccount(acc0,"123456")
true

解锁完成之后,即可执行转账操作:

> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")})
"0x23d65dd8c4d8b26b820013fff0f1c70fd50f2e471ea58b3041389f6746ed02e2"

但此时查看时会发现接收账户依旧为原来数值。此时需要执行挖矿命令,才会把转账真正完成。

> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 425 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 0 ether
  Total balance: 425 ether
undefined
> miner.start()
null
> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 547 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 3 ether
  Total balance: 550 ether
undefined
> miner.stop()
true

acc1余额增加是因为启动挖矿后又有以太币进账。

fromWei和toWei

> web3.fromWei("425000000000000000000", "ether")
"425"
> web3.toWei("1", "ether")
"1000000000000000000"

参考:

  1. 使用 Go-Ethereum 1.7.2搭建以太坊私有链
    作者:迦壹
  2. 区块链学堂(5):Geth 安装
    作者:以太中文网
上一篇下一篇

猜你喜欢

热点阅读