ubuntu16.04安装以太坊并运行

以太坊学习记录

  • 1.入门
    • 1.1技术核心
    • 1.2客户端
    • 1.3 智能合约
    • 1.4 发展路线
  • 2.安装
    • 2.1安装git,nodejs
    • 2.2安装solc
    • 2.3安装
    • 2.4运行
  • 3.以太坊私有链的搭建与运行
    • 3.1搭建一个私有链
    • 3.2Javascript控制台命令
      • 3.2.1新建账户
      • 3.2.2查看余额
      • 3.2.3挖矿
      • 3.2.4交易
      • 3.2.5区块
      • 3.2.6远程节点管理
    • 3.3以太坊cli控制台命令
      • 3.3.1账户管理
      • 3.3.2区块数据管理
    • 3.4以太坊TestRPC测试链搭建


参考来自《区块链开发实战这本书

1.入门

首先来了解下以太坊的一些知识
比特币的设计只适合虚拟货币场景,由于存在非图灵完备、缺少保存状态的账户概念以及pow挖矿机制带来的资源浪费和效率问题,需要一个新的基于区块链的具有图灵完备性、高效共识机制、支持更多应用场景的智能合约开发平台。
以太坊是平台和编程语言

1.1技术核心

1)以太坊虚拟机(EVM),以太坊智能合约运行的环境,是基于栈的虚拟机
2)账户:外部账户(密钥对控制),合约账户;包含4个部分:nonce(发送过的交易数或创建过的合约数),balance(账户拥有的余额,1Ether=10^18Wei),storageRoot(存储内容的merkle patricia树根节点),codeHash(空的字符串哈希值或EVM code的哈希值)
3)消息
4)交易:存储从外部账户发出的消息的签名数据包
5)gas:无论执行到什么位置,gas耗尽就会触发out-of-gas,所有状态回滚,交易执行过程中消耗的gas不会退回,还是支付交易费用添加到矿工账户
6)存储、主存和栈:1.存储,永久的内存区域,key-value(256-256);2.主存,合约执行每次消息有一块新的被清除的主存
7)指令集:
8)消息调用
9)代码调用和库

1.2客户端

目前有4种语言编写的以太坊客户端,go语言实现的Geth,C++实现的Eth,Python实现的Pyethapp和java实现的EthereumJ,go是以太坊官方一直维护并推荐使用的客户端。
parity声称是世界上最快最轻便的以太坊客户端,用rust语言编写。
以太坊有一个专用的客户端浏览器,mist
以太坊有四种专用语言:Serpent,Solidity,Mutan,LLL,其中Solitity是以太坊的首选语言,语法类似于javascript
以太坊的网络类型:主网络的networkid=1,公开的测试网有4个,目前仍在运行的有3个。morden(已退役,2),ropsten(pow,3),kovan(poa,仅parity钱包客户端可用),rinkeby(poa,4)

1.3 智能合约

运行在区块链网络上的程序,称为智能合约(smart contract)
这个程序就像一个可以被信任的人,可以临时保管资产,总是按照事先的规则执行和操作。

1.4 发展路线

以太坊的发展分成4个阶段,Frontier(前沿),Homestead(家园),Metropolis(大都会),Serenity(宁静),在前三个阶段采用工作量证明机制,在第四阶段会切换到权益证明机制,阶段之间的转换通过硬分叉的方式实现
2015.7.30 发布Frontier阶段
2016.3.14 发布Homestead阶段,提供图形界面的钱包
Metropolis分为两个阶段,Byzantium(拜占庭)和Constantinople(君士坦丁堡)
2017.10.16 Byzantium硬分叉成功

2.安装

安装部分有参考下面内容
https://blog.csdn.net/u013137970/article/details/52255001#commentBox
https://blog.csdn.net/weixin_40345905/article/details/81041748

2.1安装git,nodejs

sudo apt-get install git
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y npm

上述步骤如果不行就编译源码,相对耗时,在官网下载

tar -zxvf node-v8.12.0.tar.gz 
cd node-v8.12.0/
sudo ./configure
sudo make
sudo make install

2.2安装solc

solidity是以太坊智能合约的开发语言,测试智能合约、开发Dapp都需要安装

sudo npm install -g solc solc-cli --save-dev

运行solcjs --help报错

parallels@parallels-vm:~$ solcjs --help
/usr/bin/env: ‘node’: No such file or directory

可能是solc与solc-cli的版本不匹配,未解决,走下面的步骤

sudo ln -s /usr/bin/nodejs /usr/local/bin/node

如果需要在geth控制台使用solc编译器,需要以下步骤,添加以太坊官方apt源

sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install -y solc

2.3安装

3)源码编译

git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum/
sudo make geth

最后一步有问题,需要安装go语言环境,报错如下

parallels@parallels-vm:~/go-ethereum$ sudo make geth
build/env.sh go run build/ci.go install ./cmd/geth
build/env.sh: 30: exec: go: not found
Makefile:15: recipe for target 'geth' failed
make: *** [geth] Error 127

