200行代码就能写出区块链

发表于:2018-2-06 09:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:待字闺中    来源:搜狐科技

#
it
#
代码
#
技术
  区块链的概念好理解,也不好理解。区块链是很多技术的合集,尤其是密码学对大多数工程师来说很陌生,更不用说更复杂的比特币。其实区块链很简单,最近看了一篇英文文章,介绍得很清楚,我根据自己的理解翻译,并且加上我的注解,希望可以让大家明白什么是区块链。
  区块链的基本概念很简单:
  区块链是一个基于共识机制的、去中心化的、公开的、不可篡改的分布式数据库
  有几个特点:
  ●共识机制,很巧妙的设计,保证了数据的一致性
  ●去中心化,是所有的节点都是对等的,没有中央节点,网络中的节点平起平坐。
  ●公开的,大家都可以看到。实际上,一种理想的情况,各个节点都有完整的数据,然后共识机制来保证数据一致。
  ●不可篡改,所有节点的监督,以及可以通过算法检查,密码学相关部分
  我认为区块链的几个特点中,共识机制是最创新的。其他的只是技术的合集。去中心化这个特点,只能说看上去很美。比较理想的状况了。这里底层是有原因的,算力和资源的本质就是集中的。所以,挖矿这件事是违背去中心化的。不过已经很好了。这一点,很多比特币的狂热粉丝会和我争论,我们后面找机会展开。
  区块结构
  第一步了解下区块的结构,因为是了解区块链,所以进行了简化,像重要的norance并没有提,所以,工作量证明也不包含在这篇文章里。一个区块包括:
  ●index
  ●timestamp 时间有序
  ●data
  ●hash
  ●previous hash
  代码如下:
  classBlock { constructor(index, previousHash, timestamp, data, hash) { this.index = index; this.previousHash = previousHash.toString(); this.timestamp = timestamp; this.data = data; this.hash = hash.toString(); }} 区块哈希
  用来保证数据完整性,保证没有被篡改,我们这里采用和比特币一样的SHA-256算法。
  varcalculateHash = (index, previousHash, timestamp, data) => { returnCryptoJS.SHA256(index + previousHash + timestamp + data).toString();}; 产生区块
  比特币中区块是通过“挖矿”得到的,不断的计算满足某个条件的hash值,这里通过简单的计算模拟:
  sha256(index+hash+data+timestamp)
  vargenerateNextBlock = (blockData) => { varpreviousBlock = getLatestBlock(); varnextIndex = previousBlock.index + 1; varnextTimestamp = new Date().getTime() / 1000; varnextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); return newBlock(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);}; 区块存储
  这里,我们采用一个JS的数组来存储区块链,做一个模拟,我们初始化一个“创世区块”
  vargetGenesisBlock = () => { returnnewBlock( 0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");}; varblockchain = [getGenesisBlock()]; 验证区块的完整性
  这个是很重要的一点,实际上就是看数据是否一致,是否被篡改。计算hash进行比对。
  varisValidNewBlock = (newBlock, previousBlock) => { if(previousBlock.index + 1!== newBlock.index) { console.log( 'invalid index'); returnfalse; } elseif(previousBlock.hash !== newBlock.previousHash) { console.log( 'invalid previoushash'); returnfalse; } elseif(calculateHashForBlock(newBlock) !== newBlock.hash) { console.log( 'invalid hash: '+ calculateHashForBlock(newBlock) + ' '+ newBlock.hash); returnfalse; } returntrue;}; 区块链合并
  在网络中,同时会有多个矿工在挖矿,如果大家几乎同时提交,那么比特币就会出现“分叉”,那么怎么办呢?做法很简单,就是选择最长的链。如下图:
  代码如下:
  varreplaceChain = (newBlocks) => { if(isValidChain(newBlocks) && newBlocks.length > blockchain.length) { console.log( 'Received blockchain is valid. Replacing current blockchain with received blockchain'); blockchain = newBlocks; broadcast(responseLatestMsg()); } else{ console.log( 'Received blockchain invalid'); }}; 网络节点之间的通信
  这部分很重要,比较关键的点在于保证网络中的区块链是同步的。如何保证呢?
  ●当一个节点产生了一个新的区块,要广播给其他节点。
  ●当一个节点和一个另一个节点建立了连接,要查询最新的区块。为了检查区块链是否一致,如果出现情况,按照下一步处理。
  ●当接受到一个区块的index大于当前链的index,有几种情况:
  ●如果当前区块链上最新区块的hash和接受区块的previousHash相同,则加入区块链
  ●如果不相同:
  ●接受的区块数为1,则广播获取完整区块链,然后在合并
  ●接受的区块数大于1,则合并区块链
  这里没有实现节点发现的机制,可以通过配置固定一些peer进行测试
  节点控制
  提供rest接口,对节点进行控制,模拟挖矿:
  varinitHttpServer = () => { varapp = express(); app.use(bodyParser.json()); app.get( '/blocks', (req, res) => res.send( JSON.stringify(blockchain))); app.post( '/mineBlock', (req, res) => { varnewBlock = generateNextBlock(req.body.data); addBlock(newBlock); broadcast(responseLatestMsg()); console.log( 'block added: '+ JSON.stringify(newBlock)); res.send(); }); app.get( '/peers', (req, res) => { res.send(sockets.map(s => s._socket.remoteAddress + ':'+ s._socket.remotePort)); }); app.post( '/addPeer', (req, res) => { connectToPeers([req.body.peer]); res.send(); }); app.listen(http_port, () => console.log( 'Listening http on port: '+ http_port));}; 架构
  网络中节点暴露rest接口和websocket接口,websocket接口主要用户网络节点之间的数据同步,维护数据一致性,rest接口主要用户提供功能操作。
  结论
  这篇文章,主要是为了大家理解什么是区块链,或者单纯的区块链,不包含比特币相关特性的。有代码,差不多200行就实现了简单的功能完善的区块链,JavaScrip实现,代码简单很容易理解。相信通过这篇文章,都可以明白什么是区块链。至于挖矿、共识机制机制,我们在后续的文章中介绍。
  如果要一起讨论区块链,可以加入“待字闺中读者群”小密圈,一起讨论区块链应用。


上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号