程序员技术交流互联网科技区块链研习社

区块链系列教程——创建属于自己的区块链

2019-05-01  本文已影响97人  程序员Sunny

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

1. 区块链简介

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

区块链示意图
    实际上,除了区块(区块头)结构,区块链可以抽象出更多的技术,比如共识机制、密码学机制、P2P网络、Hash树、智能合约等,这些可以统称为区块链技术,后续教程会涉及到其中部分的原理。
    以太坊区块链的区块结构较为复杂,远远不止示意图中的结构,有兴趣的读者可以去其github上查看详细源码,这是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"`
}

2. 开始实践

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

1.1 安装geth客户端
方法1

可以直接去官网下载对应操作系统的客户端。

方法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命令后面教程将会详细说明。此处,我们可以控制当前区块链节点做一些操作了。

  1. 创建一个账户
> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x6393bb737b95465ccd9e4597df0647cdcd09775f"
  1. 挖矿
> 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
  1. 查看余额
> eth.getBalance(eth.coinbase)
5000000000000000000
  1. 解锁账户
> personal.unlockAccount(eth.coinbase)
Unlock account 0x6393bb737b95465ccd9e4597df0647cdcd09775f
Passphrase: 
true
  1. 转账
        需要注意的是,转账操作前需要将账户解锁,在转账操作发起成功后,需要等待一段时间,矿工将该转账交易打包进入新的发行区块后才会生效。
> 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

联系与交流

欢迎小伙伴与我讨论哦~

邮箱:zsunny@yeah.net

本文欢迎转载,请注明本文地址:https://www.jianshu.com/p/d1ec1cc10355

上一篇下一篇

猜你喜欢

热点阅读