4)快速安装
不想用源码的话可以跳过3)通过添加以太坊官网apt源,并安装以太坊客户端

sudo apt-get install software-properties-common
sudo apt-get-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get -y ethereum

下面是安装后的部分日志,就当记录了

Setting up abigen (1.8.16+build15490+xenial) ...
Setting up bootnode (1.8.16+build15490+xenial) ...
Setting up evm (1.8.16+build15490+xenial) ...
Setting up geth (1.8.16+build15490+xenial) ...
Setting up puppeth (1.8.16+build15490+xenial) ...
Setting up rlpdump (1.8.16+build15490+xenial) ...
Setting up wnode (1.8.16+build15490+xenial) ...
Setting up ethereum (1.8.16+build15490+xenial) ...

5)docker安装
还可以通过docker拉取镜像,docker之前安装好了

sudo apt install docker.io
sudo apt install docker-compose

拉取ethereum/client-go:alpine镜像,然后启动

docker pull ethereum/client-go:alpine
docker run -d --name ethereum-node -v /Users/alice/ethereum:/root -p 8545:8545 -p 30303:30303 ethereum/client-go --fast --cache=512

2.4运行

在同步的数据的时候可以指定–datadir参数设置区块数据存放位置,–fast启动快速区块同步模式,在同步到最新区块后,转为正常区块同步模式,–fast貌似不可用
1)公有链上运行一个全节点

geth --cache=512 --datadir "/home/parallels/gethblock" console

2)testnet上

 geth --testnet --cache=512 --datadir "/home/parallels/gethblock" console

打印内容

instance: Geth/v1.8.16-stable-477eb093/linux-amd64/go1.10
 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
> INFO [10-08|15:50:41.385] Block synchronisation started 
INFO [10-08|15:51:04.099] Imported new block headers               count=192 elapsed=699.139ms number=192 hash=9d4976…cf6e5b age=1y10mo3w
INFO [10-08|15:51:04.100] Imported new block receipts  
···

3.以太坊私有链的搭建与运行

3.1搭建一个私有链

1)新建一个geth工作目录,不需要sudo

mkdir geth
cd geth
touch gensis.json

2)创世区块配置文件
创世(Genesis)区块是区块链的起点,这点能确保没有其它节点和你的节点的区块链版本一致,除非创世区块一致。因此我们可一创建任意多的私有区块链

{
    "config":{
        "chainId":15,
        "homesteadBlock":0,
        "eip155Block":0,
        "eip158Block":0
        },
    "alloc":{
        "0xeb680f30715f347d4eb5cd03ac5eced297ac5046":{"balance":"1000000000000000000000000000000"}
        },
    "coinbase":"0x0000000000000000000000000000000000000000",
    "difficulty":"0x01",
    "extraData":"0x0000111122223333",
    "gasLimit":"0xffffffff",
    "nonce":"0x0000000000000001",
    "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp":"0x00"
}

各个参数的介绍

参数名称 参数详解
chainId 指定了独立的区块链网络id,网络id在连接到其它节点的时候会用到,以太坊公网id是1,不同的id网络的节点无法相互连接
homesteadBlock HomesteadBlock是以太坊的第二个主要版本,第一个是Frontier,这个值设置为“0”表示目前正在使用Homestead版本
eip155Block eip是ethereum improvement proposal的缩写,我们的链不会提议分叉,所以设置为“0”即可
eip158Block 同上
minhash 与nonce配合用于挖矿,由上一个区块的一部分生成的哈希,注意它和nonce的设置需要满足以太坊的yellow paper
nonce 一个用于挖矿的64位随机数
difficulty 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
alloc 给某个账户预分配以太币
coinbase 矿工的账号(随便填)
timestamp 设置创世区块的时间戳
parentHash 上一个区块的哈希值,因为是创世区块,所以这个值是0
extraData 可以写入32byte大小的任意数据,每个block都会有,由挖出block的miner来决定要不要写点什么
gasLimit 该值设置对gas的消耗总量限制,用来限制区块能包含的交易信息和,因为我们是私有链,所以填最大

写入之后可以使用jq来看json内容

parallels@parallels-vm:~/geth$ jq . gensis.json 
{
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {
    "0xeb680f30715f347d4eb5cd03ac5eced297ac5046": {
      "balance": "1000000000000000000000000000000"
    }
  },
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x01",
  "extraData": "0x0000111122223333",
  "gasLimit": "0xffffffff",
  "nonce": "0x0000000000000001",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

3)初始化
新建一个目录存放区块链数据,然后在geth目录下执行初始化命令

sudo mkdir db
geth --datadir "./db" init gensis.json

报错1

Fatal: invalid genesis file: json: cannot unmarshal hex string of odd length into Go struct field Genesis.coinbase of type common.Address

应该是输入问题无法解析奇数位的十六进制,发现是我的coinbase少打一位
查看日志打印

