Ethereum初探

转载请注明出处:www.huamo.online
字节杭州 求贤若渴:

  1. https://job.toutiao.com/s/JXTdQaH
  2. https://job.toutiao.com/s/JXTMWW3
  3. https://job.toutiao.com/s/JXT1tpC
  4. https://job.toutiao.com/s/JXTdu6h

运行geth

Ethereum主网上运行全节点

1
$ geth console

该命令将会:

  • 以快速同步模式启动geth(默认值,可以使用--syncmode参数修改),为了避免处理以太坊主网的所有历史数据,它需要下载更多的数据,该过程非常耗费CPU。

  • 启动geth内置的JavaScript console,你可以调用所有官方的web3方法,也可以调用geth自己的控制类API,这个工具是可选的,如果你把它放在外面,也总是可以通过geth attach将其附加到一个已经运行的geth实例上。

Ethereum测试网络上运行全节点

1
$ geth --testnet console

面向开发者的过渡网络,如果你想创建以太坊智能合约来玩转以太坊,那么在整个系统稳定之前,你肯定不想花费任何真钱。换句话说,不加入以太坊主网络,而是将你的节点加入测试网络,除了测试网络上的以太币是假的(play-Ether),测试网络和主网完全一致

虽然是测试网络,但是这里面的console子命令和上一节的功能完全一致。

加上了--testnet标签之后,会对geth实例有一些小小的改动:

  • 不再使用默认的数据目录(比如在Linux中位于~/.ethereum),而是会存储在一个testnet子目录中(在Linux系统下位于~/.ethereum/testnet),注意,在OSXLinux系统下,这还意味着想要附加到一个正在运行的测试网络节点上,geth attach命令还需要附带上自定义的数据路径,因为该命令会默认附加到生产节点上。例如geth attach <datadir>/testnet/geth.ipcWindows用户不受此影响。

  • 不再连入以太坊主网,客户端会连入测试网络,使用不同的P2P启动节点(bootnodes),不同的网络ID以及创世状态。

Rinkeby测试网络上运行全节点

1
$ geth --rinkeby console

上述测试网络是基于ethash工作证明共识算法的跨客户端网络。 因此,由于网络的低难度/低安全性,它有一定的额外开销,并且更容易受到重组攻击(reorganization attacks)。 Go-Ethereum还支持连接到称为Rinkeby的权威证明(proof-of-authority)测试网络(由社区成员运营)。 这个网络更轻,更安全,但只支持go-ethereum

运营一个Ethereum私有网络

运营你自己的私有网络需要更多的工作量,因为很多配置都是用于主网的配置,它们都需要手动重新设置。

1. 定义私有的创世状态

