从第三方信任到“信任共产主义”

发布时间:2018-2-1信息来源:热度:

区块链技术被认为是继蒸汽机、电力、互联网之后的下一代颠覆性核心技术。蒸汽机解放了人类的生产力,使得人类的产能大大提升,推动了第一次工业革命;“电气时代”的到来又极大的推动了社会生产力的发展,人类社会的经济、政治、文化、军事、科技和生产力都取得了极大的进步;原子能、计算机等信心技术带来了第三次工业革命,互联网使人类进入了信息时代。在信息时代,人与人之间的信任问题一直是科学家们非常关心的课题,泛化来看,不仅仅是人与人,人与公司,公司与公司,但凡不同的个体之间都是存在信任的确立问题的。个体与个体之间的信任问题不仅仅关乎个体相互之间的“交易”是否能很好的推进,更多的是要构建一个良好的信任网络,而这个网络的构建很可能就是接下来一次工业革命的最大的产物,笔者称之为“交易共产主义时代”。

1999年9月9日,中国浙江省杭州市,一个其貌不扬的年轻人创立了一家名叫“阿里巴巴”的由18个人组成的小公司,这个小公司就像是互联网浪潮中的一朵不起眼的小浪花,没有人料到在不到二十年的时间里,这个公司成长为了中国最大的民营商业王国,估值超过4700亿美元。“星星之火,可以燎原。”阿里巴巴的成功的关键并不在于其创始人或者传说中的“十八罗汉”,它的成功在于适应了历史潮流的发展,它向着历史前进的方向多走了一小步,这一小步便是“第三方信任”。

在特定的范围内,交易的双方并没有建立过联系,他们也可以毫无保留的信任对方。他们之所以相互信任,是因为他们和一个共同的第三方建立了信任关系,第三方为交易的双方提供了信任的担保。在互联网时代,我们的地球被缩小为“地球村”,交易的范围也随着这种缩小而扩大,三十年前人们买一瓶酱油最好的选择到村口,今天人们可以在互联网上和相距一千公里以外的素昧平生的人进行交易,而其中的信任问题便是由第三方——阿里巴巴等电商平台来提供,人类的生活习惯随着这种第三方信任的保证产生了巨大的变化,而这种变化也给“中间人”带来了巨大的收益。“第三方信任”的威力可见一斑。

图1 第三方信任

 

2009年中本聪提出了“比特币”的概念,根据中本聪的思路设计发布的开源软件以及其构建其上的P2P网络。比特币是一种P2P形式的数字货币。于是,第一个点对点的传输的“去中心化支付系统”首次落地。截止日前,比特别的价格已超过40k元/个。而比特币背后的支撑技术——区块链,更是被视为是去中心化交易网络实现的曙光。那么区块链技术到底是如何解决交易网络中的信任问题的呢?这便是我们今天要讨论的共识机制。

图2 区块链信任网络

目前区块链技术中涉及的共识算法有:

PoW:Proof of Work,工作证明。

PoS: Proof of Stake 股权证明。

DPos:Delegated Proof of Stake 委任权益证明。

PBFT: Practical Byzantine Fault Tolerance 拜占庭共识算法。

共识算法的比较如下图所示:

共识算法

PoW

PoS

DPoS

PBFT

性能

一般

较高

去中心化程度

完全

完全

完全

部分

最大允许作恶节点数量

51%

51%

51%

33%

是否需要代币

应用类型

公有链

公有链

公有链

联盟链

能否防范女巫攻击

技术成熟度

成熟

成熟

成熟

较成熟

需要专用硬件

 

PoW

PoW(Proof of Work)是工作量证明, 是比特币系统中采用的共识机制。 比特币交易的合法性是由整个网络合力验证的,只有大多数参与者认同某笔交易, 该交易才被视为有效。

然而, 在这种机制下, 假身份的问题凸显出来,即敌手可能发起女巫攻击(Sybil attack)。 交易发起方可以伪造多个身份, 随后对自己的交易进行确认,由于“大多数人”都认同这笔交易, 即便是双重支付,接收方也会相信并接受该交易。

PoS

PoS(Proof of Stake)本质上是采用权益证明来代替PoW 的算力证明,记账权由最高权益的节点获得,而不是最高算力的节点。权益代表节点对特定数量的货币的所有权,称作币龄或币天数。币龄等于货币数量乘最后一次交易时间长度。

例如,在交易中某人收到 10 个币,持有 10 天,则获得 100 币龄,如果又花去 5 个币,则消耗掉 50 币龄。采用 PoS 共识机制的系统在特定时间点的币龄是有限的,长期持币者有更长的币龄,所以币龄可以视为其在系统中的权益。

共识过程的难度与币龄成反比,这样累计消耗币龄最高的区块将被链接到主链。仅依靠内部币龄和权益而不再需要大量消耗外部算力和资源,解决了 PoW 消耗算力的问题。

PoS 的优点是不像 Pow 那么消耗算力。缺点是拥有权益的参与者未必希望参与记账,还是需要挖矿

DPos

DPoS 在 PoS 的基础上,将记账人的角色专业化。先以权益作为选票来选出记账人,然后记账人之间再轮流记账。所有持币者投票选出一定数量的节点。被选中的节点代理他们进行验证和记账,记账人必须保证 90% 在线。该共识机制中每个节点都能够自主决定其信任的授权节点,且由这些节点轮流记账生成新的区块。

优点是大幅缩小参与验证和记账节点的数量,可以达到秒级的共识验证。缺点是整个共识机制还是依赖于代币,很多商业应用是不需要代币存在的。

PBFT

拜占庭将军问题:

一群将军想要实现某一个目标(一致进攻或者一致撤退),但是单独行动行不通,必须合作, 达成共识;由于叛徒的存在,将军们不知道应该如何达到一致。

