安装环境
1.首先安装VMware和Ubuntu
安装教程连接
链接:https://pan.baidu.com/s/1D6-M3lTQbnTDGqJ-T2lHXw
提取码:585t
复制这段内容后打开百度网盘手机App,操作更方便哦
安装包连接
链接:https://pan.baidu.com/s/1cNKvQjymAwtPzKefuBCjkQ
提取码:9jf9
复制这段内容后打开百度网盘手机App,操作更方便哦
2.安装以太坊客户端
这里给出两种方式
1)PPA 直接安装
安装必要的工具包:
apt install software-properties-common
添加以太坊源
add-apt-repository -y ppa:ethereum/ethereum
apt update
安装git
安装git工具,git是一个非常优秀的免费、开源的版本管理控制工具, 我们可以使用git工具方便地下载官方(Golang、Hyperledger Fabric等等)在Github网站上发布的相关源代码或其它内容。
安装git工具使用如下命令:
sudo apt update
sudo apt install git
安装cURL
使用如下命令安装cURL:
sudo apt install curl
安装Docker
查看系统中是否已经安装Docker:
使用如下命令安装Docker的最新版本
sudo apt update
sudo apt install docker.io
查看Docker版本信息
docker --version
安装Docker-compose
确定系统中是否已安装docker-compose工具
$ docker-compose --version
如系统提示未安装,则使用如下命令安装docker-compose工具:
sudo apt install docker-compose
安装成功后,查看Docker-Compose版本信息
$ docker-compose --version
安装 go-ethereum
apt install ethereum
用geth version查一下成功了么,成功了就是这样谁的
2).源码安装
因为 go-ethereum 使用 Go 语言编写,编译源码前需要配置好 Go 环境。
安装go
使用wget工具下载安装包
wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
解压tar包到/usr/local
sudo tar zxvf go1.11.linux-amd64.tar.gz -C /usr/local
创建Go目录
mkdir $HOME/go
用vim打开~./bashrc,配置环境变量
vim ~/.bashrc
增加下面的环境变量,保存退出
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
输入如下保存退出
:wq
使环境变量立即生效
source ~/.bashrc
检测go是否安装好
go version
安装make
sudo apt install make
安装g++
sudo apt install g++
安装libltdl-dev 库
sudo apt-get install libltdl-dev
3.下载和编译 Geth
安装 C 编译器:
apt install -y build-essential
下载最新源码
git clone https://github.com/ethereum/go-ethereum
编译安装:
cd go-ethereum
make geth
用geth version查看是否成功
4.安装 Solidity 编译器
add-apt-repository ppa:ethereum/ethereum
apt update
apt install solc
再推荐两个浏览器IDE,挺好用的
http://remix.ethereum.org/
http://remix.hubwiz.com/
私有链搭建
一、配置初始状态
要运行以太坊私有链,需要定义自己的创世区块,创世区块信息写在一个 JSON 格式的配置文件中。首先将下面的内容保存到一个 JSON 文件中,例如 genesis.json。
{
"config": {
"chainId": 15665883188,
"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": "0x400",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
chainID:指定了独立的区块链网络 ID。网络 ID 在连接到其他节点的时候会用到,以太坊公网的网络 ID 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 ID。不同 ID 网络的节点无法相互连接。
alloc: 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以,默认为空即可。
coinbase: 矿工的账号,随便填即可。
difficulty: 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度。
extraData: 附加信息。这里要注意一下,新版本该值需要为16进制数据,以0x 开头。
gasLimit: 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们要做的是私有链,所以此处填最大。
nonce: nonce就是一个64位随机数(0x后一位为4个二进制位,故有16位),用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
mixhash:与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
parentHash: 上一个区块的hash值,因为是创世块,所以这个值是0。
timestamp: 设置创世块的时间戳。
这里有一点需要注意,就是chainId,这个建议写的少见一点,如果和别人重复的话,在后期的节点同步过程会连接到别人的节点,同步会很慢。
2.初始化创世区块
在这里首先建立一个文件夹privatechain,然后把创世区块的.json文件放在此文件夹里边,然后在文件夹里运行此
geth --datadir data0 init genesis.json
他会生成一个data0文件夹,里边含有两个文件夹,输出如下代表成功了
其中 geth/chaindata 中存放的是区块数据,keystore 中存放的是账户数据。
接下来便是启动私有链节点
geth --identity "SCAU" --rpc --rpcport "8545" --datadir data0 --port "30303" --rpcapi "db,eth,net,web3" --allow-insecure-unlock --networkid 65534 --nodiscover console
上面命令的主体是 geth console,表示启动节点并进入交互式控制台。
各选项含义如下:
–identity:指定节点,用于标示目前网络的名字;
–rpc:表示开启 HTTP-RPC 服务;
–rpcport:指定 HTTP-RPC 服务监听端口号(默认为 8545);
–datadir:指定区块链数据的存储位置;
–port:指定和其他节点连接所用的端口号(默认为 30303);
–rpcapi: 设置允许连接的rpc的客户端,一般为db,eth,net,web3;
–networkid: 设置当前区块链的网络ID,用于区分不同的网络,是一个数字;
–nodiscover:关闭节点发现机制,防止加入有同样初始配置的陌生节点;
–maxpeers : 如果你不希望其他人连接到你的测试链,可以使用maxpeers 0。反之,如果你确切知道希望多少人连接到你的节点,你也可以通过调整数字来实现;
–rpccorsdomain : 这个可以指示什么URL能连接到你的节点来执行RPC定制端任务。务必谨慎,输入一个特定的URL而不是wildcard ( * ),后者会使所有的URL都能连接到你的RPC实例;
–console:启动命令行模式,可以在Geth中执行命令。
运行上面的命令后,就启动了区块链节点并进入了该节点的控制台:
如下便是成功了
之后,在data0中输入
geth attach ipc:geth.ipc
这回打开一个控制台
控制台操作
1.创建账户
personal.newAccount("0000");
注意:创建账户中的”0000“也是这个账户的密码
查看用户
personal.listAccounts
获取账号
personal.listAccounts[1]
这相当于一个数组,1代表第二个账户
查看账户余额
eth.getBalance("账号");或者
eth.getBalance(personal.listAccounts[0])
注意:没挖矿的情况下为0
解锁账号
personal.unlockAccount(personal.listAccounts[0]);
在这里需要输入密码,就是建立账户时给的
成功返回true
挖矿
miner.start(1)这个是全力挖矿
miner.start()一般用这个就行
如图出现小锤子,说明开始挖了
停止挖矿
miner.stop()
还有其他一些常用操作,不一一示例,后边用得着再说
eth.accounts:枚举系统中的账户;
eth.getBalance():查看账户余额,返回值的单位是 Wei(Wei 是以太坊中最小货币面额单位,类似比特币中的聪,1 ether = 10^18 Wei);
eth.blockNumber:列出区块总数;
eth.getTransaction():获取交易;
eth.getBlock():获取区块;
web3.fromWei():Wei 换算成以太币;
web3.toWei():以太币换算成 Wei;
txpool.status:交易池中的状态;
admin.addPeer():连接到其他节点;
账户之间转账
再创建一个账户,查看一下他的余额还是0
出于人道主义,我们得实现一下财富平等,所以,打钱吧
1.在打钱之前先解锁一下出钱的账户
personal.unlockAccount(personal.listAccounts[0]);
上边演示过了如何解锁,不在赘述
2.金额转换
amount = web3.toWei(5,'ether')
转多少,写多少,比较抠的话也可以写小数,0.00000001也可以的
3.打钱
eth.sendTransaction({
from:personal.listAccounts[0],to:personal.listAccounts[1],value:amount})
from和to后边也可以直接写账户地址,就是创建账户后给的那一串,记得把双引号带着
注意:如果你的账户没有挖矿,那么交易不会发生,所以记得启动一下挖矿
好了,钱打完了,看一下贫富差距
好吧,差距比我和马云都大。。。。
一些小工具
查看交易状态
txpool.status
如果刚才转账了没挖矿,那么pending就为1
查看交易
eth.getBlock("pending",true);
会获得交易的信息
查看交易
eth.getTransaction("交易的一串数据");
产看当前区块数
eth.blockNumber
通过区块号查看区块:
eth.getBlock(4)
实现合约部署
1.首先建立一个.sol文件,在里边写代码
比如如下
pragma solidity ^0.8.3
contract test {
string public data = "hello world!";
function testArray() public returns (string memory){
return data;
}
}
几点说明,这是用solidity写的,有一个solidity的教程可以看一下这个
https://zhuanlan.zhihu.com/p/353507891
pragma solidity ^0.8.3这是版本号
在这里返回值跟c和Java不一样,需要加returns,如果返回值是string,还要加memory
将这个.sol文件和.json文件放一起就可以
然后再这两个文件夹的位置运行如下两个代码
solcjs --bin mystring.sol
这个会生成一个.bin文件
要注意:如果你的代码里有错误,在这里会显示出来,警告可以忽略,但error不幸
在运行如下语句
solcjs --abi mystring.sol
生成一个.abi文件
之后进入data0文件夹,打开控制台
geth attach ipc:geth.ipc
建立code变量和abi变量
code="0x..."
省略的是.bin里边的,直接把.bin里边的数据全部copy过来就可以
需要注意的是,要用双引号包裹,在前边加上0x
abi=...
省略的是.abi文件里的内容,直接复制粘贴就好
解锁账户
personal.unlockAccount(personal.listAccounts[0]);
查看所需gas,就是查一下部署这个合约需要到少手续费
web3.eth.estimateGas({
data:code})
挖矿
miner.start()
发送部署合约
myContract = eth.contract(abi)
contract = myContract.new({
from:eth.accounts[0],data:code,gas:1000000})
获取合约地址
eth.getCode(contract.address)
调用合约
contract.testArray.call()
testArray是方法名,call是内置函数,把自己的方法名改上去就行
遇到msg.sender需要指明请求地址
contract.update.call("0xb18d9b39bb2d624a7bd6db3bd9a119071ac9625e",1111,{
from:eth.accounts[0]})
节点连接
创建文件夹,复制.json过来,创建文件夹data1,初始化
geth --datadir data0 init genesis.json
然后
geth --identity "SCAU" --rpc --rpcport "8545" --datadir data1 --port "30303" --rpcapi "db,eth,net,web3" --allow-insecure-unlock --networkid 65534 --nodiscover console
注意改一下rpcport和port
在data0中输入
geth attach ipc:geth.ipc
查看节点标识
admin.nodeInfo.enode
节点连接
admin.addPeer("enode://4923254425942156a684eebd06f2371f2601b8d4a55e80d9800930715a54da5f3fea189ea99a2d0e573c7efb68b7e35ed14d02657fe674d58abd0f83e4c24dc6@127.0.0.1:3002?discport=0")
里边的要改成你自己节点的标识,也就是admin.nodeInfo.enode的结果
查看连接
admin.peers
查看已连接的节点数量
net.peerCount
看节点1和节点2数据是否完全同步
关掉节点1的挖矿,在节点2查一下节点1的余额,能查到说明连接成功
节点1向节点2转账
eth.sendTransaction({
from: eth.coinbase, to: "0x7992d63ef38d07aeca3ca0958fb751b60038fc41", value: 66666666})
节点间合约方法/函数调用,使用合约地址调用合约
节点2调用节点1部署的合约
定义abi
abi=。。。
.abi里边的内容
定义合约部署地址
用下边这句在节点1查一下
contract.address
在节点2
address=...
在节点2运行下边
myContract = eth.contract(abi)
contract = myContract.at(address)
调合约函数就可以了
contact.ca.call()
如果是有msg.sender的用下边
contract.update.sendTransaction("0x7992d63ef38d07aeca3ca0958fb751b60038fc41",6, {
from: eth.accounts[0]})
contract.update.call("0x7992d63ef38d07aeca3ca0958fb751b60038fc41",6,{
from:eth.accounts[0]})