parallels@parallels-vm:~/geth$ geth --datadir "./db" init gensis.json
WARN [10-09|09:25:22.161] Sanitizing cache to Go's GC limits       provided=1024 updated=328
INFO [10-09|09:25:22.162] Maximum peer count                       ETH=25 LES=0 total=25
INFO [10-09|09:25:22.162] Allocated cache and file handles         database=/home/parallels/geth/db/geth/chaindata cache=16 handles=16
INFO [10-09|09:25:22.170] Writing custom genesis block 
INFO [10-09|09:25:22.170] Persisted trie from memory database      nodes=1 size=153.00B time=47.625µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [10-09|09:25:22.170] Successfully wrote genesis state         database=chaindata                              hash=e6d323…1fa434
INFO [10-09|09:25:22.170] Allocated cache and file handles         database=/home/parallels/geth/db/geth/lightchaindata cache=16 handles=16
INFO [10-09|09:25:22.173] Writing custom genesis block 
INFO [10-09|09:25:22.173] Persisted trie from memory database      nodes=1 size=153.00B time=34.398µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [10-09|09:25:22.173] Successfully wrote genesis state         database=lightchaindata                              hash=e6d323…1fa434

初始化成功后,会在数据目录db中生成geth和keystore两个文件夹

parallels@parallels-vm:~/geth$ tree
.
├── db
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.log
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   └── lightchaindata
│   │       ├── 000001.log
│   │       ├── CURRENT
│   │       ├── LOCK
│   │       ├── LOG
│   │       └── MANIFEST-000000
│   └── keystore
└── gensis.json

5 directories, 11 files

其中的db/geth/chaindata存放区块数据,db/keysotre存放账户数据
4)启动节点

geth --datadir "./db" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*" --rpcapi "eth,net,web3,personl,admin,shh,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303 --mine --miner.threads 1 --etherbase "0xeb680f30715f347d4eb5cd03ac5eced297ac5046" console

启动节点的参数

参数 参数详解
datadir 指明当前区块链私钥和网络数据存放的位置
rpc 开启http-rpc服务,可以进行智能合约的部署和调试
rpcaddr 指定http-rpc服务监听地址,默认为"localhost"
rpcport 指定http-rpc服务监听端口,默认为8545
rpccorsdomain
rpcapi 设置允许连接的rpc的客户端,一般为db,eth,net,web3
nodiscover 关闭自动连接节点,但是可以手动添加节点,在搭建私有链的时候,为避免其他节点连入私有链,可以使用该命令
maxpeers 设置允许最大连节点数,默认25
networkid 指定以太坊网络id,共有链为1,测试链为3,默认启动1
port 指定以太坊网络监听端口,默认为30303
mine 开启挖矿,默认为cpu挖矿
minerthreads 挖矿占用cpu线程数,默认为4,现命名为miner.threads
etherbase 指定矿工账号
console 启动命令行模式,可以在geth中执行命令

来看启动后

parallels@parallels-vm:~/geth$ geth --datadir "./db" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*" --rpcapi "eth,net,web3,personl,admin,shh,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303 --mine --miner.threads 1 --etherbase "0xeb680f30715f347d4eb5cd03ac5eced297ac5046" console
WARN [10-09|10:03:47.100] Sanitizing cache to Go's GC limits       provided=1024 updated=328
INFO [10-09|10:03:47.101] Maximum peer count                       ETH=30 LES=0 total=30
INFO [10-09|10:03:47.102] Starting peer-to-peer node               instance=Geth/v1.8.16-stable-477eb093/linux-amd64/go1.10
INFO [10-09|10:03:47.102] Allocated cache and file handles         database=/home/parallels/geth/db/geth/chaindata cache=246 handles=512
INFO [10-09|10:03:47.111] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150:  EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Engine: unknown}"
INFO [10-09|10:03:47.111] Disk storage enabled for ethash caches   dir=/home/parallels/geth/db/geth/ethash count=3
INFO [10-09|10:03:47.111] Disk storage enabled for ethash DAGs     dir=/home/parallels/.ethash             count=2
INFO [10-09|10:03:47.111] Initialising Ethereum protocol           versions="[63 62]" network=1981
INFO [10-09|10:03:47.111] Loaded most recent local header          number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|10:03:47.111] Loaded most recent local full block      number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|10:03:47.111] Loaded most recent local fast block      number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|10:03:47.111] Regenerated local transaction journal    transactions=0 accounts=0
INFO [10-09|10:03:47.112] Starting P2P networking 
INFO [10-09|10:03:47.113] RLPx listener up                         self="enode://6a838e31cb369d6823f8737013f8609cec10ee1d6dc6275db1d8faed644f8a5773a9f182167b1b8d88bc06bb683f170dea5cf1281039b2a666108c53d2eb3364@[::]:30303?discport=0"
INFO [10-09|10:03:47.118] IPC endpoint opened                      url=/home/parallels/geth/db/geth.ipc
INFO [10-09|10:03:47.119] HTTP endpoint opened                     url=http://0.0.0.0:8545              cors=* vhosts=localhost
INFO [10-09|10:03:47.119] Transaction pool price threshold updated price=1000000000
INFO [10-09|10:03:47.119] Updated mining threads                   threads=1
INFO [10-09|10:03:47.119] Transaction pool price threshold updated price=1000000000
INFO [10-09|10:03:47.120] Commit new mining work                   number=1 sealhash=9b6ee0…a5293b uncles=0 txs=0 gas=0 fees=0 elapsed=138.878µs
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.16-stable-477eb093/linux-amd64/go1.10
coinbase: 0xeb680f30715f347d4eb5cd03ac5eced297ac5046
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
 datadir: /home/parallels/geth/db
 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

