首页 > 技术文章 > 区块链踩坑之基础扫盲及搭建以太坊网络私有链(单节点)

zhangxiaoyong 2018-05-09 22:33 原文

连载篇提前看

系列文章一:区块链踩坑之基础扫盲及搭建以太坊网络私有链(单节点)

系列文章二:区块链踩坑之搭建以太坊网络私有链(多节点)及创建多重签名钱包

系列文章三:区块链踩坑之智能合约代币编写及使用介绍

前言

区块链近几年如火如荼,呈愈来愈望的趋势。相信不少小伙伴已经踩过坑,也有很多小伙伴还只是听过概念,并未实际接触到,更别谈开发和运用。我们在这里还是先来普及下区块链的基础概念(已经知晓概念和原理的可直接跳到环境篇):

    区块链是什么?
       区块链是一种新型去中心化协议,能安全地存储比特币交易或其它数据,信息不可伪造和篡改,可以自动执行智能合约,无需任何中心化机构的审核。交易既可以是比特币这样的数字货币,也可以是债权、股权、版权等数字资产,区块链技术解决了拜占庭将军问题,大大降低了现实经济的信任成本与会计成本,重新定义了互联网时代的产权制度。  

那更具体和详细一点的描述可以参考下面这段话:

       区块链(Blockchain)是由节点参与的分布式数据库系统,它的特点是不可更改,不可伪造,也可以将其理解为账簿系统(ledger)。它是比特币的一个重要概念,完整比特币区块链的副本,记录了其代币(token)的每一笔交易。通过这些信息,我们可以找到每一个地址,在历史上任何一点所拥有的价值。

      区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成块链。每一个区块都确保按照时间顺序在上一个区块之后产生,否则前一个区块的哈希值是未知的。这些特征使得比特币的双花(double-spending)非常困难。区块链是比特币的核心创新。

区块链概念的出现,首先是在中本聪的比特币白皮书中提到的,但是以工作量证明链(proof-of-work chain)的形式而存在,以下是中本聪对区块链概念的描述:

时间戳服务器通过对以区块(block)形式存在的一组数据,实施随机散列而加上时间戳,并将该随机散列进行广播,就像在新闻或世界性新闻组网络(Usenet)的发帖一样 。显然,该时间戳能够证实特定数据必然于某特定时间是的确存在的,因为只有在该时刻存在了才能获取相应的随机散列值。每个时间戳应当将前一个时间戳纳入其随机散列值中,每一个随后的时间戳都对之前的一个时间戳进行增强(reinforcing),这样就形成了一条链(Chain)。

节点始终都将最长的链视为正确链,并持续工作和延长它。如果有两个节点同时广播不同版本的新区块,那么其他节点在接收到该区块的时间上,将存在先后差别。当此情形,他们将在率先收到的区块基础上进行工作,但也会保留另外一条链,以防后者变成最长链。该僵局(tie)的打破,要等到下一个工作量证明被发现,而其中的一条链被证实为是较长的一条,那么在另一条分支链上工作的节点将转换阵营,开始在较长的链上工作。

      比特币钱包的功能依赖于与区块链的确认,一次有效检验称为一次确认。通常一次交易要获得数个确认才能进行。轻量级(SPV )比特币钱包, 其客户端在本地只需保存与用户可支配交易相关的数据,而不会存储完整的区块链。

    区块链技术是众多加密数字货币的核心,包括比特币、以太坊、莱特币、狗狗币等。维护区块链的方式,有工作量证明(proof-of-work)、权益证明(proof-of-stake)等。

区块链的优势

区块链体系结构的核心优势包括:

1.任何节点都可以创建交易,在经过一段时间的确认之后,就可以合理地确认该交易是否为有效,区块链可有效地防止双花问题的发生。

2.对于试图重写或者修改交易记录而言,它的成本是非常高的。

3.区块链实现了两种记录:交易(transactions)以及区块(blocks)。交易是被存储在区块链上的实际数据,而区块则是记录确认某些交易是在何时,以及以何种顺序成为区块链数据库的一部分。交易是由参与者在正常过程中使用系统所创建的(在加密数字货币的例子中,一笔交易是由bob将代币发送给alice所创建的),而区块则是由我们称之为矿工(miners)的单位负责创建。

区块链工作原理

这里有个问题就是:我们谈的区块链,那什么是区块呢?

 数据通过称之为区块(block)的文件,永久记录在数字货币网络上。它们好比是一个股票交易账本。新的区块会被添加到记录(区块链)的末端,而且一旦书写就很难修改或移除。

区块的结构是什么样的呢?

 

 

 

 

 

 

