区块链系列教程以以太坊区块链为基础,主要包括若干以太坊区块链的创建使用等,还包括部分原理说明,后期还会加入对其的改进。
本文是区块链系列教程的第一章,主要内容是使用以太坊区块链创建私链,并使用控制台进行一些基本操作。

<>1. 区块链简介

    在正文之前,先简单介绍一下区块链的基本概念。
    区块链,顾名思义,其存储形式是若干个区块组成,区块之间通过某种方式联系在一起。如图所示:


    实际上,除了区块(区块头)结构,区块链可以抽象出更多的技术,比如共识机制、密码学机制、P2P网络、Hash树、智能合约等,这些可以统称为区块链技术,后续教程会涉及到其中部分的原理。
    以太坊区块链的区块结构较为复杂,远远不止示意图中的结构,有兴趣的读者可以去其github
<https://github.com/ethereum/go-ethereum>
上查看详细源码,这是go语言实现版本,也是官方主推的版本。此处大概说明以太坊区块链的区块结构,以太坊的区块结构主要定义在go-ethereum/core/types/block.go文件中,其区块结构为:
type Block struct { header *Header uncles []*Header transactions Transactions
// caches hash atomic.Value size atomic.Value // Td is used by package core to
store the total difficulty // of the chain up to and including the block. td
*big.Int // These fields are used by package eth to track // inter-peer block
relay. ReceivedAt time.Time ReceivedFrom interface{} }
    区块结构中,header表示区块头,是非常重要的参数,其具体结构后面会说明
;uncles表示该区块的叔块,也就是父区块的兄弟区块(因为以太坊的区块发行时间只有10秒左右,所以矿工之间会存在竞争,两个同时发行的区块将成为兄弟区块);transactions表示区块中装载的交易信息,这也是一个非常重要的参数,在区块链中交易是最为重要的功能。
    以太坊区块头格式为:
type Header struct { ParentHash common.Hash `json:"parentHash"
gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles"
gencodec:"required"` Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"` TxHash common.Hash
`json:"transactionsRoot" gencodec:"required"` ReceiptHash common.Hash
`json:"receiptsRoot" gencodec:"required"` Bloom Bloom `json:"logsBloom"
gencodec:"required"` Difficulty *big.Int `json:"difficulty"
gencodec:"required"` Number *big.Int `json:"number" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"` GasUsed uint64
`json:"gasUsed" gencodec:"required"` Time uint64 `json:"timestamp"
gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash"` Nonce BlockNonce `json:"nonce"` }
* ParentHash表示父区块的Hash值,该值实际上就是所谓的链,用于实现区块链数据不可逆的特性。
* UncleHash是区块结构中uncles经过hash运算得到的结果,用于验证区块数据的正确性。
* Coinbase用于记录该区块的发行者,其可获得区块奖励和矿工费奖励。
* Root用于验证当前区块链的状态,其中状态使用MPT(Merkle-Patricia-Tree)结构存储。
* TxHash用于验证当前区块的交易信息,所有交易使用
MPT结构组织存储。
* ReceiptHash用于验证当前区块的交易收据信息,对于一个交易执行完成后会有相应的收据,其组织形式也是MPT。
* Bloom是当前区块交易执行日志的布隆过滤器,用于快速确定某交易是否存在。
* Difficulty是当前区块链POW的难度值,这与共识机制有关,后文会详细介绍。
* Number是当前区块高度,即区块id,创世区块为0,逐一递增。
*
GasLimit是当前区块大小,以太坊使用gas机制来控制区块大小,每个交易(包括转账交易和智能合约交易)都会消耗相应的gas,特别是智能合约交易,消耗的gas大小与其执行步骤和存储消耗有关,因为以太坊是图灵完备的,所以需要此措施来防止出现死循环。
* GasUsed是当前区块所消耗的总的gas大小。
* Time是区块打包时间。
* Extra是额外附加信息。
* MixDigest和Nonce是POW共识机制的结果证明。
<>2. 开始实践

    本文主要使用以太坊geth客户端来创建私链,并基于console进行部分简单操作,让读者可以对区块链有一个大概的直观的感觉。