> INFO [10-09|10:03:49.703] Generating DAG in progress               epoch=0 percentage=0 elapsed=1.837s
INFO [10-09|10:03:51.668] Generating DAG in progress               epoch=0 percentage=1 elapsed=3.802s
INFO [10-09|10:03:53.590] Generating DAG in progress               epoch=0 percentage=2 elapsed=5.724s
INFO [10-09|10:03:55.497] Generating DAG in progress               epoch=0 percentage=3 elapsed=7.631s
INFO [10-09|10:03:57.279] Generating DAG in progress               epoch=0 percentage=4 elapsed=9.413s
INFO [10-09|10:03:59.186] Generating DAG in progress               epoch=0 percentage=5 elapsed=11.320s
INFO [10-09|10:04:01.077] Generating DAG in progress               epoch=0 percentage=6 elapsed=13.211s
INFO [10-09|10:04:02.938] Generating DAG in progress               epoch=0 percentage=7 elapsed=15.071s
INFO [10-09|10:04:04.712] Generating DAG in progress    
···

可以看到后面不是挖矿,是生成dag,是虚拟机分配的内存太小的原因,应该是出现锤子,后面有

5)进入javascript控制台
另开一个终端,通过attach命令,连接一个已经启动节点,启动js命令环境

parallels@parallels-vm:~$ cd geth
parallels@parallels-vm:~/geth$ geth --datadir './db' attach ipc:./db/geth.ipc 
WARN [10-09|10:07:40.514] Sanitizing cache to Go's GC limits       provided=1024 updated=328
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.16-stable-477eb093/linux-amd64/go1.10
coinbase: 0xeb680f30715f347d4eb5cd03ac5eced297ac5046
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
 datadir: /home/parallels/geth/db
 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

> 

3.2Javascript控制台命令

在启动参数的rpcapi有设置过,这些是以太坊javascript的内置对象
1)eth:提供操作区块链相关的方法
2)net:提供查看p2p网络状态的方法
3)admin:提供管理节点相关的方法
4)miner:提供启动和停止挖矿的方法
5)personal:提供了管理账户的方法
6)txpool:提供查看内存池的方法
7)web3:除了包含以上对象中的方法,还包含一些单位换算的方法

3.2.1新建账户

需要在开启节点的情况下,才能在js控制台使用命令

geth --datadir "./db" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*" --rpcapi "eth,net,web3,personl,admin,shh,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303  console

上述步骤开启节点不挖矿

> personal.newAccount("123456")
Error: write unix @->/home/parallels/geth/db/geth.ipc: use of closed network connection
> personal.newAccount("123456")
"0x0f9fea676cad4b86d157179d77d038982614104b"

personal.newAccount(“passwd”)用来生成账户,传入的参数是账户密码,执行后会返回账户公钥,生成的账户文件在keystore下

│   └── keystore
│       └── UTC--2018-10-09T02-40-07.234932244Z--0f9fea676cad4b86d157179d77d038982614104b

查看我们刚生成的两个账户,执行两次

> eth.accounts
["0x0f9fea676cad4b86d157179d77d038982614104b", "0x3262f586a0c0b7e82a357c42fb57a0d1b9083d57"]

3.2.2查看余额

> balance=web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
0
> balance=web3.fromWei(eth.getBalance(eth.accounts[1]),"ether")
0

eth.accounts[index]会按传入的索引返回已有的账户,eth.getBalance(address)会返回账户的余额,余额是以wei为单位,传入的参数是账户的公钥,可以看到新建的这两个账户的余额都是0,需要通过挖矿获取

3.2.3挖矿

在挖矿前,先设置挖矿奖励地址

> miner.setEtherbase(eth.accounts[0])
true
> eth.coinbase
"0x0f9fea676cad4b86d157179d77d038982614104b"

设置成功后,我们就开始挖矿,调大虚拟机内存

