基于阿里云服务器搭建私链并与SpringBoot项目进行交互

Bambi ·
更新时间:2024-11-14
· 540 次阅读

前言

这是区块链系列的第三篇,内容是在服务器上去搭建一条属于自己的以太坊私链,同时部署运行我们之前写好的demo,实现通信记录等等完整的操作,因为有过在Windows环境下搭建私链的经验,看起来并不难,但是,实际上,这里是让我消耗最多时间的地方!!!在这个过程中,真的是,大坑小坑不断,并且,我的目的是最终能真正跑起来,所以也需要去解决更多的问题

文章目录前言一:环境搭建搭建go环境geth的安装二:私有链搭建以及geth使用创建创世区块初始化创世块启动私有链三:控制台交互geth自动关闭问题解决方案挖矿返回null进入dev模式初始化时指定账户余额:项目启动前准备开放8545端口客户端的自动挖矿两种模式自动挖矿的比较geth的后台运行总结 一:环境搭建

首先说一下我的环境,我的服务器是阿里云的,CentOS7.

还是一样,我用的是geth客户端

之前讲过,在不同环境搭建安装geth客户端方法是不一样的,是的不一样,CentOS只能先下载部署好go环境,然后再去github上clone下geth客户端

搭建go环境

可以先在服务器上运行以下命令:

cd /usr/local/ mkdir go cd go/ wget https://storage.googleapis.com/golang/go1.10.2.linux-amd64.tar.gz tar -zxvf go1.10.2.linux-amd64.tar.gz echo "export GOROOT=/usr/local/go" >> /etc/profile echo "export PATH=/usr/local/go/bin:$PATH" >> /etc/profile source /etc/profile go version

最后执行完应该可以查询出go的版本,截图如下:

如果不能查询出正确的go版本,那么你直接打开/etc/profile配置文件,直接在文件尾部修改确认好你的路径没有问题,然后再重新source一下就可以了。

geth的安装

接下来是geth的安装,先 git clone下go-ethereum项目,如果服务器上没git,那么先安装git

//正常情况 yum install git //没有权限的话: sudo yum install git

接着,执行以下指令:

mkdir /usr/local/apps/geth/ cd /usr/local/apps/geth/ git clone https://github.com/ethereum/go-ethereum.git cd go-ethereum/ make all echo "export PATH=$PATH:/usr/local/apps/geth/go-ethereum/build/bin" >> /etc/profile source /etc/profile geth version

正常的话能走到结尾会返回以下结果:

但是,大概率是不会正常的,因为在make过程中 可能会出现以下错误:
exec: “gcc”: executable file not found in $PATH

则是没有安装gcc的原因,执行

yum install gcc

还一定会出现无法进行clean all操作,具体信息大概是你缺了某个包某个文件,你进去它说的地方一看,还真的没有它说的缺的那个包;

实际上是因为我们clone下来的是整个master分支,所以我们需要切换分支,再进行clone即可,可以先去它的github上查看一下目前的分支信息,现在是19年12月份,现在是1.9;所以运行以下命令:

git checkout release/1.9 make geth echo "export PATH=$PATH:/usr/local/apps/geth/go-ethereum/build/bin" >> /etc/profile source /etc/profile geth version

这样就能成功返回geth版本信息了。

最后,可以设置一下防火墙相关:

可以关闭防火墙:

systemctl stop firewalld systemctl disable firewalld

也可以添加防火墙规则,允许geth使用某几个端口:

firewall-cmd --zone=public --add-port=8087/tcp --permanent firewall-cmd --zone=public --add-port=30303/tcp --permanent systemctl enable firewalld systemctl start firewalld

区块链需要同步网络时间,所以需要启用网络时间同步,执行以下命令:

systemctl enable ntpd systemctl start ntpd 二:私有链搭建以及geth使用

按照以前的感觉,我们可以先创建创世区块

创建创世区块

首先,先创建一个文件夹,然后定义自己的创世区块,创世区块信息写在一个 JSON 格式的配置文件中。首先如下:genesis.json:

{ "nonce":"0xdeadbeefdeadbeef", "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x4000", "alloc": {}, "coinbase":"0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x00000000", "gasLimit":"0xffffffff", "config":{ "chainId": 1024, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0 } } 初始化创世块

输入命令完成初始化:

geth --datadir data init genesis.json 启动私有链

初始化完成之后,输入以下命令即可启动私有链:

geth --identity "TestNode" --rpc --rpcport "8545" --datadir data --port "30303" --nodiscover --allow-insecure-unlock console 三:控制台交互

关于利用geth与控制台交互的各种指令和在Windows下无差别,可以看之前的博客,也可以看这个:Geth管理API文档 这个是geth客户端很完整的指令文档

geth自动关闭问题

在这个过程中,如果你的服务器配置比较低,很可能会出现输入个命令没啥反应,并且geth这个进程随时可能会被杀掉退出,这是因为服务器内存不足触发Linux的OOM killer操作

解决方案

1、设置 –cache,发现并不能解决问题。

2、升级内存,钱到位了就直接解决了。

3、用shell编程书写一个监控程序,发现问题重启即可。

4、设置swap分区。具体命令如下:

free -m dd if=/dev/zero of=/swap bs=10M count=800 chmod 600 /swap ll /swap mkswap /swap swapon /swap swapon -s free -m

这种方法是一个折中方法,但是够用。

挖矿返回null

接着,当我们想在链上和在Windows一样先进行挖矿赚点钱的时候,发现输入miner.start()指令,会返回一个null,没其他任何反应,这里可能有几种情况,首先,可以确定的是geth高版本源码规定了不管挖没挖矿,都会返回Null.所以你首先确定一下你有没有矿工账户,其次看一下自己的区块数量有没有改变,如果都没有改变,那么你是正常模式下还是dev模式?因为在高版本geth里,–dev模式下新增了一个参数项:–dev.period value;value的默认值是0,这表示在默认情况下,只有发生交易才会进行挖矿(dev模式是回归测试模式,主要用来给开发人员提供一个方便的开发测试环境),如果你是dev模式的话,那么退出然后指定好–dev.period value的值重新进就可以了,如果不是dev模式,账号正常,但就是没有挖矿,那么你只能通过以下方法来解决这个问题了:

进入dev模式

我们退出控制台,重新进,输入命令:

geth --identity "TestNode" --rpc --rpcport "8545" --dev --dev.period 1 --datadir data --port "30303" --nodiscover --allow-insecure-unlock console

然后会发现,报了这个Bug

Fatal: Failed to unlock developer account: could not decrypt key with given password

这是因为我们刚才自己创建了账号,而在 dev 模式下,启动节点后,系统默认提供一个开发者账号,并且这个账号密码是空;

所以加下来我们需要清除掉所有的信息,其实也就是吧data文件删除干净,然后不需要初始化创世块,直接输入上面的指令进入控制台就可以了,也就是直接输入:

geth --identity "TestNode" --rpc --rpcport "8545" --dev --dev.period 1 --datadir data --port "30303" --nodiscover --allow-insecure-unlock console 初始化时指定账户余额:

刚才因为账户没钱导致的没法交易所以要先挖矿,但是其实我们还可以在初始化时就指定余额。

在我们的 genesis.json里有这样一个参数: “alloc”: ,在这个参数可以指定某个账号的特定信息,包括账户余额。

那么我们修改我们的genesis文件,然后删掉相关数据,重新初始化即可。

修改的genesis文件的alloc配置如下:

"alloc": {"0x8df95cc3baed5d10d3a27c2705e3726c9aadf635":{"balance":"1000000000000000000000000000000"}},

怎么获得前面的账户地址呢,也有两种方法,一种是直接用geth指令创建账户(不用进入控制台模式就可以创建);第二就是把之前创建过的账户的地址记下来,然后把之前那个账户的keystore中对应的文件复制好重新放在你现在打算开启的私链地址的keystore中即可。

到了这里,我们在windows所做的在geth客户端的所有操作就基本都可以在服务器上去操作了,接下来就是结合我们的springBoot项目来实现了

项目启动前准备

关于SpringBoot项目怎么在服务器上跑的一系列相关就不说了,记得修改我们的demo代码,主要是两个地方:

//修改连接地址 Web3j web3j = Web3j.build(new HttpService("http:// 你的服务器ip:8545")); //新建链上账号时,修改保存核心文件路径 wallet = WalletUtils.generateBip39Wallet(walletPwd, new File("/usr/local/block/data/keystore/")); //发起交易时,修改文件路径 String keyStoreKey = "/usr/local/block/data/keystore/";

大概就是这几个地方,修改完成之后打包部署上去即可。