<>1.1 安装geth客户端
<>方法1
可以直接去官网 <https://geth.ethereum.org/downloads/>下载对应操作系统的客户端。
<>方法2
Ubuntu的读者可以通过命令来安装:
sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo
apt-get install ethereum
macOS的读者可以通过brew进行安装:
brew tap ethereum/ethereum brew install ethereum
<>1.2 创世块文件


    在创建私链时,由于我们是从创世块开始,其他区块的内容和创世块会有很大的关系,而创世块是需要我们来设定其中的字段信息的。此处,设置genesis.json文件:
{ "config": { "chainId": 10, "homesteadBlock": 0, "eip155Block": 0,
"eip158Block": 0 }, "alloc" : {}, "coinbase" :
"0x0000000000000000000000000000000000000000", "difficulty" : "0x2000000",
"extraData" : "", "gasLimit" : "0x33450", "nonce" : "0x0000000000000042",
"mixhash" :
"0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" :
"0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00" 17 } <>1.3 创建数据文件夹
使用命令创建数据文件夹test:
<>1.4 初始化区块链
使用命令初始化区块链:
geth --datadir test/ init genesis.json
得到结果:
INFO [05-01|21:27:32.575] Maximum peer count ETH=25 LES=0 total=25 INFO
[05-01|21:27:32.576] Allocated cache and file handles
database=/home/hadoop/blockchain/test/geth/chaindata cache=16 handles=16 INFO
[05-01|21:27:32.581] Writing custom genesis block INFO [05-01|21:27:32.581]
Persisted trie from memory database nodes=0 size=0.00B time=3.104µs gcnodes=0
gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [05-01|21:27:32.581]
Successfully wrote genesis state database=chaindata hash=b123b8…4077eb INFO
[05-01|21:27:32.581] Allocated cache and file handles
database=/home/hadoop/blockchain/test/geth/lightchaindata cache=16 handles=16
INFO [05-01|21:27:32.584] Writing custom genesis block INFO
[05-01|21:27:32.584] Persisted trie from memory database nodes=0 size=0.00B
time=2.105µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO
[05-01|21:27:32.585] Successfully wrote genesis state database=lightchaindata
hash=b123b8…4077eb <>1.5 创建区块链私链
使用命令创建区块链私链:
geth --datadir test/ --networkid 10 console
得到结果:
INFO [05-01|21:29:06.015] Maximum peer count ETH=25 LES=0 total=25 INFO
[05-01|21:29:06.016] Starting peer-to-peer node
instance=Geth/v1.8.17-stable-8bbe7207/linux-amd64/go1.10 INFO
[05-01|21:29:06.016] Allocated cache and file handles
database=/home/hadoop/blockchain/test/geth/chaindata cache=768 handles=512 INFO
[05-01|21:29:06.024] Initialised chain configuration config="{ChainID: 10
Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0
Byzantium: <nil> Constantinople: <nil> Engine: unknown}" INFO
[05-01|21:29:06.024] Disk storage enabled for ethash caches
dir=/home/hadoop/blockchain/test/geth/ethash count=3 INFO [05-01|21:29:06.024]
Disk storage enabled for ethash DAGs dir=/home/hadoop/.ethash count=2 INFO
[05-01|21:29:06.024] Initialising Ethereum protocol versions="[63 62]"
network=10 INFO [05-01|21:29:06.025] Loaded most recent local header number=0
hash=b123b8…4077eb td=33554432 age=50y2w3d INFO [05-01|21:29:06.025] Loaded
most recent local full block number=0 hash=b123b8…4077eb td=33554432
age=50y2w3d INFO [05-01|21:29:06.025] Loaded most recent local fast block
number=0 hash=b123b8…4077eb td=33554432 age=50y2w3d INFO [05-01|21:29:06.025]
Regenerated local transaction journal transactions=0 accounts=0 INFO
[05-01|21:29:06.025] Starting P2P networking INFO [05-01|21:29:08.150] UDP
listener up
self=enode://21d2a8209dc9aeadd15d94c2df30128dd7bd4b772f34e61e8f76afb893a2f7735a77c9061b64076ca61b5635b5d434fa32600af0e56f833fd7e582bff94e679d@222.201.145.179:30303
INFO [05-01|21:29:08.151] RLPx listener up
self=enode://21d2a8209dc9aeadd15d94c2df30128dd7bd4b772f34e61e8f76afb893a2f7735a77c9061b64076ca61b5635b5d434fa32600af0e56f833fd7e582bff94e679d@222.201.145.179:30303
INFO [05-01|21:29:08.155] IPC endpoint opened
url=/home/hadoop/blockchain/test/geth.ipc INFO [05-01|21:29:08.169] Mapped
network port proto=udp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"
INFO [05-01|21:29:08.189] Mapped network port proto=tcp extport=30303
intport=30303 interface="UPNP IGDv1-IP1" Welcome to the Geth JavaScript
console! instance: Geth/v1.8.17-stable-8bbe7207/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 > <>1.6 使用区块链

    完成步骤1.5后,区块链已经可以使用,1.5中的console命令是指开启控制台用于与区块链进行交互——具体的geth命令后面教程将会详细说明。此处,我们可以控制当前区块链节点做一些操作了。