> miner.start(1)
INFO [10-09|11:23:18.475] Updated mining threads                   threads=1
INFO [10-09|11:23:18.475] Transaction pool price threshold updated price=1000000000
null
> INFO [10-09|11:23:18.475] Commit new mining work                   number=1 sealhash=5ee453…d43b2f uncles=0 txs=0 gas=0 fees=0 elapsed=188.516µs
> INFO [10-09|11:23:32.327] Successfully sealed new block            number=1 sealhash=5ee453…d43b2f hash=3a7693…ac82f9 elapsed=13.852s
INFO [10-09|11:23:32.329]  mined potential block                  number=1 hash=3a7693…ac82f9
INFO [10-09|11:23:32.329] Commit new mining work                   number=2 sealhash=4a9541…3f58a4 uncles=0 txs=0 gas=0 fees=0 elapsed=705.055µs
INFO [10-09|11:23:32.770] Successfully sealed new block            number=2 sealhash=4a9541…3f58a4 hash=d522c7…b6b0ba elapsed=440.109ms
INFO [10-09|11:23:32.770]  mined potential block                  number=2 hash=d522c7…b6b0ba
INFO [10-09|11:23:32.770] Commit new mining work                   number=3 sealhash=28cbd5…160883 uncles=0 txs=0 gas=0 fees=0 elapsed=135.475µs
···
INFO [10-09|11:24:07.320] Successfully sealed new block            number=11 sealhash=9ffeca…eab784 hash=8f021e…b07669 elapsed=1.803s
INFO [10-09|11:24:07.320]  block reached canonical chain          number=4  hash=5b856d…0b87e3
INFO [10-09|11:24:07.320]  mined potential block                  number=11 hash=8f021e…b07669
INFO [10-09|11:24:07.320] Commit new mining work                   number=12 sealhash=1dbbe1…99fdc7 uncles=0 txs=0 gas=0 fees=0 elapsed=105.843µs
INFO [10-09|11:24:07.471] Successfully sealed new block            number=12 sealhash=1dbbe1…99fdc7 hash=253223…a70f75 elapsed=151.429ms
INFO [10-09|11:24:07.471]  block reached canonical chain          number=5  hash=66b687…c722a6
INFO [10-09|11:24:07.471]  mined potential block                  number=12 hash=253223…a70f75
INFO [10-09|11:24:07.471] Commit new mining work                   number=13 sealhash=f0e378…bcb36a uncles=0 txs=0 gas=0 fees=0 elapsed=105.459µs
INFO [10-09|11:24:11.512] Successfully sealed new block            number=13 sealhash=f0e378…bcb36a hash=1f7b2e…2f0d16 elapsed=4.040s
···

出现锤子了,并且块会达到标准链中
现在来余额,另外开一个attach,先停止挖矿,返回的不是true有点奇怪

> miner.stop()
null
> balance=web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
425

现在账户上有425个以太币了

3.2.4交易

在发送转账交易之前需要先解锁账户,否则会报错,600表示600s

> personal.unlockAccount(eth.accounts[0],"123456",600)
true

准备就绪后开始转账操作

> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether")})
INFO [10-09|11:39:38.775] Setting new local account                address=0x0F9fea676cAd4B86d157179d77D038982614104B
INFO [10-09|11:39:38.775] Submitted transaction                    fullhash=0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6 recipient=0x3262f586A0c0b7e82A357c42FB57A0d1b9083D57
"0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6"

查看交易池等待被打包的交易

> txpool.status
{
  pending: 1,
  queued: 0
}

pending表示已提交但还未被处理的交易,下面显示详细信息

> txpool.inspect.pending
{
  0x0F9fea676cAd4B86d157179d77D038982614104B: {
    0: "0x3262f586A0c0b7e82A357c42FB57A0d1b9083D57: 1000000000000000000 wei + 90000 gas × 1000000000 wei"
  }
}

要使交易被处理,需要开启挖矿,我们启动挖矿

> miner.start(1);admin.sleepBlocks(1);miner.stop(1);
INFO [10-09|11:44:43.093] Updated mining threads                   threads=1
INFO [10-09|11:44:43.093] Transaction pool price threshold updated price=1000000000
INFO [10-09|11:44:43.094] Commit new mining work                   number=86 sealhash=21e018…ecdfcd uncles=0 txs=0 gas=0 fees=0 elapsed=126.346µs
INFO [10-09|11:44:43.096] Commit new mining work                   number=86 sealhash=fb70ee…1cacb0 uncles=0 txs=1 gas=21000 fees=2.1e-05 elapsed=2.484ms
INFO [10-09|11:44:54.368] Successfully sealed new block            number=86 sealhash=fb70ee…1cacb0 hash=be7528…a5e03f elapsed=11.273s
INFO [10-09|11:44:54.370]  block reached canonical chain          number=79 hash=fb125b…007941
INFO [10-09|11:44:54.370]  mined potential block                  number=86 hash=be7528…a5e03f
INFO [10-09|11:44:54.370] Commit new mining work                   number=87 sealhash=ad0d6d…ee831e uncles=0 txs=0 gas=0     fees=0       elapsed=389.275µs
Error: Invalid number of input parameters to RPC method
    at web3.js:3133:20
    at web3.js:5008:15
    at web3.js:5051:5
    at web3.js:5075:23
    ···

并没有限制住,后面还有区块被挖出来,所以不止一个区块,先来查看余额

> balance=web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
644
> balance=web3.fromWei(eth.getBalance(eth.accounts[1]),"ether")
1

644=5*129-1
转账成功的

3.2.5区块

转账交易时返回的交易hash可以用来查询发起转账交易时的详情

