目录
前言
挖矿
1)安装geth
(一)二进制安装
(二)Ubuntu下通过PPA安装
(三)源代码安装
(四)通过docker安装
2)geth使用的前期准备
(一)创建创始域文件(用来生成属于我们自己的私有链的文件)
(二)创建创世区块(初始化区块链)
(三)启动私有链
3)挖矿指令
(一)查询钱包列表
(二)创建账户
(三)查询余额
(四)开启挖矿
(五)停止挖矿
(六)区块高度
(七)解锁钱包
(八)发送交易
(九)查询交易
(十)连接节点
总结
前言
现在流行的技术区块链算一个热门,我也在学习的路上,写下博客旨在为了记录一些自己遇到的问题和解决方法,希望可以多多帮助学习路上的小白。
提到区块链不得不提到比特币,但是现在热门的开发就是go语言开发和基于以太坊的开发,我目前在学的是以太坊的一些东西,之前没有接触很多,所以也是从无到有的过程。
经过这些天的学习我发现中国对于这块技术的讨论还是相对较少(在遇到问题的时候通过百度很难找出答案,不知道是因为大牛的封闭,还是我们确实缺乏这方面技术的研究)。
什么是Dapp?
App我们都知道是客户端应用,是application的简称。再说dapp就是D+app,d是英文单词decentralization的首字母,单词翻译中文是去中心化,即dapp为去中心化应用。主要强调的是一个可以被我们直观看见的一个页面这样子的应用,里面集成了我们的区块链技术(去中心化技术)。
接上一篇的文章,上一篇我们是在Windows上实现了Dapp,那么我没也可以在Linux上实现我们的Dapp投票合约,按理来说后者更加的适合我们的需求和环境。
本文参考基础:
- 如果想在Windows上搭建Dapp的可以参看上文:手把手教你一步步开发第一个Dapp(使用solidity语言实现投票合约)——Remix版本
- 如果在下面的操作遇到问题可以先安装VMware Tools功能,就可以实现Windows和Ubuntu之间相互复制粘贴了,教程在这边:VM 安装VM tools实现VM和Windows之间可以互相复制粘贴
- Uabntu中的vi编译器的基础:Ubantu中的Vi编辑器的基本操作命令
看完这篇文章后你会学会:
话不多说直接开整!
安装的代码有:
由于官方提供了我们编译好的二进制文件,直接下载下来就可以使用,Linux可以讲Geth所在的目录添加到环境变量中,或者直接sudo mv Geth /user/bin
下载地址:https://geth.ethereum.org/downloads/(可以使用软件会快一点载入界面)
//期间需要输入密码
1.yeyuheng@yeyuheng-virtual-machine: sudo apt-get install software-properties-common
2.yeyuheng@yeyuheng-virtual-machine: sudo add-apt-repository -y ppa:ethereum/ethereum
3.yeyuheng@yeyuheng-virtual-machine: sudo apt-get update
4.yeyuheng@yeyuheng-virtual-machine: sudo apt-get install ethereum
通过golang编译源代码:
1.yeyuheng@yeyuheng-virtual-machine: sudo apt-get install -y build-essential golang
2.yeyuheng@yeyuheng-virtual-machine: cd go-ethereum
3.yeyuheng@yeyuheng-virtual-machine: make geth
编译完成后在目录build/bin/geth
下可以看到编译好的Geth。
Geth不像Hyperledger安装这么麻烦,不建议docker安装,如有需要,参考:https://github.com/ethereum/go-ethereum/wiki/Running-in-Docker
我通过的是第二种安装,有需要的可以自己选择安装方法
输入geth -v 如出现下面的信息就是安装成功
安装成功此刻的心情一定是如此:
通过第一步我们安装好了geth,下面我们介绍一下真正的开始挖矿我们需要做点什么准备,就像你想写java代码编译你总要有jdk吧
首先我们新建一个文件夹用来存放我们这条链的数据(账号,区块,报错信息)——新建ethereum文件夹,然后在ethereum文件夹中创建data文件夹(存储区块数据)和genesis.json文件,打开genesis.json文件将创世区块代码复制到文件中并保存
在桌面创建我们需要的文件夹和初始化文件(genesis.json)
yeyuheng@yeyuheng-virtual-machine:~$ cd 桌面
yeyuheng@yeyuheng-virtual-machine:~/桌面$ mkdir ethereum
yeyuheng@yeyuheng-virtual-machine:~/桌面$ cd ethereum
yeyuheng@yeyuheng-virtual-machine:~/桌面/ethereum$ mkdir data
通过上面的命令我们创建了ethereum文件夹和data子文件夹,我们还缺少一个genesis.json文件(注意:genesis.json的位置是和data同级的,因为data文件夹是用存放区块和链的数据的)
//创建genesis.json并编译
yeyuheng@yeyuheng-virtual-machine:~/桌面/ethereum$ vi genesis.json
上面用的vi其实是Ubuntu中的一个编译器,操作和Windows上的操作天翻地覆,所以还要学习一下怎么操作我们的Vi编译器 在前言已经给出,不会的小伙伴可以看看,或者直接点击链接:Ubuntu中的Vi编辑器的基本操作命令
将下面给的代码复制到vi编译器然后保存退出就好了。
{
"config": {
"chainId": 666,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x00001",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": { },
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
参数说明:
参数名 | 说明 |
---|---|
nonce | nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。 |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度(以便后续出矿快) |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。 |
coinbase | 矿工的账号,任意填写一个账号即可。 |
imestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash值,因为是创世块,所以这个值是0 |
extraData | 附加信息,随便填,可以填你的个性信息 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。 |
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。. |
yeyuheng@yeyuheng-virtual-machine:~/桌面/ethereum$ geth --datadir data init genesis.json
初始化成功后刚刚新建的data文件夹下就会多出两个文件夹(keystroe用来存放创建的账户信息,geth放置的是一些初始化信息):
到此我们完成了挖矿的前期准备工作,可以顺利的进行下一步骤的操作。
代码:
yeyuheng@yeyuheng-virtual-machine:~/桌面/ethereum$ geth --port 3000 --networkid 15 --datadir="data" --maxpeers=3 --rpc --rpcport 8545 --rpcaddr 127.0.0.1 --rpccorsdomain "*" --rpcapi="db,eth,web3,personal,admin,txpool" console
出现下面代码说明启动成功:
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.25-stable-e7872729/linux-amd64/go1.15.6
at block: 0 (Thu Nov 28 2019 17:11:26 GMT+0800 (CST))
datadir: /home/yeyuheng/桌面/ethereum/data
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
To exit, press ctrl-d
>
到此我们完成了前期的准备工作,可以进行下一步的账户创建、余额查询、转账和账户交易等操作!
是不是很快乐?学习的乐趣
>eth.accounts
可以看到当前的账户为空,因为我们没有创建。
法一:
> personal.newAccount("123")
123为密码,出现的是账户的地址:"0x06144f8e61123af6900805d9cfe671c12dcc082f"
法二:
> personal.newAccount()
Passphrase:
Repeat passphrase:
密码输两遍, 出现的是账户的地址:"0xf42038dd008c757c0c8b3cc216622b42fbd87bc5"
注意:出现已杀死报错并且直接退出了console,可以选择重新进入,如果还是不行选择重新启动客户端解决问题。
刚刚我们将到keystore是存放我们账户信息的,现在我们创建了两个账户,那么keystore文件下会有什么变化呢?——可以看到出现了两个账号,并且文件的命名是有创建时间,创建的账号等信息
再次查询钱包列表:
第一个创建的钱包地址会自动作为默认钱包,挖矿得到的ETH会存入默认钱包中,查看默认钱包 :
> eth.coinbase
也可以对其默认账户进行修改:
> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
"0xf42038dd008c757c0c8b3cc216622b42fbd87bc5"
可以输入账户地址或者是钱包列表序号来查询余额:
> eth.getBalance("0x06144f8e61123af6900805d9cfe671c12dcc082f")
> eth.getBalance(eth.accounts[0])
还可以查询默认钱包:
> eth.getBalance(eth.coinbase)
0
挖矿产生的受益会在默认的账户中(coinbase)
> miner.start(1)
一直在Looking for Peers说明一直在挖矿(第一次需要耐心等待)
由于时间有限,我用我已经挖到矿的节点来展示下面的操作。
当挖矿成功会出现:
新打开终端,用 geth attach ipc:geth.ipc(需要在同一个文件下执行)命令连接到js控制台再查询默认钱包余额,发现已经有币了
余额的单位是GWEI,要转为ETH只要除以10的18次方即可,这里的余额为1613.99ETH
对其转化成eth
> web3.fromWei(eth.getBalance(eth.coinbase),'ether')
> miner.stop()
null
返回null表示停止挖矿成功
区块高度也叫区块数量、最新区块
> eth.blockNumber
808
以太坊钱包大概每5分钟就会被锁住,交易和创建合约都需要先解锁,输入下面的命令和钱包密码即可解锁,出现true说明解锁成功
> personal.unlockAccount(eth.accounts[0])
注意:如果出现了GoError: Error: account unlock with HTTP access is forbidden at web3.js:6347:37(47)就可以用下面的语句重新启动。
geth --networkid 3 --datadir data --identity "mychain" --rpc --rpcaddr 0.0.0.0 --rpcport 8545 --rpcapi "admin,debug,eth,miner,net,personal,shh,txpool,web3" --port 30303 --rpccorsdomain "*" --nodiscover console 2>>mychain.log --allow-insecure-unlock
发送交易前请先解锁转出地钱包并启动挖矿,然后使用eth.sendTransaction命令发送交易,下面的命令将从eth.accounts[0]转5个ETH到eth.accounts[1],也可以替换成具体的钱包地址:
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x3bffbaef38ce641989b6cd3da88f296b5b861a35
Passphrase:
true
> amount = web3.toWei(5,'ether')
"5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
"0xf308c404dfcccaec2bef5aaf427ca453f6cca2d9565f4a3cab7e48133e3e5cc4"
返回的"0xf308c404dfcccaec2bef5aaf427ca453f6cca2d9565f4a3cab7e48133e3e5cc4"就是本次交易的hash地址
查看挖矿终端也会出现相应的显示,有交易的hash地址。
发送成功将返回交易哈希,等待挖矿执行交易,再查看余额可以看到已经到账
之前账户的余额:
转账完成后的账户余额:
> eth.getTransaction("0xf308c404dfcccaec2bef5aaf427ca453f6cca2d9565f4a3cab7e48133e3e5cc4")
{
blockHash: "0x896f29d85a96f9c266feb5d71caa08d33c05e6656a554d9ab6c481c1c721995b",
blockNumber: 809,
from: "0x3bffbaef38ce641989b6cd3da88f296b5b861a35",
gas: 21000,
gasPrice: 1000000000,
hash: "0xf308c404dfcccaec2bef5aaf427ca453f6cca2d9565f4a3cab7e48133e3e5cc4",
input: "0x",
nonce: 5,
r: "0x1ba9225971debf478224ea1db83e993e10ba52fe4890fd559bb79775d6dcaf10",
s: "0x7e4375812e71054d965c02ee6ab6d69c5dff76a20d5a25a2023c847fb3e36183",
to: "0xfb7b36db9eb089576ec58df7f4619a4e3972192c",
transactionIndex: 0,
v: "0x558",
value: 5000000000000000000
}
可以看见我们的账户地址没有问题。是从第一个账户到第二个账户中的。
如果局域网内有多个私有链节点,可以将这些节点连接起来组成链,这些节点会同步相同的区块和交易,相当于小型的公链。但是要将这些节点连接起来需要满足3个条件:
假设有两个节点:节点一(Ubuntu端)和节点二(windows端),它们的geth启动命令中的networkid都是1108,首先要知道节点二的enode信息,启动节点二的私有链,在js console中执行下面的命令查看enode信息:
> admin.nodeInfo.enode
"enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@[::]:30304"
复制上面给出的信息添加到admin.Peer的参数中,注意要把enode中的[::]替换成节点二的IP地址。然后在节点一的js console中执行admin.addPeer(),就可以连接到节点二。
> admin.addPeer("enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@192.168.1.111:30304")
连接成功后,节点一和节点二就会开始同步的区块,保证区块数据一致。使用admin.peers
命令可以查看当前网络连接在一起的所有节点
> admin.peers
[{
caps: ["eth/62", "eth/63"],
id: "070b16d058df62a934bb1b9f6e216f6763d63c51011c559d0ad155ae428294c69aed1e35a46c36a6613989941b67b530ab92c7667bd63e7e8a7a5717a266751f",
name: "Geth/v1.8.12-stable/linux-amd64/go1.9.2",
network: {
inbound: true,
localAddress: "172.31.238.175:30303",
remoteAddress: "145.239.0.91:51238",
static: false,
trusted: false
},
protocols: {
eth: {
difficulty: 8.379127609415399e+21,
head: "0x7ce58e50b8bc9af80c6900729801832ec9a5f86e549930e085f1a208dacf5608",
version: 63
}
}
}, {
caps: ["eth/62", "eth/63"],
id: "19211a5d0fbcabf5184e49639839bda772080cba500a4a0e9ced1f89c3a43fea1c00d4d8de5a463d6002bfa594e46e2c03611a6514117f1bd8c7e889bfb4ec7a",
name: "Geth/v1.8.18-unstable-126dfde6/linux-amd64/go1.9.4",
network: {
inbound: true,
localAddress: "172.31.238.175:30303",
remoteAddress: "120.78.87.202:53548",
static: false,
trusted: false
},
protocols: {
eth: {
difficulty: 5.481064970682881e+21,
head: "0xdb982b1ff69083b090549c3809dd6b58f87ca50db97e0b4144aac9269ad198be",
version: 63
}
}
}]
注意:
不同节点间启动命令:geth --datadir ./data2 --nodiscover console 2--rpc --rpcport 8001 --rpccorsdomain "*" --datadir "./" --port 30306 --rpcapi "db,eth,net,web3" --networkid 999 console 2>>2.log
连接节点参考文章: https://blog.csdn.net/C_jian/article/details/85212512
这篇文章主要是针对在Ubuntu上开发以太坊的的一个记录,主要是针对自己刚刚学做一个好开端,其实这篇文章是我做了好久才出的,毕竟学习一门新的技术是需要时间的,我也学习了好久,遇到了数不胜数的问题,但是遇到问题千万不可以放弃自己,所有问题都可以被解决,主要是安装环境等的操作可能会出错,其他的都是按部就班就可以实现其功能。
本来是写的Ubuntu上开发Dapp的,结果写基础的时候发现你这篇文章已经很长了,所以把Ubuntu上挖矿这一块单独列出来了,以便视觉疲劳。
下一篇《手把手教你一步步开发第一个Dapp(使用solidity语言实现投票合约)——Ubuntu版本》也会马上的出版,记得关注不迷路。
打个广告:代做Web毕设(可加区块链),专业团队值得信任,可以私聊。
好了本篇到此结束:
对了记得:
No pains No results