* 创建一个账户 > personal.newAccount() Passphrase: Repeat passphrase:
"0x6393bb737b95465ccd9e4597df0647cdcd09775f"
* 挖矿 > miner.start() INFO [05-01|21:34:33.568] Updated mining threads
threads=8 INFO [05-01|21:34:33.568] Transaction pool price threshold updated
price=1000000000 INFO [05-01|21:34:33.568] Etherbase automatically configured
address=0x6393Bb737b95465cCD9E4597dF0647CdcD09775f null > INFO
[05-01|21:34:33.569] Commit new mining work number=1 sealhash=0fcb98…71f1eb
uncles=0 txs=0 gas=0 fees=0 elapsed=299.471µs
* 查看余额 > eth.getBalance(eth.coinbase) 5000000000000000000
* 解锁账户 > personal.unlockAccount(eth.coinbase) Unlock account
0x6393bb737b95465ccd9e4597df0647cdcd09775f Passphrase: true
* 转账
    需要注意的是,转账操作前需要将账户解锁,在转账操作发起成功后,需要等待一段时间,矿工将该转账交易打包进入新的发行区块后才会生效。 >
eth.sendTransaction({from:eth.coinbase, to:personal.listAccounts[1],
value:100}) INFO [05-01|21:37:28.223] Setting new local account
address=0x6393Bb737b95465cCD9E4597dF0647CdcD09775f INFO [05-01|21:37:28.223]
Submitted transaction
fullhash=0xc2479ec79713c9a7bd638146fabf5175eeaad8df87939af83be91ce4218a7c6c
recipient=0x5eDcF2B2eFa9500C9F056f58E9C032B375b877E0
"0xc2479ec79713c9a7bd638146fabf5175eeaad8df87939af83be91ce4218a7c6c" > INFO
[05-01|21:37:29.194] Commit new mining work number=6 sealhash=47fb15…84b362
uncles=0 txs=1 gas=21000 fees=2.1e-05 elapsed=601.799µs
随后,检查两者的余额,发现已经转账成功:
> eth.getBalance(eth.coinbase) 29999999999999999900 >
eth.getBalance(personal.listAccounts[1]) 100
<>联系与交流

欢迎小伙伴与我讨论哦~

邮箱:[email protected]

本文欢迎转载,请注明本文地址:https://blog.csdn.net/m0_37595562/article/details/89763685
<https://blog.csdn.net/m0_37595562/article/details/89763685>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信