> eth.getTransaction("0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6")
{
  blockHash: "0xbe752881732690580d24cdeb1362a081c93aa57ca883003f911ba7ea35a5e03f",//交易所在区块的hash值
  blockNumber: 86,//交易所在区块的块号
  from: "0x0f9fea676cad4b86d157179d77d038982614104b",
  gas: 90000,
  gasPrice: 1000000000,
  hash: "0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6",
  input: "0x",//交易附带的数据
  nonce: 0,//交易发起者在之前发起过的交易
  r: "0xe8877ecaed9777a4767d737a99f6905d6c0ad3e6ea077e215bb0f41011490283",
  s: "0x6c28c426d99353e3b19816e6da871bbbdcd9e3b85430adbfd4321740eaf28cf4",
  to: "0x3262f586a0c0b7e82a357c42fb57a0d1b9083d57",
  transactionIndex: 0,//交易在区块中的序号,区块处于pending返回null
  v: "0x42",
  value: 1000000000000000000
}
> 

还有另外一个命令,可以查看交易被打包进区块时的命令

> eth.getTransactionReceipt("0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6")
{
  blockHash: "0xbe752881732690580d24cdeb1362a081c93aa57ca883003f911ba7ea35a5e03f",
  blockNumber: 86,
  contractAddress: null,//创建的合约地址,如果是一个合约创建交易,则返回合约地址,其他情况返回null
  cumulativeGasUsed: 21000,//当前交易执行后累积花费的gas总值
  from: "0x0f9fea676cad4b86d157179d77d038982614104b",
  gasUsed: 21000,//执行当前这个交易单独花费的gas
  logs: [],//这个交易产生的日志对象数组
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",//由logs中的address和topics共同决定
  root: "0x08b18b0bd13b3ce809a5e26795a3c0d554311542bbd7cd15cebed74dde2e26e7",//交易执行后的stateroot
  to: "0x3262f586a0c0b7e82a357c42fb57a0d1b9083d57",//交易接收者的地址
  transactionHash: "0x03ae416d2817a05a1e2c4720dc6ae8b3c0b06b28943cfe7dd71d31b76e7f58a6",
  transactionIndex: 0
}

下面还有一些常用的查询区块命令:
*查看当前区块总数

> eth.blockNumber
129

*查询最新区块

> eth.getBlock('latest')
{
  difficulty: 133705,
  extraData: "0xd683010810846765746886676f312e3130856c696e7578",
  gasLimit: 3786362799,
  gasUsed: 0,
  hash: "0x4367222de32a091e9366d32c9c0f92e294500350dacec50b347b22be5fbb33f7",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0f9fea676cad4b86d157179d77d038982614104b",
  mixHash: "0x40b821fe4ea919ef1647bd7dee575392e5c80bd4b660e7f6945a48ba41808735",
  nonce: "0x216d305d26aa65a5",
  number: 129,
  parentHash: "0x025649a36c8d91b9d5d36ca59b2ea00f0df46a1973e3f675c32678b59d72c968",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 536,
  stateRoot: "0xa9e986c2104ae06f45dfbe208097eadce679001f2585c280ff14051cafca58b2",
  timestamp: 1539056840,
  totalDifficulty: 17173277,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

eth.getBlock(blockNumber|blockHash)根据区块Number或Hash查询区块

> eth.getBlock(0)
{
  difficulty: 1,
  extraData: "0x0000111122223333",
  gasLimit: 4294967295,
  gasUsed: 0,
  hash: "0xe6d323f9071b7765f4cf1b22f7516b271b8c5825d546667d29179dd2c81fa434",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000001",//工作量证明
  number: 0,//当前区块高度
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",//区块receipt trie的根
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",//对叔区块的进行hash运算的结果
  size: 513,//区块大小,字节
  stateRoot: "0xf4963e586b9cd62eb4c47233af0b49b9841b0737baf0872e02c29ea03165e599",//块的状态树根结果
  timestamp: 0,
  totalDifficulty: 1,//达到该区块的难度总数
  transactions: [],//交易数组
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",//交易的merkle树根
  uncles: []//当前区块引用的叔父区块的哈希值
}

这个是我们自己写的创世区块,大部分内容都熟悉的

3.2.6远程节点管理

目前为止,我们的以太坊私有链还是在单机上运行的,接下来看怎么和其他节点通信,唔,我只能尝试两台虚拟了
*查看节点信息

> admin.nodeInfo
{
  enode: "enode://6a838e31cb369d6823f8737013f8609cec10ee1d6dc6275db1d8faed644f8a5773a9f182167b1b8d88bc06bb683f170dea5cf1281039b2a666108c53d2eb3364@[::]:30303?discport=0",
  id: "6a838e31cb369d6823f8737013f8609cec10ee1d6dc6275db1d8faed644f8a5773a9f182167b1b8d88bc06bb683f170dea5cf1281039b2a666108c53d2eb3364",
  ip: "::",
  listenAddr: "[::]:30303",
  name: "Geth/v1.8.16-stable-477eb093/linux-amd64/go1.10",
  ports: {
    discovery: 0,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        chainId: 15,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 17173277,
      genesis: "0xe6d323f9071b7765f4cf1b22f7516b271b8c5825d546667d29179dd2c81fa434",
      head: "0x4367222de32a091e9366d32c9c0f92e294500350dacec50b347b22be5fbb33f7",
      network: 1981
    }
  }
}

