以太坊源码解析(一)
项目地址:https://github.com/ethereum/go-ethereum
cd /Users/apple/Documents/app/go_project/src/github.com/ethereum/go-ethereum
项目构建
构建geth
需要Go(1.13版或更高版本)和C编译器。您可以使用自己喜欢的软件包管理器来安装它们。
安装依赖项后,运行
1 | make geth |
或者,构建全套实用程序:
1 | make all |
go-ethereum项目随附在cmd
目录中找到的几个包装器/可执行文件。
命令 | 描述 |
---|---|
geth |
我们主要的以太坊CLI客户端。它是以太坊网络(主,测试或私有网络)的入口点,可以作为完整节点(默认),存档节点(保留所有历史状态)或轻节点(实时获取数据)运行。其他进程可以通过暴露在HTTP,WebSocket和/或IPC传输之上的JSON RPC终结点,将其用作进入以太坊网络的网关。geth --help 以及命令行选项的CLI Wiki页面。 |
abigen |
源代码生成器,用于将以太坊合同定义转换为易于使用的,编译时类型安全的Go软件包。如果还提供了合约字节码,它可以在具有扩展功能的普通以太坊合约ABI上运行。但是,它也接受Solidity源文件,从而使开发更加简化。有关详细信息,请参见我们的Native DApps Wiki页面。 |
bootnode |
我们的以太坊客户端实现的精简版本,仅参与网络节点发现协议,但不运行任何更高级别的应用程序协议。它可用作轻型引导节点,以帮助在专用网络中查找对等节点。 |
evm |
EVM(以太坊虚拟机)的开发人员实用程序版本,能够在可配置的环境和执行模式下运行字节码摘要。其目的是允许对EVM操作码(例如evm --code 60ff60ff --debug run )进行隔离的细粒度调试。 |
gethrpctest |
开发人员实用工具,用于支持我们的以太坊/ rpc-test测试套件,该套件可验证与以太坊JSON RPC规范的基准一致性。有关详细信息,请参阅测试套件的自述文件。 |
rlpdump |
开发人员实用程序工具,用于将二进制RLP(递归长度前缀)转储(以太坊协议使用的数据编码,无论是网络还是共识方式)转换为用户友好的层次表示形式(例如rlpdump --hex CE0183FFFFFFC4C304050583616263 )。 |
puppeth |
一个CLI向导,可帮助创建新的以太坊网络。 |
太坊CLI客户端 geth
以太坊主网络上的完整节点
最常见的情况是人们只想与以太坊网络进行交互:创建帐户;转移资金; 部署合同并与之交互。对于这种特定的用例,用户无需关心已有多年的历史数据,因此我们可以快速快速同步到网络的当前状态。
1 | # 以太坊主网络上的完整节点 |
该命令将:
geth
以快速同步模式启动(默认情况下,可以用该--syncmode
标志更改),从而使其下载更多数据作为交换,从而避免处理以太坊网络的整个历史记录,这是占用大量CPU的资源。- 启动
geth
内置的交互式JavaScript控制台(通过结尾的console
子命令),您可以通过该控制台调用所有官方web3
方法 以及geth
自己的管理API。该工具是可选的,如果不使用它,则可以始终使用附加到已在运行的geth
实例geth attach
。
–goerli测试网络
1 | $ geth --goerli console |
与其使用默认的数据目录(
~/.ethereum
例如,在Linux上),geth
不如将其自身嵌套更深一层到goerli
子文件夹(~/.ethereum/goerli
在Linux上)。请注意,在OSX和Linux上,这还意味着附加到运行中的testnet节点需要使用自定义端点,因为geth attach
默认情况下它将尝试附加到生产节点端点geth attach /goerli/geth.ipc
。Windows用户不受此影响。
–rinkeby测试网络
Go Ethereum还支持连接到称为Rinkeby的较早的基于权威证明的测试网络,该网络由社区成员运营
1 | $ geth --rinkeby console |
–ropsten测试网络
除了Görli和Rinkeby,Geth还支持古老的Ropsten测试网。Ropsten测试网络基于Ethash工作量证明共识算法。这样,它具有一定的额外开销,并且由于网络的低难度/安全性而更容易受到重组攻击的影响。
注意:较旧的Geth配置将Ropsten数据库存储在
testnet
子目录中。
1 | $ geth --ropsten console |
配置
除了将大量标志传递给geth
二进制文件之外,还可以通过以下方式传递配置文件
1 | $ geth --config /path/to/your_config.toml |
要了解文件的外观,可以使用dumpconfig
子命令导出现有配置:
1 | $ geth --your-favourite-flags dumpconfig |
注意:这仅适用于
geth
v1.6.0及更高版本。
Docker快速入门
在机器上启动并运行以太坊的最快方法之一是使用Docker:
1 | docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ |
geth
就像上面的命令一样,它将以1GB的DB内存配额在快速同步模式下启动。它还将在您的主目录中创建一个持久卷,以保存您的区块链并映射默认端口。还有一个alpine
标签可用于图像的精简版。
--rpcaddr 0.0.0.0
如果您想从其他容器和/或主机访问RPC,请不要忘记。默认情况下,geth
绑定到本地接口,并且无法从外部访问RPC端点。
以编程方式接口geth
节点
作为一名开发人员,您希望早晚geth
通过您自己的程序而不是通过控制台手动与以太坊网络进行交互。为此,geth
内置支持基于JSON-RPC的API(标准API 和geth
特定API)。这些可以通过HTTP,WebSocket和IPC(在基于UNIX的平台上为UNIX套接字,在Windows上为命名管道)公开。
IPC接口默认情况下处于启用状态,并且公开了所支持的所有API geth
,而出于安全原因,HTTP和WS接口需要手动启用,并且仅公开一部分API。可以按照您的期望打开/关闭和配置它们。
基于HTTP的JSON-RPC API选项:
--rpc
启用HTTP-RPC服务器--rpcaddr
HTTP-RPC服务器侦听端口(默认:localhost
)--rpcport
HTTP-RPC服务器侦听端口(默认值:8545
)--rpcapi
API的通过HTTP-RPC接口提供的(默认:eth,net,web3
)--rpccorsdomain
逗号分隔的域列表,从中接受跨域请求(强制浏览器)--ws
启用WS-RPC服务器--wsaddr
WS-RPC服务器侦听端口(默认:localhost
)--wsport
WS-RPC服务器侦听端口(默认值:8546
)--wsapi
API的在WS-RPC接口提供的(默认:eth,net,web3
)--wsorigins
接受网络套接字请求的来源--ipcdisable
禁用IPC-RPC服务器--ipcapi
API的在IPC-RPC接口提供的(默认:admin,debug,eth,miner,net,personal,shh,txpool,web3
)--ipcpath
datadir中IPC套接字/管道的文件名(显式路径对其进行转义)
您将需要使用自己的编程环境的功能(库,工具等)通过HTTP,WS或IPC连接到geth
配置有上述标志的节点,并且需要在所有传输方式上使用JSON-RPC。您可以将同一连接重用于多个请求!
注意:在执行此操作之前,请了解打开基于HTTP / WS的传输的安全性!互联网上的黑客正在积极尝试使用公开的API来破坏以太坊节点!此外,所有浏览器选项卡都可以访问本地运行的Web服务器,因此恶意网页可能试图破坏本地可用的API!
运营私人网络
维护您自己的专用网络会更加繁琐,因为需要手动设置许多在官方网络中理所当然的配置。
定义私人起源状态
首先,您需要创建网络的起源状态,所有节点都需要了解并达成共识。这由一个小的JSON文件(例如称为genesis.json
)组成:
1 | { |
尽管我们建议将更nonce
改为一些随机值,但上述字段对于大多数用途还是不错的,这样可以防止未知的远程节点能够连接到您。如果您想为一些帐户预先注资以进行更轻松的测试,请创建帐户并在其alloc
字段中填充其地址。
1 | "alloc": { |
使用上述JSON文件中定义的创始状态,您需要在启动每个 geth
节点之前对其进行初始化,以确保正确设置所有区块链参数:
1 | $ geth init path/to/genesis.json |
创建集合点
将要运行的所有节点初始化为所需的创始状态后,您需要启动一个引导节点,其他节点可以使用该节点在网络和/或Internet上相互查找。干净的方法是配置并运行专用的引导节点:
1 | $ bootnode --genkey = boot.key |
引导节点在线时,它将显示一个enode
URL ,其他节点可以使用该URL连接到该节点并交换对等信息。确保[::]
使用外部可访问的IP 替换显示的IP地址信息(最有可能是),以获取实际的enode
URL。
注意:您也可以将成熟的
geth
节点用作引导节点,但这是不建议使用的方法。
启动您的成员节点
在bootnode可操作且在外部可访问(您可以尝试 telnet
确保它确实可访问)的情况下,启动所有geth
指向该bootnode的后续节点,以通过该--bootnodes
标志进行对等发现。最好将私有网络的数据目录分开,因此也要指定一个自定义--datadir
标志。
1 | $ geth --datadir=path/to/custom/data/folder --bootnodes=<bootnode-enode-url-from-above> |
注意:由于您的网络将与主网络和测试网络完全断开,因此您还需要配置一个矿工来处理交易并为您创建新的区块。
经营私人矿工
在以太坊公共网络上进行挖掘是一项复杂的任务,因为只有在使用GPU(需要启用OpenCL或CUDA的ethminer
实例)时才可行。有关此类设置的信息,请查阅EtherMining subreddit 和ethminer存储库。
但是,在专用网络设置中,单个CPU矿工实例对于实际目的来说绰绰有余,因为它可以按正确的时间间隔生成稳定的块流,而无需占用大量资源(考虑在单个线程上运行,也不需要多个线程) )。要启动geth
实例进行挖掘,请使用所有常规标志运行它,并扩展为:
1 | $ geth <usual-flags> --mine --miner.threads=1 --etherbase=0x0000000000000000000000000000000000000000 |
它将在单个CPU线程上开始挖掘块和事务,并将所有过程记入所指定的帐户--etherbase
。您可以通过将默认的气体限制块收敛到(--targetgaslimit
)来进一步调整采矿,并在(--gasprice
)接受价格交易。