首页 > 其他分享 >使用docker搭建以太坊私链

使用docker搭建以太坊私链

时间:2023-09-06 23:22:29浏览次数:42  
标签:geth 以太 -- coinbase eth docker 节点 私链

准备工作

1、宿主机安装 Docker 和 Go 编程语言。

2、在本地计算机上克隆 go-ethereum 代码库

git clone http://github.com/ethereum/go-ethereum.git 

3、宿主机编译以太坊客户端

make geth

该命令将在当前目录下的 build/bin 目录中生成可执行文件 geth。 4、创建一个新目录,用于存放节点相关数据。在该目录下创建一个名为“genesis.json”的文件,用于定义创世区块。并初始化用户,存储私链配置文件和数据。

以上内容在下面的部署过程中详细说明

docker-compose部署

以下只是一个大概的方法,步骤可供参考。由于第一次下载使用的基础镜像,以太坊源码版本都太低,导致没有第一笔交易无法进行挖矿,因此换了第二种方法,并使用了更高版本的以太坊源码和基础镜像,所有功能测试都通过

1、宿主机下载geth

下载位置https://geth.ethereum.org/downloads,然后解压

tar -xvf geth-linux-amd64-1.12.2-bed84606.tar.gz 

 此时无法识别 geth ,需要将其添加进系统路径中,可以先打印查看当前系统路径

echo $PATH

 分别执行以下两条命令

echo 'export PATH=$PATH:/root/go-ethereum/geth-linux-amd64-1.12.2-bed84606' >> ~/.bashrc
source ~/.bashrc

表示在~/.bashrc文件的末尾添加一行,将/root/go-ethereum/geth-linux-amd64-1.12.2-bed84606添加到$PATH中。source ~/.bashrc表示立即生效。

此时再执行 geth ,如果不添加任何参数,就开始更新主网了

 2、预先创建账户,初始化

新建一个目录,首先创建密码文件,

echo "123456" > .passwd

创建账户时使用以下语句分别创建两个节点,每个节点包含两个账户,分别存储于node1/node2目录下

for ((n=0;n<2;n++)); do geth account new --password .passwd --datadir ./node1; done

这个命令会在./node1目录下创建两个新的以太坊账户,并将它们的加密私钥存储到默认的账户目录中。--password将从名为.passwd的文件中读取密码,并将其用于加密私钥。--datadir表示想要使用的目录路径。

 账户1地址为 coinbase 地址,即挖矿得到的奖励地址,账户2为转账交易地址,地址如下表