*添加节点(我没尝试)

admin.nodeInfo.enode//获取节点二的encode
admin.addPeer("")//上面获取的encode

3.3以太坊cli控制台命令

3.3.1账户管理

*创建新账号

parallels@parallels-vm:~/geth$ geth --datadir './db' account new
WARN [10-09|14:18:05.723] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:18:05.724] Maximum peer count                       ETH=25 LES=0 total=25
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {27d56169b474f570c58c37a39a6433630be58d09}

*列举已存在账号

parallels@parallels-vm:~/geth$ geth --datadir './db' account list
WARN [10-09|14:20:49.310] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:20:49.310] Maximum peer count                       ETH=25 LES=0 total=25
Account #0: {0f9fea676cad4b86d157179d77d038982614104b} keystore:///home/parallels/geth/db/keystore/UTC--2018-10-09T02-40-07.234932244Z--0f9fea676cad4b86d157179d77d038982614104b
Account #1: {3262f586a0c0b7e82a357c42fb57a0d1b9083d57} keystore:///home/parallels/geth/db/keystore/UTC--2018-10-09T02-45-56.804969723Z--3262f586a0c0b7e82a357c42fb57a0d1b9083d57
Account #2: {27d56169b474f570c58c37a39a6433630be58d09} keystore:///home/parallels/geth/db/keystore/UTC--2018-10-09T06-18-17.187006663Z--27d56169b474f570c58c37a39a6433630be58d09

*修改账户密码

parallels@parallels-vm:~/geth$ geth --datadir './db' account update 27d56169b474f570c58c37a39a6433630be58d09
WARN [10-09|14:23:30.021] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:23:30.022] Maximum peer count                       ETH=25 LES=0 total=25
Unlocking account 27d56169b474f570c58c37a39a6433630be58d09 | Attempt 1/3
Passphrase: 
INFO [10-09|14:23:39.512] Unlocked account                         address=0x27d56169B474F570C58C37A39a6433630Be58d09
Please give a new password. Do not forget this password.
Passphrase: 
Repeat passphrase:

*导入密钥文件

geth --datadir './db' account import ecc.key

ecc.key是ECDSA的私钥,这里不尝试了

3.3.2区块数据管理

*导出区块数据
将db目录中的区块数据导出到bak文件

parallels@parallels-vm:~/geth$ geth --datadir './db' export ./bak
WARN [10-09|14:35:09.825] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:35:09.825] Maximum peer count                       ETH=25 LES=0 total=25
INFO [10-09|14:35:09.826] Allocated cache and file handles         database=/home/parallels/geth/db/geth/chaindata cache=498 handles=1024
INFO [10-09|14:35:09.833] Disk storage enabled for ethash caches   dir=/home/parallels/geth/db/geth/ethash count=3
INFO [10-09|14:35:09.833] Disk storage enabled for ethash DAGs     dir=/home/parallels/.ethash             count=2
WARN [10-09|14:35:09.833] Head state missing, repairing chain      number=129 hash=436722…bb33f7
INFO [10-09|14:35:09.839] Rewound blockchain to past state         number=0   hash=e6d323…1fa434
INFO [10-09|14:35:09.839] Loaded most recent local header          number=129 hash=436722…bb33f7 td=17173277 age=2h47m49s
INFO [10-09|14:35:09.839] Loaded most recent local full block      number=0   hash=e6d323…1fa434 td=1        age=49y5mo3w
INFO [10-09|14:35:09.839] Loaded most recent local fast block      number=129 hash=436722…bb33f7 td=17173277 age=2h47m49s
INFO [10-09|14:35:09.839] Exporting blockchain                     file=./bak
INFO [10-09|14:35:09.840] Exporting batch of blocks                count=1
INFO [10-09|14:35:09.840] Exported blockchain                      file=./bak
Export done in 103.155µs

导出成功后会有bak文件

parallels@parallels-vm:~/geth$ ll
total 20
drwxrwxr-x  3 parallels parallels 4096 Oct  9 14:35 ./
drwxr-xr-x 21 parallels parallels 4096 Oct  9 13:58 ../
-rwxrwxr-x  1 parallels parallels  513 Oct  9 14:35 bak*
drwxrwxr-x  4 parallels parallels 4096 Oct  9 13:58 db/
-rw-rw-r--  1 parallels parallels    0 Oct  9 10:45 eth.accounts
-rw-rw-r--  1 parallels parallels  630 Oct  9 09:24 gensis.json

*移除区块数据

parallels@parallels-vm:~/geth$ geth --datadir './db' removedb
WARN [10-09|14:39:40.167] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:39:40.167] Maximum peer count                       ETH=25 LES=0 total=25
/home/parallels/geth/db/geth/chaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [10-09|14:39:46.755] Database successfully deleted            database=chaindata elapsed=259.121µs
/home/parallels/geth/db/geth/lightchaindata
Remove this database? [y/N] y
Remove this database? [y/N] y
INFO [10-09|14:39:48.971] Database successfully deleted            database=lightchaindata elapsed=537.34µs

