以太坊源码解析(二)入门

Posted by 姚飞亮 on 2020-07-09

以太坊源码解析(二)入门

入门

Geth入门

要使用Geth,您需要先安装它。您可以通过多种方式安装geth软件。其中包括通过您最喜欢的软件包管理器进行安装;下载独立的预构建二进制文件;作为docker容器运行; 或自己建造。

对于本教程,我们假设您可以轻松下载预构建的二进制文件。如果要使用其他安装方法,请转到“ 安装和构建”部分,并按照您的操作系统的说明进行操作。

下载Geth

我们以独立的二进制文件形式分发所有稳定的发行版和开发版本。这些对于您要执行以下操作的场景很有用:a)安装特定版本的代码(例如,用于可重现的环境);b)安装在无法访问互联网的机器(例如,气隙式计算机)上;或c)不喜欢自动更新,而宁愿手动安装软件。

要下载Geth,请转到“ 下载”页面,然后选择与您的平台匹配的最新稳定版本。

我们创建以下档案:

  • .tar.gzLinux上的32位,64位,ARMv5,ARMv6,ARMv7和ARM64归档文件()
  • .tar.gzmacOS上的64位归档文件()
  • Windows上的32位和64位归档文件(.zip)和安装程序(.exe

创建一个账户

在启动Geth之前,您首先需要创建一个代表密钥对的帐户。使用以下命令创建一个新帐户并为该帐户设置密码:

1
2
3
4
5
6
7
8
9
geth account new

您的新帐户已被密码锁定。请输入密码。不要忘记这个密码。
密钥的公共地址:0x84f16e24293bFC03e7E7b04F5a9366fa18B1215C
密钥文件路径:/Users/apple/Library/Ethereum/keystore/UTC--2020-07-09T07-35-38.728555000Z--84f16e24293bfc03e7e7b04f5a9366fa18b1215c
-你可以和任何人分享你的公共广播。其他人需要它来与你互动。
-你决不能与任何人分享密钥!钥匙控制着你资金的使用!
-你必须备份你的密钥文件!没有钥匙,就无法进入账户资金!
-你必须记住你的密码!没有密码,就不可能解密密钥!

阅读本指南以获取有关导入现有以太坊帐户和该account命令的其他用法的更多详细信息

同步模式

运行Geth将启动一个以太坊节点,该节点可以加入任何现有网络,也可以创建一个新网络。您可以使用--syncmode "{mode}" 参数确定网络中属于哪种节点,以三种不同的同步模式之一启动Geth 。

这些是:

  • full完整:下载所有块(包括标题,交易和收据),并通过执行每个块来增量生成区块链的状态。
  • fast快速(默认):下载所有块(包括标题,交易和收据),验证所有标题,然后下载状态并针对标题进行验证。
  • light浅:下载所有块标题,块数据,并随机进行验证。
1
2
geth --syncmode "light"
# /Users/apple/Library/Ethereum/

Javascript控制台

拥有帐户并运行Geth后,您可以通过打开另一个终端并使用以下命令打开JavaScript控制台来与之交互:

1
2
3
4
5
6
7
geth attach

Welcome to the Geth JavaScript console!
instance: Geth/v1.9.16-unstable-6d8e51ab-20200707/darwin-amd64/go1.14
at block: 0 (Thu Jan 01 1970 08:00:00 GMT+0800 (CST))
datadir: /Users/apple/Library/Ethereum
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 les:1.0 lespay:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

如果出现错误“无法附加到远程geth”,请尝试通过HTTP连接,如下所示:

1
geth attach http://127.0.0.1:8545

在控制台中,您可以发出任何Geth命令,例如,列出节点上的所有帐户,请使用:

1
2
> eth.accounts
["0x84f16e24293bfc03e7e7b04f5a9366fa18b1215c"]

使用以下console命令启动节点时,也可以直接进入控制台:

1
geth console --syncmode "light"

开发模式

Geth的开发模式可以建立一个单节点以太坊测试网络,并提供针对在本地计算机上进行开发而优化的选项。使用--dev参数启用它。

在开发人员模式下启动geth会执行以下操作:

  • 用测试创世块初始化数据目录
  • 将最大对等体设置为0
  • 关闭其他节点的发现
  • 将汽油价格设置为0
  • 使用Clique PoA共识引擎,可根据需要挖掘块,而不会占用过多的CPU和内存
  • 使用按需块生成,在等待挖掘交易时生成块

在开发人员模式下启动Geth

您可以使用该--datadir选项指定数据目录以维护两次运行之间的状态,否则,数据库为临时数据库和内存数据库:

1
mkdir test-chain-dir

对于本指南,请在开发人员模式下启动geth,然后启用RPC,以便可以将其他应用程序连接到geth。对于本指南,我们使用基于Web的以太坊IDE Remix,因此也允许其域接受跨域请求。

1
geth --datadir test-chain-dir --rpc --dev --rpccorsdomain "https://remix.ethereum.org,http://remix.ethereum.org"

各选项含义如下:

  • --identity:指定节点 ID;
  • --rpc:表示开启 HTTP-RPC 服务;
  • --rpcaddr:HTTP-RPC 服务ip地址;
  • --rpcport:指定 HTTP-RPC 服务监听端口号(默认为 8545);
  • --datadir:指定区块链数据的存储位置;
  • --port:指定和其他节点连接所用的端口号(默认为 30303);
  • --nodiscover:关闭节点发现机制,防止加入有同样初始配置的陌生节点。
1
2
3
4
5
6
7
8
9
mkdir data
geth --networkid 123 --dev --datadir data --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --port 30303 console

Welcome to the Geth JavaScript console!
instance: Geth/v1.9.16-unstable-6d8e51ab-20200707/darwin-amd64/go1.14
coinbase: 0x0caad1f289fdfdf0a0988d2f4239caa2453d73cc
at block: 0 (Thu Jan 01 1970 08:00:00 GMT+0800 (CST))
datadir: /Users/apple/Documents/app/go_project/src/github.com/ethereum/go-ethereum/build/bin/data
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0

为了方便操作,我们将上面的命令存为init.sh:

1
2
3
4
5
nano init.sh
//输入
geth --networkid 123 --dev --datadir data --rpc --rpcaddr 192.168.43.52 --rpcport 8545 --port 30303 console
//赋予执行权限
chmod 775 init.sh

从另一个终端窗口连接到节点上的IPC控制台

保持节点的运行,不要关闭终端,重新打开一个终端,使用geth attach连接节点,并且打开geth console

1
2
geth attach <IPC_LOCATION>
geth attach ipc:data/geth.ipc

为了方便操作,我们将上面的命令存为connect.sh:

1
2
3
4
5
nano connect.sh
//输入
geth attach ipc:data/geth.ipc
//赋予执行权限
chmod 775 connect.sh

一旦geth在开发模式下运行,您就可以与geth以其他方式运行时相同的方式与之交互。

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

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

例如,创建一个测试帐户:

1
2
3
4
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0xd981f82235febaa46d23a6c4be45abccb9310a95"

查看账户

1
2
> personal.listAccounts
["0x0caad1f289fdfdf0a0988d2f4239caa2453d73cc", "0xd981f82235febaa46d23a6c4be45abccb9310a95"]

并将以太币从币库转移到新帐户:

1
> eth.sendTransaction({from:eth.coinbase, to:eth.accounts[1], value: web3.toWei(0.05, "ether")})

并检查帐户余额:

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

如果要使用实际的阻止时间测试dapp,请在使用参数--dev.period启动开发人员模式时使用该选项--dev.period 14

web3命令

查看创世账户

1
2
> web3.eth.coinbase
"0x0caad1f289fdfdf0a0988d2f4239caa2453d73cc"

获取账户

1
2
> personal.listAccounts[1]
"0xd981f82235febaa46d23a6c4be45abccb9310a95"

查看账户余额

1
2
3
4
eth.getBalance("账户地址")
//eth.getBalance("0x0caad1f289fdfdf0a0988d2f4239caa2453d73cc")
//eth.getBalance(personal.listAccounts[0])
//eth.getBalance(personal.listAccounts[1])

开始挖矿

1
miner.start();

停止挖矿

1
miner.stop();

终端1账户0向账户1转账

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//解锁账户0(密码为空)
personal.unlockAccount(personal.listAccounts[0]);
//以太币转wei
amount = web3.toWei(5,'ether');
//转账
eth.sendTransaction({from:personal.listAccounts[0],to:personal.listAccounts[1],value:amount});
//查看交易状态
txpool.status
//查看区块信息
eth.getBlock("pending",true);

{
difficulty: 2,
extraData: "0xd783010910846765746886676f312e31348664617277696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
gasLimit: 6301605,
gasUsed: 0,
hash: null,
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: null,
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: null,
number: 3,
parentHash: "0x1100bb5dbf6803d444b79ddc128ebb21485879cc5d6ad563e6ff97cb2a49b841",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 606,
stateRoot: "0x0f2bff95db3fcaefdce401685cdddd5780b47e054e427611e3bebd37612e04cb",
timestamp: 1594311926,
totalDifficulty: 0,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}

//开始挖矿
miner.start();
//停止挖矿
miner.stop();
//查看交易状态
txpool.status
//查看账户1的余额
eth.getBalance(personal.listAccounts[1])
//转账成功!!!
//查看区块数
eth.blockNumber
//查看交易信息
eth.getTransaction("0x7811782799fb175f9576848f1928031dcc25248c4ebf218764ee6296159f53c4")

{
blockHash: "0x1100bb5dbf6803d444b79ddc128ebb21485879cc5d6ad563e6ff97cb2a49b841",
blockNumber: 2,
from: "0x0caad1f289fdfdf0a0988d2f4239caa2453d73cc",
gas: 21000,
gasPrice: 1,
hash: "0x7811782799fb175f9576848f1928031dcc25248c4ebf218764ee6296159f53c4",
input: "0x",
nonce: 1,
r: "0x8e08d5260f970e0879525ae515b47508f358a84cdda053110bcc3062f380fea7",
s: "0x4a8d2c63aa5bba7af84d84fdbe59a79620dd67e72f9a1ca40cd9a2ab8471d87",
to: "0xd981f82235febaa46d23a6c4be45abccb9310a95",
transactionIndex: 0,
v: "0xa96",
value: 5000000000000000000
}

//查看区块信息(区块号)
eth.getBlock(1)

将Remix连接到Geth

在运行geth的情况下,打开https://remix.ethereum.org。正常编译合同,但是在部署和运行合同时,请从“ 环境”下拉列表中选择“ Web3提供程序 ”,然后在弹出框中添加“ http://127.0.0.1:8545”。点击*部署*,然后与合同进行交互。您应该看到合同创建,挖掘和交易活动。

专用网络教程

该页面介绍了如何设置本地节点集群,建议如何使其成为私有集群以及如何在eth-netstat网络监视应用程序上连接节点。完全受控的以太坊网络可用作网络集成测试的后端(从事与网络/区块链同步/消息传播等问题相关的核心开发人员,或测试多块和多用户方案的DAPP开发人员)。

我们假设您能够geth按照构建说明进行构建

设置多个节点

为了在本地运行多个以太坊节点,您必须确保:

  • 每个实例都有一个单独的数据目录(--datadir
  • 每个实例都在不同的端口(eth和rpc)上运行(--port and --rpcport
  • 如果是集群,则实例必须彼此了解
  • ipc端点是唯一的或ipc接口已禁用(--ipcpath or --ipcdisable

您启动第一个节点(让我们显式设置端口并禁用ipc接口)

1
2
3
geth --datadir tmpdata1 -verbosity 6 --ipcdisable --port 30301 --rpcport 8101 console 2>> tmpdata1/01.log

geth --networkid 123 --dev --datadir data --rpc --rpcaddr 127.0.0.1 --rpcport 8101 --port 30301 console

我们使用控制台启动了节点,因此我们可以获取例如enode URL:

1
2
> admin.nodeInfo.enode
"enode://6db6081e945d0457d25e062bc8454f1b8fbe2fcb0bff6771a3439a3bc9fe75e1c230932172309763f8c49bda89aa9aa1a631856ba92661e07c7c46f07ac76da3@127.0.0.1:63867?discport=0"

[::]将被解析为localhost(127.0.0.1)。如果您的节点在本地网络上,请检查每台主机,并使用ifconfig(在Linux和MacOS上)找到您的IP :

1
2
3
$ ifconfig|grep netmask|awk '{print $2}'
127.0.0.1
192.168.43.52

如果您的对等设备不在本地网络上,则需要知道您的外部IP地址(使用服务)来构造enode URL。

现在,您可以使用以下命令启动第二个节点:

1
2
3
geth --datadir tmpdata1 -verbosity 6 --ipcdisable --port 30301 --rpcport 8101 console 1>> tmpdata1/01.log

geth --datadir tmpdata2 -verbosity 6 --ipcdisable --port 30302 --rpcport 8102 console 2>> tmpdata2/01.log

如果要将此实例连接到先前启动的节点,则可以使用从控制台将其添加为对等实例admin.addPeer(enodeUrlOfFirstInstance)

您可以通过在geth控制台中键入来测试连接:

1
2
3
4
5
6
> net.listening
true
> net.peerCount
1
> admin.peers
...

本地集群

作为上述扩展,您可以轻松生成本地节点集群。还可以编写脚本,包括进行挖掘所需的帐户创建。有关gethcluster.sh用法和示例,请参见 脚本和自述文件。

专用网

请参阅[[专用网络页面 | 专用网络]]。

设置引导节点

节点第一次连接到网络时,将使用预定义的引导节点之一 。通过这些引导节点,一个节点可以加入网络并找到其他节点。在专用群集的情况下,这些预定义的引导节点用处不大。因此,go-ethereum提供了可以在您的专用网络中配置和运行的bootnode实现。

可以通过命令运行。

1
2
3
4
> bootnode
Fatal: Use -nodekey or -nodekeyhex to specify a private key
引导节点
致命:使用-nodekey或-nodekeyhex指定私钥

可以看出,bootnode要求输入密钥。每个以太坊节点(包括引导节点)由一个enode标识符标识。这些标识符是从密钥派生的。因此,您将需要为bootnode提供此类密钥。由于我们目前没有,我们可以指示bootnode在启动之前生成密钥(并将其存储在文件中)。

1
> bootnode -genkey bootnode.key

可以通过以下方式查看存储的密钥

1
2
> cat bootnode.key
11042159d89a7a42ac23463ae4b02881c8ac73e2f99cffd0f88cf32b7e186306

要指示geth节点使用我们自己的bootnode,请使用--bootnodes标志。这是逗号分隔的引导节点enode标识符列表。

1
geth --bootnodes "enode://890b6b5367ef6072455fedbd7a24ebac239d442b18c5ab9d26f58a349dad35ee5783a0dd543e4f454fed22db9772efe28a3ed6f21e75674ef6203e47803da682@[::]:30301"

[::]前面已经解释了什么意思)

因为每次使用相同的enode来启动bootnode都很方便,所以我们可以在下次启动时给bootnode程序刚刚生成的密钥。

1
2
3
4
5
bootnode -nodekey bootnode.key
enode://840dd3574337a628c9b38c6faca48f6fbb24e5f53662e7229eac553624b7ad8bafc910092ec9bb7b6072386d2d14cd88b0de8dfbae811d2b999f2d1750845933@127.0.0.1:0?discport=30301
Note: you're using cmd/bootnode, a developer tool.
We recommend using a regular node as bootstrap node for production deployments.
INFO [07-10|11:25:11.174] New local node record

要么

1
2
3
4
5
bootnode -nodekeyhex 11042159d89a7a42ac23463ae4b02881c8ac73e2f99cffd0f88cf32b7e186306
enode://840dd3574337a628c9b38c6faca48f6fbb24e5f53662e7229eac553624b7ad8bafc910092ec9bb7b6072386d2d14cd88b0de8dfbae811d2b999f2d1750845933@127.0.0.1:0?discport=30301
Note: you're using cmd/bootnode, a developer tool.
We recommend using a regular node as bootstrap node for production deployments.
INFO [07-10|11:27:13.067] New local node record seq=1 id=7cd00f8c425b2bb7 ip=<nil> udp=0 tcp=0

监控节点

本页介绍如何使用 以太坊(集中式)网络状态监视器。监视您的节点。

此页面本自述文件 描述了如何为(私有或公共)本地集群设置自己的监视服务。



Ω