可以把秘钥或者核心文件名等相关信息保存到你的数据库上,可以方便很多

开放8545端口

项目部署完之后,这个时候直接请求对应接口你会发现访问会被拒绝,这个时候你需要先去阿里云控制台先设置好安全组,开发出8545端口,接着你要让你的客户端是可连接的

你可以通过以下命令查看你的客户端是否可连接:

wget 你的ip:8545 netstat -tnulp | grep 8545 netstat -all ssh -v -p 8545 root@你的ip

如果不是可连接的,那么你运行这些命令会发现你会被拒绝。

通过netstat命令查看你的8545端口开放情况,一般默认是127.0.0.1或者localhost;这也意味着你只能在自身服务器上去相连接,但是跨服务器是不可以的,这种情况显然很不适合以后的开发,所以你可以退出geth客户端,重新进入,进入的时候指定你的客户端的开放情况

geth --identity "TestNode" --rpc --rpcaddr="0.0.0.0" --rpcport "8545" --dev --dev.period 1 --datadir data --port "30303" --nodiscover --allow-insecure-unlock console

这样的话就是任意联网的设备都可以请求你的8545端口,但是一般不要这样开放,因为很容易遭受攻击,我的开放了两天,一直有国外ip的机器在攻击,最好是在节点间设置 rpc 通信的白名单,这样也可以防止黑客暴力破解 keystore 的密码。

到这里就保证了你的项目和客户端是已经能互相连通的了

客户端的自动挖矿

运行我们的项目,并且对客户端进行连接,我们接下来的需求是,怎么让它自动挖矿,而不是我们一直去运行miner.start()命令

一样的,geth客户端支持我们做这样的事情,这要分两种情况

首先是dev模式下的指令如下:

geth --identity "TestNode" --rpc --rpcaddr="0.0.0.0" --rpcport "8545" --dev --dev.period 1 --datadir data --port "30303" --nodiscover --allow-insecure-unlock --mine --etherbase 0 console 2

这个指令意思就是允许你一边启动一边自动挖矿,dev模式会简单许多

另外就是假设你不是dev模式,那么你应该这样启动:

首先创建一个password.json文件,里面直接保存你的矿工账户的密码;

接着,运行下面指令:

geth --rpc --rpcaddr="0.0.0.0" --rpcport "8545" --datadir data --allow-insecure-unlock --unlock 0x8df95cc3baed5d10d3a27c2705e3726c9aadf635 --password password.json --mine --etherbase 0 console 2

这样就实现了自动挖矿

两种模式自动挖矿的比较

最大的差别就是dev模式下,挖矿速度更快,并且你可以设置为交易发生时再挖矿,资源消耗上更少,普通模式资只要开启了自动挖矿就会一直挖下去,不管有没有交易发生,源消耗更大;需要注意得一点是,dev模式下由于系统的默认账户密码是空,安全性比较不好,所以建议你自建账号,然后将其相关数据加密存储,并且将其设置为矿工行号即可,这样只需要在启动自动挖矿时去解锁账户即可

geth的后台运行

到这里之前,你会发现你一退出客户端,服务就停了,这就很不符合实际情况了,还好你可以通过以下指令完成geth的后台启动并且自动挖矿,并且设置成交易提交再进行挖矿,减少资源损耗,并保证数据能准时准确快速上链:

nohup geth --rpc --rpcaddr="0.0.0.0" --rpcport "8545" --datadir data1 --allow-insecure-unlock --dev --dev.period 0 --mine --etherbase 0 2>> get.log &

这个时候会发现我们的8545端口是一直处于开启监听的状态

总结

到了这里,基本就实现了我们在服务器搭建了一条私链,同时我们用代码实现了将数据上链的过程,同时,我们也可以把我们的挖矿服务器和跑服务的服务器分开来,比如本地跑项目,服务器挖矿等等的操作,这样就基本保证项目的落地性和可运行性,当然,关于安全等等方面的问题也是在真实环境中你需要考虑的。

最后,在附带一点智能合约的相关链接吧:

如何实现可升级的智能合约

开发编译智能合约

web3j教程:以太坊智能合约

智能合约初体验

你还可以去github上获取到很多相关资料,祝你好运!

如果中间有问题或者其他情况可以留言,我们一起交流学习


作者:闻赤松之清尘,愿承风乎遗则



springboot 阿里云 云服务器 服务器 阿里云服务器 阿里

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Daisy 2020-05-31
604