*导入区块数据
在导入前需要先用gensis.json文件执行初始化操作

geth --datadir './db' init gensis.json 

初始化后可以开始导入区块

parallels@parallels-vm:~/geth$ geth --datadir './db' import ./bak
WARN [10-09|14:42:43.095] Sanitizing cache to Go's GC limits       provided=1024 updated=664
INFO [10-09|14:42:43.096] Maximum peer count                       ETH=25 LES=0 total=25
INFO [10-09|14:42:43.096] Allocated cache and file handles         database=/home/parallels/geth/db/geth/chaindata cache=498 handles=1024
INFO [10-09|14:42:43.103] Disk storage enabled for ethash caches   dir=/home/parallels/geth/db/geth/ethash count=3
INFO [10-09|14:42:43.103] Disk storage enabled for ethash DAGs     dir=/home/parallels/.ethash             count=2
INFO [10-09|14:42:43.103] Loaded most recent local header          number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|14:42:43.103] Loaded most recent local full block      number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|14:42:43.103] Loaded most recent local fast block      number=0 hash=e6d323…1fa434 td=1 age=49y5mo3w
INFO [10-09|14:42:43.103] Importing blockchain                     file=./bak
INFO [10-09|14:42:43.103] Blockchain manager stopped 
Import done in 150.15µs.

Compactions
 Level |   Tables   |    Size(MB)   |    Time(sec)  |    Read(MB)   |   Write(MB)
-------+------------+---------------+---------------+---------------+---------------
   0   |          1 |       0.00070 |       0.00000 |       0.00000 |       0.00000

Read(MB):0.00216 Write(MB):0.00097
Trie cache misses:  0
Trie cache unloads: 0

Object memory: 126.225 MB current, 126.217 MB peak
System memory: 263.530 MB current, 263.530 MB peak
Allocations:   0.017 million
GC pause:      391.196µs

Compacting entire database...
Compaction done in 37.935811ms.

Compactions
 Level |   Tables   |    Size(MB)   |    Time(sec)  |    Read(MB)   |   Write(MB)
-------+------------+---------------+---------------+---------------+---------------
   0   |          0 |       0.00000 |       0.00218 |       0.00000 |       0.00021
   1   |          1 |       0.00070 |       0.00148 |       0.00091 |       0.00070

Read(MB):0.00235 Write(MB):0.00207
INFO [10-09|14:42:43.142] Database closed                          database=/home/parallels/geth/db/geth/chaindata

*更新db目录中的区块数据

parallels@parallels-vm:~/geth$ geth --datadir './db' upgradedb
WARN [10-09|14:44:52.823] Sanitizing cache to Go's GC limits       provided=1024 updated=664
invalid command: "upgradedb"

emmmm…无效的指令,根据geth help来看,确实没有这个指令
*dump(未尝试)
从区块链中抛弃某一区块数据

geth --datadir './db' number/blockHash

3.4以太坊TestRPC测试链搭建

testrpc是一个基于node.js开发的以太坊客户端,使用ethereumjs模拟以太坊完整客户端的行为,帮助快速开发
前面我们已经安装过nodejs了,不过很尴尬的是版本不够

parallels@parallels-vm:~$ nodejs --version
v4.2.6

首先卸载,然后再装

sudo apt-get --purge remove nodejs
tar -zxvf node-v8.12.0.tar.gz 
cd node-v8.12.0/
sudo ./configure
sudo make
sudo make install

然后安装testrpc

sudo npm install -g ethereumjs-testrpc
···//日志
+ ethereumjs-testrpc@6.0.3
added 331 packages from 281 contributors in 11.262s

testrpc客户端的基本使用方法如下

testrpc -a 1//-a或--accounts指定在启动时生成多少个账户
parallels@parallels-vm:~$ testrpc -a 1
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0xfc277a31bacb72c35dc7cbcda0dbda3e36779979

Private Keys
==================
(0) 263dcf64aea1c34d99f5870b5e47c3be40d3c447c7f66d42a36f9e98398f2a6d

HD Wallet
==================
Mnemonic:      double hint anger erosion exile easy index vintage city ecology harvest glad
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545


testrpc -b 1//-b或--blocktime设置每隔多少秒产生一个区块,用于自动挖矿。默认0,不挖矿
testrpc -n//-n或--secure默认锁上所有可用的账户
testrpc -a 1 -m "squirrel shield mass ···"//-m或--mnemonic使用一个指定分层确定性钱包助记符来生成初始地址
testrpc -a 1 -d -p 8888//-p或--port用于监听的端口,默认8545
testrpc -a 1 -s "11"//-s或--seed使用任意的数据生成分层确定钱包助记符

-h或–hostname 用于设置监听的域名
-g或–gasPrice 自定义gas价格(默认200000000000)
-l或–gasLimit 自定义gas限额(默认0x47E7C4)
···

你可能感兴趣的:(以太坊)