首先,你需要为你自己的网络创建创世状态,所有节点都需要了解并达成一致。这被包含在一个JSON文件中(比如,称之为genesis.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"config": {
"chainId": 0,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}

上述字段适用于绝大多数场景,但是我们还是推荐你将nonce改为其它的随机数,以防止未知的远程节点和你建立连接。如果你想对一些账户预充值方便测试,可以向alloc字段输入账号配置信息:

1
2
3
4
"alloc": {
"0x0000000000000000000000000000000000000001": {"balance": "111111111"},
"0x0000000000000000000000000000000000000002": {"balance": "222222222"}
}

根据上面定义的创世状态,你需要在启动每一个geth节点之前,用这个JSON文件进行初始化,以保证所有的区块链参数都被正确设置:

1
$ geth init path/to/genesis.json

2. 创建集合点(rendezvous point

如果所有要运行的节点都初始化为所需的创世状态,则需要启动引导节点,其他人可以使用它来在网络中和/或通过互联网找到彼此。 简便的方法是配置和运行专用的引导节点:

1
2
$ bootnode --genkey=boot.key
$ bootnode --nodekey=boot.key

引导节点上线后,它会显示一个编码URL,其它节点可以使用该路径连接上引导节点并交换节点信息。确保你使用了外部可访问的IP来拿到真实的编码URL,而不是用显示的IP地址(很大可能是[::]

备注:你也可以使用一个健全的geth节点作为引导节点(即用geth命令,而不是bootnode命令,但是这种方式官方不推荐)。

3. 启动成员节点

在引导节点运行中并且可以从外部访问的情况下(你可以尝试telnet <ip> <port>来确保确实可达),通过--bootnodes标签指向这个引导节点启动后续每一个geth节点,你可能还需要将你的私有网络数据单独存放,所以还需要加上--datadir标签自定义数据存放路径。

1
$ geth --datadir=custom/data/folder --bootnodes=<bootnode-encode-url-from-above>

备注:由于你的网络将与主网和测试网络完全隔离,因此你还需要配置一个矿工来处理交易,并为你挖矿创建新区块。

4. 运行一个私有矿工

在以太坊主网上挖矿是一个复杂的任务,因为它只能使用GPU挖矿,需要一个启用OpenCL或者CUDAethminer实例。想要了解设置信息,请咨询EtherMining subreddit,以及Genoil miner

但是在私有网络中,一个单核CPU矿工实例已经够用了,因为它可以在不需要大量资源的情况下以正确的时间间隔产生稳定的区块流(考虑单线程运行的情况,不需要用到多线程)。要启动一个挖矿的geth实例,请使用通常的标签运行它,并配上如下扩展:

1
$ geth <usual-flags> --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000

这将在一个单核CPU线程上开始挖矿,并将所有的过程记录在由--etherbase指定的账号上。你还可以将默认gas limit改为--targetgaslimit指定的值,并设置交易接受价格为--gasprice指定的值,以进一步调整挖矿。

5. 实操

完成后布局

搭建完成后文件布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ tree -L 2 ./my-private-net
.
├── bootnode-dir
│   └── boot.key
├── datadir1
│   ├── geth
│   ├── geth.ipc
│   └── keystore
├── datadir2
│   ├── geth
│   ├── geth.ipc
│   └── keystore
└── genesis.json
步骤
  1. 编写创世文件:vim genesis.json

  2. 初始化2个节点:

    1
    2
    $ geth init --datadir "./datadir1" ./genesis.json
    $ geth init --datadir "./datadir2" ./genesis.json
  3. 运行bootnode

    1
    2
    3
    4
    $ cd bootnode-dir
    $ bootnode --genkey=boot.key
    $ bootnode --nodekey=boot.key
    INFO [05-07|03:06:24] UDP listener up self=enode://0fd751b41c799962489a9b2b95c6a4815e67abc574fea7cd9208e34bd0092869ba1ba8e9877c246a23428d9e38fb2fba5fed00dabd3dd77644b5628082e9af0e@[::]:30301
  4. 开新窗口,运行节点1:

    1
    $ geth --datadir=./datadir1 --bootnodes=enode://0fd751b41c799962489a9b2b95c6a4815e67abc574fea7cd9208e34bd0092869ba1ba8e9877c246a23428d9e38fb2fba5fed00dabd3dd77644b5628082e9af0e@127.0.0.1:30301
  5. 再开新窗口,运行节点2,并作为矿工:

    1
    $ geth --datadir=./datadir2 --bootnodes=enode://0fd751b41c799962489a9b2b95c6a4815e67abc574fea7cd9208e34bd0092869ba1ba8e9877c246a23428d9e38fb2fba5fed00dabd3dd77644b5628082e9af0e@127.0.0.1:30301 --mine --minerthreads=1 --etherbase=0x26add576232dad627a9102015a7b11763e98f85b --port 30304

JavaScript后台交互

Ethereum实现了一个JS运行时环境(JSRE),可用于交互模式(命令行后台),和非交互模式(脚本)。其中JS后台支持全部的web3 JavaScript Dapp APIadmin API

geth就包含了一个JavaScript后台(一个接入JSREREPL(Read, Evaluate & Print Loop)),可以通过geth console或者geth attach命令启动。console子命令会启动节点并打开后台,attach子命令不会启动节点,而只是尝试打开一个正在运行的geth实例的js后台。

attach会接受endpoint端点指定,以应对geth节点没有运行在默认的ipc端点上,或者仅仅是你想去连其他的rpc接口。

1
2
$ geth --datadir="./datadir1"// 正常启动geth节点
$ geth attach --datadir="./datadir1" //接入该节点的JS console

JS console中转账ETH

  1. 首先,需要genesis.jsonconfig.chainId不为0,否则会导致转账中出现“余额不足”的错误。

  2. 进入后台: geth attach --datadir="./datadir1"

  3. 保证eth.accounts中有账号:可以将keystore文件放在datadir1/keystore/目录下,也可以提前使用geth account new --datadir="./datadir1"创建账号。

  4. 解锁转账账号:personal.unlockAcccount(eth.accounts[0])

  5. 转账:

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

Nix

关于Nix

Nix是一个纯粹的函数式包管理工具,这意味着它对待包的方式,就像类似于Haskell这种纯函数式编程语言对待值一样 – 这些包由函数编译而成并且没有其它副作用。并且一旦编译完成不会再改变。Nix将包存储在Nix store中,一般都在/nix/store目录中,每一个包都有它自己独有的子目录,比如:

1
/nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/

其中b6gvzjyb2pg0...是这个包的唯一标识符,包含了它的一切依赖(是包编译依赖图的一个加密哈希值)。这种方式具有很多很强的特性。

快速开始

这部分是为那些没有耐心读文档的人准备的。更多更深度的信息,你可以阅读后续的章节

  1. 安装单用户Nix

    1
    $ curl https://nixos.org/nix/install | sh
这将会把`Nix`安装在`/nix`下。该安装脚本将会使用`sudo`权限创建`/nix`目录,所以确定一下你拥有足够的权限。(想看其它安装方式,查看[`Installation`](https://nixos.org/nix/manual/#chap-installation))。
  1. channel中查看哪些安装包目前可用:

    1
    2
    3
    4
    5
    6
    7
    $ nix-env -qa
    docbook-xml-4.3
    docbook-xml-4.5
    firefox-33.0.2
    hello-2.9
    libxslt-1.1.28
    ...
  2. channel中安装一些包:

    1
    $ nix-env -i hello ...

    这会下载预先编译好的包;

参考资料

转载请注明出处:www.huamo.online