了解了拜占庭将军这个古老的问题,就很好理解PBFT机制。这是一种基于消息传递的一致性算法,算法经过三个阶段达成一致性,这些阶段可能因为失败而重复进行。在 N ≥ 3F+1 的情况下一致性是可能解决的。其中,N 为计算机总数,F 为有问题计算机总数。信息在计算机间互相交换后,各计算机列出所有得到的信息,以大多数的结果作为解决办法。只要系统中有 2/3 的节点是正常工作的,就可以保证一致性。

 

以太坊开发:如何在Windows下开发一个简易Dapp

以太坊,是一种区块链技术,一个开源平台,可以创建和发布去中心化的应用程序(Đapp),最终实现去中心化因特网。

以太坊区块链的特点主要包括:

l  单独为智能合约指定编程语言 Solidity;

l  使用了内存需求较高的哈希函数:避免出现算力矿机;

l  uncle 块激励机制:降低矿池的优势,减少区块产生间隔为 15 秒;

l  难度调整算法:一定的自动反馈机制;

l  gas 限制调整算法:限制代码执行指令数,避免循环攻击;

l  记录当前状态的哈希树的根哈希值到区块:某些情形下实现轻量级客户端;

l  为执行智能合约而设计的简化的虚拟机 EVM

本文将通过设计一个简单的去中心化投票系统来对区块链技术进行初步探索,通过智能合约技术实现了投票流程的去中心化。

1.      环境配置

安装nodejs,npm,git,web3,solc

nodejs:官网下载最新版本https://nodejs.org/en/download/current/

npm:在Windows下安装nodejs会自带npm

git:官网下载即可https://git-scm.com/downloads

web3:直接采用npm install web3在Windows下会报错,需要配置大量环境,不建议使用。如果确实需要,可以参考下面这篇文章。

https://medium.com/@PrateeshNanada/steps-to-install-testrpc-in-windows-10-96989a6cd594

建议用npm installweb3@0.20.0,表示安装0.20.0的版本。0.20.0是我写这篇文章时候的最新稳定版。或者在https://www.npmjs.com/package/web3查询当前的稳定版本。将0.20.0替换即可。

solc:直接npm install solc即可

 

2.      用Solidity编写智能合约并使用solc编译

我们这里写一个简单的投票智能合约,可以通过Dapp对给定的候选人投票并计算每个候选人获得的票数。这个合约有四个方法,分别是构造方法,查询票数,投票,和判断是否是候选人,逻辑非常简单。篇幅所限,这里我们就不给出具体的方法了。

在写好了合约之后,我们需要对它进行编译:

[plain] view plain copy

进入node,然后输入以下语句:

>Web3 = require('web3')

>web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

这样我们就初始化了一个web3对象,并可以利用这个web3对象来和区块链进行交互。比如,可以通过这个web3对象来查询它所连接到的区块链的账户信息:

> web3.eth.accounts

那么我们如何编译呢?很简单,使用我们之前安装的solc:

> solc = require('solc')

>code = fs.readFileSync('Voting.sol').toString()

>compiledCode = solc.compile(code)

这几条命令执行完了之后我们就把编译好了的代码存到了compiledCode当中。

 

3.      部署智能合约

testrpc安装语句: npm install ethereumjs-testrpc web3

在部署之前首先我们要先安装并打开testRPC,可以理解为一个测试链,会自动生成十个账户,并且每个账户中都会初始有100个以太币(当然是假的以太币)。

 

另外开启一个控制台,进入node,输入以下命令:

//abiDefinition中保存的是该智能合约的界面信息,JSON.parse() 方法解析一个JSON字符串,构造由字符串描述的JavaScript值或对象。也就是说,把JSON字符串解析为JavaScript值。

>abiDefinition=JSON.parse(compiledCode.contracts[':Voting'].interface)

//这句代码的作用相当于初始化一个只有外壳和界面的投票合约对象

> VotingContract = web3.eth.contract(abiDefinition)

//将这些字节码存到byteCode这个变量中去

> byteCode = compiledCode.contracts[':Voting'].bytecode

//VotingContract.new就将这个合约部署到了以太链上去了,这里VotingContract本身就有abiDefinition,这里把byteCode作为data传入,因此就把其界面和比特码同时利用上了。

> deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})

//到上一句,实际上智能合约就部署好了,这里我们使用这个命令来获取这个合约的地址

> deployedContract.address

这里其实只是相当于作了一个名称的简化

> contractInstance = VotingContract.at(deployedContract.address)

 

4.      在控制台中与智能合约进行交互

可以参考下面的代码,理解起来比较简单,不作过多解释。

> contractInstance.totalVotesFor.call('Rama')

{ [String: '0'] s: 1, e: 0, c: [ 0 ] }

> contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]})

'0xdedc7ae544c3dde74ab5a0b07422c5a51b5240603d31074f5b75c0ebc786bf53'

> contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]})

'0x02c054d238038d68b65d55770fabfca592a5cf6590229ab91bbe7cd72da46de9'

> contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]})

'0x3da069a09577514f2baaa11bc3015a16edf26aad28dffbcd126bde2e71f2b76f'

> contractInstance.totalVotesFor.call('Rama').toLocaleString()

'3'

 

5.      利用网页与智能合约进行交互

在上一步的交互中我们是在nodejs中进行投票和查询的,现在我们就要把这些命令写到js中,并写一个简单的html文件,通过网页来与智能合约进行交互。把这两个文件放到与Voting.sol同级别的目录下。

在index.js中把合约的地址替换之后打开index.html即可在网页上进行我们的投票操作,同时可以通过MetaMask看到我们的交易和以太币的变动情况。