节点账户1地址(挖矿账户账户2地址(资金账户
node1 0xb03CDd04856f4429A7e834A3aC7f3CeD6B23d002 0x202b971c3b9D7366532942E50Cb701DbbA893B0F
node2 0x7B9fc9e4CAAda8Eec649274e2860C67E0976420F 0xd5ad8AA9eB84820bC7361FE3227f687ed3C26ECe

执行完后,会出现两个目录,其中存储了私钥文件keystore

3、创建创世区块

创世区块为文件genesis.json,位于/ethnode目录下

{
  "config": {
    "chainId": 150,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {},
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x10000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

4、初始化

执行以下命令初始化两个节点

geth init --datadir ./node1 genesis.json

返回内容

部分返回解释:

Maximum peer count:最大对等节点数。在这个例子中,ETH网络的最大对等节点数为50。
Set global gas cap:设置全局gas上限。在这个例子中,全局gas上限为50,000,000。
Writing custom genesis block:正在写入自定义创世块。
Successfully wrote genesis state:成功写入创世状态。

5、编写Dockerfile

使用了两个镜像,其中golang 1.10的alpine镜像为基础环境,从 github 上下载源码编译,然后使用第二个镜像alpine:latest构建最终的Geth节点,并在其中运行Geth二进制文件。

#编译geth所需镜像
FROM golang:1.10-alpine as builder
​
RUN apk add --no-cache make gcc musl-dev linux-headers git
RUN git clone --depth 1 --branch release/1.8 https://github.com/ethereum/go-ethereum /go-ethereum
RUN cd /go-ethereum && make all
​
#运行geth的基础镜像
FROM alpine:latest
#安装ca证书,用于节点间安全通信
RUN apk add --no-cache ca-certificates
#从builder镜像中复制编译好的Geth二进制文件到/usr/local/bin/目录中
COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/
​
WORKDIR "/opt"
​
ENV coinbase=""
ENV datadir=""
#启动一个Geth节点,并将其配置为使用指定的数据目录、coinbase地址和密码文件。
CMD exec geth --datadir ./$datadir  --verbosity=4 --rpc --rpcapi "eth,web3,personal,net,miner,admin,debug,db" --rpcaddr "0.0.0.0" --rpccorsdomain "*" --syncmode=full --mine --unlock $coinbase --password .passwd
#通过RPC接口与Geth节点进行通信
EXPOSE 8545
#通过P2P网络与其他节点进行通信
EXPOSE 30303

6、配置docker-compose

定义两个容器,命名为sealnode-1/2,配置环境,将他们连接到一个网络下进行通信。

正常来说docker-compose.yaml文件要通过image指定使用哪个镜像,但是该文件通过build关键字指定 dockerfile 构建上下文,也就是将使用当前目录中的Dockerfile来构建镜像。

version: "3"
​
services:
  sealnode-1:
    container_name: sealnode-1
    hostname: sealnode-1
    #环境变量,geth节点的coinbase地址和数据目录
    environment:
      coinbase: 82a6d98ea4a194258b37c9d6376d2857f626fe78
      datadir: node1
    #构建上下文
    build:
      context: .
    #端口映射,本机-容器
    ports:
      - 8011:8545
      - 30011:30303
    #将当前目录映射至容器/opt目录中
    volumes:
      - .:/opt
    #网络配置
    networks:
      - mynet
​
  sealnode-2:
    container_name: sealnode-2
    hostname: sealnode-2
    environment:
      coinbase: db9a80b86bb062519f0d9d4475fd990f5ea351ff
      datadir: node2
    build:
      context: .
    ports:
      - 8012:8545
      - 30012:30303
    volumes:
      - .:/opt
    networks:
      - mynet
​
#定义两个桥接网络,默认和用于容器间通信的mynet
networks:
  default:
    driver: bridge
  mynet:
    driver: bridge

7、启动

启动三个终端,分别用于挂起 docker 查看日志和查看两个容器

终端1

挂起 docker 查看日志

docker-compose up

 在不断监控两个节点状态中

以上内容表示正在挖矿,删除死节点、重新计算下载器 QoS 值,还可以看到生成 DAG 的信息。DAG 是以太坊挖矿所需的数据集,用于计算区块的哈希值。在生成 DAG 期间,节点会执行一些计算操作,并将结果保存到本地硬盘中

终端2

另起终端,先查看当前Docker Compose项目中正在运行的容器的状态信息,包括容器ID、名称、状态、端口映射等信息,进入容器内部,连接到geth控制台

docker exec -it sealnode-1 /bin/sh
geth attach node1/geth.ipc

终端3

该终端进入第二个容器,同样的操作不演示

附目录结构

当前目录结构

├── .passwd
├── docker-compose.yaml
├── dockerfile
├── genesis.json
├── node1
│   ├── geth
│   ├── geth.ipc
│   └── keystore
└── node2
    ├── geth
    ├── geth.ipc
    └── keystore

shell脚本部署

通过 shell 脚本开启两个容器,并使他们处于同一网络下。目录结构如下

├── .passwd
├── go-ethereum-1.11.4
├── dockerfile
├── script.sh
├── script1.sh
├── node1
│   ├── genesis.json
│   └── data
│       ├── geth
│       ├── geth.ipc
│       └── keystore
└── node2
    ├── genesis.json
    └── data
        ├── geth
        ├── geth.ipc
        └── keystore

1、创建虚拟网络

docker network create ethproject

 在启动容器时添加--network=ethproject参数,两个节点就会在同一网络下

2、创建创世区块

与上面的一样,可以用一样的genesis.json文件,这里把网络id改成了666

{
  "config": {
    "chainId": 666,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {
    "0xd8e6708334bdf3e9144a62859c99998caa7df32d": {
      "balance": "1000000000000000000000000000"
    },
    "0x4beff4fceff14ef1c24956fb81387d21f24ca04b": {
      "balance": "1000000000000000000000000000"
    }
  },
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "100000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

3、初始化用户脚本

和方法一差不多,只是把这些放到脚本里一次运行了,

#!/bin/bash
#先删除节点同步的链上信息与账户信息
rm -rf ./node1/data
rm -rf ./node2/data
​
#在两个节点的/data路径下分别创建两个用户
echo "111111" > .passwd
for ((n=0;n<2;n++)); do geth account new --password .passwd --datadir ./node1/data; done
for ((n=0;n<2;n++)); do geth account new --password .passwd --datadir ./node2/data; done
​
#初始化
geth init --datadir ./node1/data ./node1/genesis.json
geth init --datadir ./node2/data ./node2/genesis.json

4、编写dockerfile创建镜像

dockerfile,由于使用的新版,和上面的区别主要是基础镜像和CMD启动命令不同

FROM golang:1.19-alpine as builder
  
RUN apk add --no-cache make gcc musl-dev linux-headers git
RUN mkdir -p /go-ethereum
COPY ./go-ethereum-1.11.4/ /go-ethereum/
RUN go env -w GOPROXY=https://goproxy.cn,direct
RUN cd /go-ethereum && make all
​
FROM alpine:latest
RUN apk add --no-cache ca-certificates
COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/
​
WORKDIR "/opt"
COPY ./ ./
​
ENV datadir=""
ENV coinbase=""
​
CMD exec geth --datadir ./data --networkid 666 --verbosity=4 --port 30001 --nodiscover --syncmode=full --mine --miner.etherbase $coinbase --allow-insecure-unlock --http --http.addr 0.0.0.0 --http.port 8001 --http.corsdomain "*" --http.api eth,web3,personal,net,miner,admin,debug,db --password .passwd
​
EXPOSE 8001
EXPOSE 30001

参数解释(如果不是v1.11.4版本,可以阅读源码文件中的 readme 文档,或查看geth -help查看最新参数)
--verbosity:用于控制节点的日志详细程度,值越高越详细,4为debug,最详细为5
--nodiscover:用于控制节点是否启用对等节点的自动发现机制,默认情况下,以太坊节点会尝试通过网络自动发现其他节点,以建立对等连接。若启动该参数,则不会主动发现其他节点,需要手动添加其他节点
--syncmode:用于控制以太坊节点的同步模式,包括full,light,snap,full表示同步所有区块信息
--miner.etherbase:用于指定挖矿奖励应该发送到的以太坊账户地址
--allow-insecure-unlock:允许通过不安全的方式解锁账户,开启此选项可使用 http 解锁账户进行转账

构建镜像

完成后可查看镜像

5、容器启动脚本

分别获取两个节点下的第一个账户地址,作为挖矿奖励,然后使用刚刚创建的镜像分别启动两个容器,注意端口映射关系,这样可以通过不同的端口访问不同的节点

#!/bin/bash
  
coinbase1=""
for file in ./node1/data/keystore/*
do
  if [ -f "$file" ]
  then
    name1=$(echo "$file" | tail -c 41)
    coinbase="0x${name1}"
    coinbase1=$(echo "$coinbase" | head -n 1)
    echo "$coinbase1"
    break
  fi
done
​
coinbase2=""
for file in ./node2/data/keystore/*
do
  if [ -f "$file" ]
  then
    name2=$(echo "$file" | tail -c 41)
    coinbase="0x${name2}"
    coinbase2=$(echo "$coinbase" | head -n 1)
    echo "$coinbase2"
    break
  fi
done
​
docker run -d --name ethnode1 --network=ethproject -p 8001:8001 -p 30001:30001 -v ~/eth-docker/node1/data:/opt/data -e coinbase=$coinbase1 eth_docker
​
docker run -d --name ethnode2 --network=ethproject -p 8002:8001 -p 30002:30001 -v ~/eth-docker/node2/data:/opt/data -e coinbase=$coinbase2 eth_docker

执行过程中会输出两个挖矿奖励接收的地址,以及两个容器id,再次查看容器,就在运行中了

 

6、远程连接节点并绑定对等节点

使用 rpc 远程连接节点1 ,同理,8002端口可连接节点2

geth attach http://192.168.123.215:8001

这里用 节点1 连接 节点2 ,可以另起一个终端进入 节点2 ,然后查看当前节点enode信息

admin.nodeInfo.enode

 

复制下来,将红框部分改为对应的 ip 和端口,去掉disport,切换到 节点1 ,执行以下命令,

>admin.addPeer("enode://[email protected]:30002")

语法正确会返回 true ,但不代表连接成功,需要执行admin.peersnet.peerCount确定,如果出现以下数组即为绑定成功,这个时候两个节点可以任意查看绑定的节点信息

 

7、功能测试

包含以下命令

#查看当前节点账户
> eth.accounts
#查看账户1的余额(单位wei转换为Eth)
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
#查看账户2的余额
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
#从账户1转入3个ETH给账户2
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(3, "ether")})
#设置挖矿收益账户
> miner.setEtherbase(eth.accounts[0])
#挖矿
> miner.start()
#停止挖矿
> miner.stop()
#查看区块高度
> eth.blockNumber
#解锁账户
> personal.unlockAccount(eth.accounts[0],”111111”)
#查看交易池状态
> txpool.status

我的测试过程如下,先分别开启挖矿,十分钟后查看区块高度,发现两个节点是一样的,即代表同步成功。然后分别查看两个地址账户余额,第一个是挖矿奖励地址,第二个是普通地址。另一个节点同样有钱,这里只展示一个,结果如下

然后测试转账功能,转账之前需要先解锁账户,否则会报错

 解锁后给第二个账户转账30,再次查看余额

 功能测试完成

标签:geth,以太,--,coinbase,eth,docker,节点,私链
From: https://www.cnblogs.com/hackcaixukun/p/17683680.html

相关文章

  • Docker 启动alpine镜像中可执行程序文件遇到 not found
    问题:dockeralpine镜像中遇到sh:xxx:notfound例如:在容器内/app/目录下放置了可执行文件abc,启动时提示notfound/app/startup.sh:line5:./abc:notfound原因由于alpine镜像使用的是musllibc而不是gnulibc,/lib64/是不存在的。但他们是兼容的,可以创建个软连接过去......
  • Centos7安装Docker全过程记录(无坑版教程)
     一、安装前必读在安装Docker之前,先说一下配置,我这里是Centos7Linux内核:官方建议3.10以上,3.8以上貌似也可。注意:本文的命令使用的是root用户登录执行,不是root的话所有命令前面要加sudo1.查看当前的内核版本uname-r2.使用root权限更新yum包(生产环境中此步操作......
  • docker 中安装kafka
    docker中安装kafka docker中安装kafka在安装kafka之前需要先安装zookeeper,因为kafka启动会将元数据保存在zookeeper中,zookeeper是一种分布式协调服务,可以再分布式系统中共享配置,协调锁资源,提供命名服务。zookeeper安装1、在docker中拉取zookeeper镜像dockerpull......
  • Docker的基础安装
    卸载旧版本yumremovedockerdocker-clientdocker-client-latestdocker-commondocker-latestdocker-latest-logrotatedocker-logrotatedocker-engine安装GCCyum-yinstallgccyum-yinstallgcc-c++安装软件包yuminstall-yyum-utils设置镜像仓库官方设置y......
  • docker 修改存储目录
    有以下两种修改方式https://blog.csdn.net/weixin_45720992/article/details/131136505方法1.修改docker默认存储位置step1:docker默认存储路径在/var/lib/docker下[root@node01system]#dockerinfo|grep-idirDockerRootDir:/var/lib/dockerstep2:修改默认......
  • docker 打开报错 windows hypervisor is not present docker desktop is unable to de
     dockerdesktop-windowshypervisorisnotpresentdockerdesktopisunabletodetectahypervisor.hardwareassistedvirtualizationanddataexecutionprotectionmustbeenabledintheblos.seehttps://docsdocker.com/desktop/troubleshoot/topics/#virtua......
  • 使用 Docker Compose 部署 Redis Sentinel 高可用架构
    在现代应用中,无法容忍系统中断或数据丢失。Redis作为一种高性能的内存数据库,被广泛应用于缓存、会话管理等场景。然而,即使我们拥有可伸缩的RedisCluster集群,也需要考虑在主节点故障时自动切换到从节点的机制。这时候RedisSentinel就派上用场了。高可用性是分布式应用的核心......
  • 优化Docker权限管理:配置Docker用户组
    Docker利用Linux的用户和组权限来管理对Docker守护进程的访问权限。一般情况下,只有root用户和属于docker用户组的用户才被允许访问Docker守护进程。在Linux系统上使用Docker时,如果您尚未配置docker用户组,那么作为非root用户执行Docker相关命令将要求使用sudo......
  • Docker三剑客之docker-compose
    docker-compose是Docker生态系统中的一个重要成员,它允许开发人员使用一个简单的配置文件来定义和运行多个Docker容器。通过docker-compose,你可以定义应用程序的各个组件、容器之间的依赖关系以及网络配置,从而实现在一个命令中启动、停止和管理整个应用程序栈。安装docker-co......
  • Docker 及 Docker Compose 安装指南
    Docker是一个开源的容器化平台,可以帮助我们快速构建、打包和运行应用程序。而DockerCompose则是用于管理多个容器应用的工具,可以轻松定义和管理多个容器之间的关系。现在,让我们开始安装过程吧!docker安装apt安装sudoaptupdatesudoaptinstalldocker.iosudosystemctlstatu......