区块头是什么?

       区块头由三组区块元数据组成。首先是一组引用父区块哈希值的数据,这组元数据用于将该区块与区块链中前一区块相连接。第二组元数据,即难度、时间戳和nonce,与挖矿竞争相关 。第三组元数据是merkle树根(一种用来有效地总结区块中所有交易的数据结构)。

区块头结构是什么?

创始区块是什么?

    比特币区块链的第一个区块,创建于2009年,我们称之为创世区块。它是比特币区块链里所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。

每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。

在chainparams.cpp里可以看到创世区块被编入到比特币核心客户端里。

创世区块的哈希值为:

0000000000 19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

 在命令行使用比特币核心客户端:

$ bitcoindgetblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f{    "hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",    "confirmations":308321,    "size":285,    "height":0,    "version":1,    "merkleroot":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",    "tx":["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"],    "time":1231006505,    "nonce":2083236893,    "bits":"1d00ffff",    "difficulty":1.00000000,    "nextblockhash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"}

      创世区块包含一个隐藏的信息。在其Coinbase交易的输入中包含这样一句话“The Times 03/Jan/2009 Chancellor on brink of second bailout forbanks.”这句话是泰晤士报当天的头版文章标题,引用这句话,既是对该区块产生时间的说明,也可视为半开玩笑地提醒人们 , 一个独立的货币制度的重要性,同时告诉人们随着比特币的发展,一场前所未有的世界性货币革命将要发生。该消息是由比特币的创立者中本聪嵌入创世区块中。

 区块链分叉是什么?

 

     诚实矿工只创建最长有效链上的最新区块。“长度”(Length)指区块链的累计计算难度,而不是是区块数目。当包括在链中的所有区块以及交易都有效,且是从创世区块开始的链,才是被我们承认的有效区块链。

     对于区块链中的任意一个区块,到达创世块的路径只有一条。然而,从创世块开始,会有分叉的情况出现。当创建两个区块的时间差只有几秒时,经常会创建出一个分叉区块。当发生这种情况时,节点就会在他们最先接收到的那个区块上创建区块。无论哪一个区块包含在下一个区块中,它都会成为主链的一部分,因为这条链更长。

      短链(无效链)中的区块没有什么作用。当比特币客户端切换至另外一条更长的区块链时,短链中的所有有效交易区块都重新添加到序列交易池中,且会包含在下一个区块中。短链中的区块奖励不会呈现在最长的区块链中,因此实际上他们是有损失的,这就是为什么需要网络强制的100个区块的成熟时间来让产生存在。

      在短链中的区块,我们通常称之为“孤儿块”(orphans)。这是因为,在长链中这个生成交易并没有父系区块,因为这些生成交易在交易PRC列表中显示为孤儿。一些矿池误解这些信息,声称他们的区块是”孤儿“。事实上,这些区块都有父系区块,而且甚至可能有子系。

 

区块链衍生的几个概念

公链(public blockchain)

公链,是指全世界任何人都可读取、发送交易且能获得有效确认的共识区块链。公链的安全由工作量证明机制(pow)或权益证明机制(pos)等方式负责维护。它们是以经济奖励与加密数字验证相结合的方式而存在的,并遵循着一般原则:每个人从中可获得的经济奖励,与对共识过程作出的贡献成正比。这些区块链通常被认为是“完全去中心化”的。

共同体区块链:(Consortium blockchains)

共同体区块链,是指其共识过程受到预选节点控制的区块链;例如,有15个金融机构组成一个共同体,每个机构都运行着一个节点,而且为了使每个区块生效需要获得其中10个机构的确认。区块链或许允许每个人都可读取,或者只受限于参与者,或走混合型的路线,例如区块的根哈希及其API(应用程序接口)对外公开,API可允许外界用来作有限次数的查询和获取区块链状态的信息。这些区块链可视为“部分去中心化”。

私链(private blockchain),又称无代币区块链(Token-less blockchain)

完全私有的区块链 , 是指其写入权限仅在一个组织手里的区块链。读取权限或者对外开放,或者被任意程度地进行了限制。相关的应用囊括数据库管理、审计、甚至一个公司,但在很多的情形下,公共的可读性并非是必须的。

 

公链和私链的特点

共同体区块链结合了公链的“低信任”和私链的“单一高度信任” , 提供了一种混合的模式,而私链可以更精确地描述为带有一定程度数字加密功能,可管理(permissioned)的传统中心化系统。

环境篇

①下载以太坊钱包Mist或者ETHWallet 

https://github.com/ethereum/mist/releases/tag/0.8.1

我这里提供下我用的两个版本地址:

Mist  链接:https://pan.baidu.com/s/1BVJV9-nJRE4q4QnupNihOw 密码:dt9j

EthWallet 链接:https://pan.baidu.com/s/1Q-tWMI5cC3uPphoQEN1Plw 密码:nhsu

Geth 链接:https://pan.baidu.com/s/1j31K0WJm9PDKy-5Cs4E5Og 密码:5zq1

② 这里我们以Mist为例 ,下载后解压Mist,直接运行,此时会在C盘生成一个Mist的Geth目录  同步区块过程很慢,可以测试环境可直接跳过 

C:\Users\Administrator\AppData\Roaming\Mist\binaries\Geth\unpacked

 我们先将生成的目录添加进系统Path环境变量中 方便我们后续操作。

添加Path后,我们打开命令窗口 执行:geth -h 查看geth版本和其他命令信息 如下图:

此时我们需要注意的是 在C盘目录下 还生成了一个 以太坊目录:C:\Users\Administrator\AppData\Roaming\Ethereum

这个路径下面存放的是 账户秘钥信息,区块文件等信息。

geth account new  创建新账户命令

秘钥一般存放在:C:\Users\Administrator\AppData\Roaming\Ethereum\keystore 如下图所示:

 

 搭建以太坊私有链

编写创始区块CustomGenesis.json 文件内容如下:

{
    "nonce": "0x0000000000000042",     
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x00",     
    "gasLimit": "0x8000000",     
    "difficulty": "0x400",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333",     
    "alloc": {
     },
     "config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    }
}

关注几个重点项:

difficulty”: “0x40000”,//难度,该值越大,出块越慢。

extraData”: “Genesis Block”,//附加信息,随意填写

gasLimit”: “0xffffffff”//每个块所能容载的gas上限

 ①创建目录:E:\Mychains\dev  将创始区块文件放入该目录下

执行cmd 

geth --identity "mydev" --rpc --rpcport "8086" --rpccorsdomain "*" --datadir "E:\Mychains\dev" --port "8545" --nodiscover --rpcapi "db,eth,net,web3" --networkid 99 init "E:\Mychains\dev\CustomGenesis.json"

 其中端口 也可以省略 用默认的 省略写法如下:

geth --identity "mydev" --rpc --rpccorsdomain "*" --datadir "E:\Mychains\dev" --rpcapi "db,eth,net,web3" --networkid 99 init "E:\Mychains\dev\CustomGenesis.json"

执行后:

到这一步 表示私有链已经创建成功。那我们如果使用这个私有链呢?继续往下看

执行cmd:

geth  --identity "mydev" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "E:\Mychains\dev" --port "8545" --nodiscover  --rpcapi "db,eth,net,web3" --networkid 99 console

如果是简写 可以直接写成:

geth  --datadir "E:\Mychains\dev"

 执行后:

到这一步 表示本地私有链已经启动成功,我们可以运行Mist客户端看一下(此时右上角有PRIVAT-NET标示,说明此时链接的是本地私有网络)

运行后主界面如下:

如果是用ETHWallet 钱包客户端打开的,显示界面如下:

剩下的私有链新建账户 和公网主账户一致,在这里就不赘述了。

另外,有几个地方需要注意,我们启动了本地私有链后 可以通过 geth查看下 当前运行的区块路径

首先新开一个cmd命令窗口 输入:

geth attach  ipc:\\.\pipe\geth.ipc

 

上图表示连接成功,然后我们看下 当前主用户的网络信息

输入:admin.nodeInfo 如下图:

如果大家留心观察会发现,这里的节点信息 和我们的创始区块文件是一模一样的。

然后我们看下连接的是哪个区块文件 输入 admin.datadir 如下图:

这个文件就是刚才我们开始创建的那个文件目录。

然后我们新建一个账户输入密码然后点击ok

 

正常创建的账户余额都是为0,然后秘钥存放位置也已经讲过了,会弹框提示备份好你的秘钥 可以直接跳过

然后我们进行挖矿操作,给自己的账户增加一些以太币

挖矿开始命令:

miner.start()

挖矿停止命令:

miner.stop()

效果如下,上面的Account2 是我新建的第二个账户,默认挖矿都是新增到主账户中。

 

 账户之间转账

 自己测试可以新建另一个账户Account2(名称默认),然后点击Account2

操作存入以太币:

然后到页面下方操作发送按钮:

此处弹框输入密码确认此笔交易,可以点击下方Cancel取消该笔交易,我们输入密码后点击Send Tansaction 如下:

 

确认中(确认过程需要网络中的矿工进行挖矿操作,该比交易才能正常进行)

我们这里可以清楚的看到该笔交易的发出者和接受者地址以及手续费等信息。

 

交易成功后 可以看到账户情况

 

 

 

至此,你已经基本了解怎么样在本地搭建以太坊网络私有链(单节点)、挖矿以及账户之间转账等基本操作。

后面文章我会继续补充关于 构建以太坊网络多节点私有链、创建多重签名钱包 以及智能合约 发行代币等内容。

 

未完待续。。。。

 

推荐阅读