当前位置:首页 » 区块链知识 » 区块链peer命令

区块链peer命令

发布时间: 2022-09-17 00:48:59

❶ 如何用JavaScript实现区块链

<span style="font-family:Arial, Helvetica, sans-serif;">'use strict';</span>var CryptoJS = require("crypto-js");var express = require("express");var bodyParser = require('body-parser');var WebSocket = require("ws");var http_port = process.env.HTTP_PORT || 3001;var p2p_port = process.env.P2P_PORT || 6001;var initialPeers = process.env.PEERS ? process.env.PEERS.split(',') : [];class Block { constructor(index, previousHash, timestamp, data, hash) { this.index = index; this.previousHash = previousHash.toString(); this.timestamp = timestamp; this.data = data; this.hash = hash.toString(); }}var sockets = [];var MessageType = { QUERY_LATEST: 0, QUERY_ALL: 1, RESPONSE_BLOCKCHAIN: 2};var getGenesisBlock = () => { return new Block(0, "0", 1465154705, "my genesis block!!", "");};var blockchain = [getGenesisBlock()];var initHttpServer = () => { var app = express(); app.use(bodyParser.json()); app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain))); app.post('/mineBlock', (req, res) => { var newBlock = 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));};var initP2PServer = () => { var server = new WebSocket.Server({port: p2p_port}); server.on('connection', ws => initConnection(ws)); console.log('listening websocket p2p port on: ' + p2p_port);};var initConnection = (ws) => { sockets.push(ws); initMessageHandler(ws); initErrorHandler(ws); write(ws, queryChainLengthMsg());};var initMessageHandler = (ws) => { ws.on('message', (data) => { var message = JSON.parse(data); console.log('Received message' + JSON.stringify(message)); switch (message.type) { case MessageType.QUERY_LATEST: write(ws, responseLatestMsg()); break; case MessageType.QUERY_ALL: write(ws, responseChainMsg()); break; case MessageType.RESPONSE_BLOCKCHAIN: handleBlockchainResponse(message); break; } });};var initErrorHandler = (ws) => { var closeConnection = (ws) => { console.log('connection failed to peer: ' + ws.url); sockets.splice(sockets.indexOf(ws), 1); }; ws.on('close', () => closeConnection(ws)); ws.on('error', () => closeConnection(ws));};var generateNextBlock = (blockData) => { var previousBlock = getLatestBlock(); var nextIndex = previousBlock.index + 1; var nextTimestamp = new Date().getTime() / 1000; var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);};var calculateHashForBlock = (block) => { return calculateHash(block.index, block.previousHash, block.timestamp, block.data);};var calculateHash = (index, previousHash, timestamp, data) => { return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();};var addBlock = (newBlock) => { if (isValidNewBlock(newBlock, getLatestBlock())) { blockchain.push(newBlock); }};var isValidNewBlock = (newBlock, previousBlock) => { if (previousBlock.index + 1 !== newBlock.index) { console.log('invalid index'); return false; } else if (previousBlock.hash !== newBlock.previousHash) { console.log('invalid previoushash'); return false; } else if (calculateHashForBlock(newBlock) !== newBlock.hash) { console.log(typeof (newBlock.hash) + ' ' + typeof calculateHashForBlock(newBlock)); console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); return false; } return true;};var connectToPeers = (newPeers) => { newPeers.forEach((peer) => { var ws = new WebSocket(peer); ws.on('open', () => initConnection(ws)); ws.on('error', () => { console.log('connection failed') }); });};var handleBlockchainResponse = (message) => { var receivedBlocks = JSON.parse(message.data).sort((b1, b2) => (b1.index - b2.index)); var latestBlockReceived = receivedBlocks[receivedBlocks.length - 1]; var latestBlockHeld = getLatestBlock(); if (latestBlockReceived.index > latestBlockHeld.index) { console.log('blockchain possibly behind. We got: ' + latestBlockHeld.index + ' Peer got: ' + latestBlockReceived.index); if (latestBlockHeld.hash === latestBlockReceived.previousHash) { console.log("We can append the received block to our chain"); blockchain.push(latestBlockReceived); broadcast(responseLatestMsg()); } else if (receivedBlocks.length === 1) { console.log("We have to query the chain from our peer"); broadcast(queryAllMsg()); } else { console.log("Received blockchain is longer than current blockchain"); replaceChain(receivedBlocks); } } else { console.log('received blockchain is not longer than received blockchain. Do nothing'); }};var replaceChain = (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'); }};var isValidChain = (blockchainToValidate) => { if (JSON.stringify(blockchainToValidate[0]) !== JSON.stringify(getGenesisBlock())) { return false; } var tempBlocks = [blockchainToValidate[0]]; for (var i = 1; i < blockchainToValidate.length; i++) { if (isValidNewBlock(blockchainToValidate[i], tempBlocks[i - 1])) { tempBlocks.push(blockchainToValidate[i]); } else { return false; } } return true;};var getLatestBlock = () => blockchain[blockchain.length - 1];var queryChainLengthMsg = () => ({'type': MessageType.QUERY_LATEST});var queryAllMsg = () => ({'type': MessageType.QUERY_ALL});var responseChainMsg = () =>({ 'type': MessageType.RESPONSE_BLOCKCHAIN, 'data': JSON.stringify(blockchain)});var responseLatestMsg = () => ({ 'type': MessageType.RESPONSE_BLOCKCHAIN, 'data': JSON.stringify([getLatestBlock()])});var write = (ws, message) => ws.send(JSON.stringify(message));var broadcast = (message) => sockets.forEach(socket => write(socket, message));connectToPeers(initialPeers);initHttpServer();initP2PServer();

❷ 区块链技术框架有哪些

当前主流的区块链架构包含六个层级:网络层、数据层、共识层、激励层、合约层和应用层。图中将数据层和网络层的位置进行了对调,主要用途将在下一节中详述。
网络层:区块链网络本质是一个P2P(Peer-to-peer点对点)的网络,网络中的资源和服务分散在所有节点上,信息的传输和服务的实现都直接在节点之间进行,可以无需中间环节和服务器的介入。每一个节点既接收信息,也产生信息,节点之间通过维护一个共同的区块链来同步信息,当一个节点创造出新的区块后便以广播的形式通知其他节点,其他节点收到信息后对该区块进行验证,并在该区块的基础上去创建新的区块,从而达到全网共同维护一个底层账本的作用。所以网络层会涉及到P2P网络,传播机制,验证机制等的设计,显而易见,这些设计都能影响到区块信息的确认速度,网络层可以作为区块链技术可扩展方案中的一个研究方向;
数据层:区块链的底层数据是一个区块+链表的数据结构,它包括数据区块、链式结构、时间戳、哈希函数、Merkle树、非对称加密等设计。其中数据区块、链式结构都可作为区块链技术可扩展方案对数据层研究时的改进方向。
共识层:它是让高度分散的节点对区块数据的有效性达到快速共识的基础,主要的共识机制有POW(Proof Of Work工作量证明机制),POS(Proof of Stake权益证明机制),DPOS(Delegated Proof of Stake委托权益证明机制)和PBFT(Practical Byzantine Fault Tolerance实用拜占庭容错)等,它们一直是区块链技术可扩展方案中的重头戏。
激励层:它是大家常说的挖矿机制,用来设计一定的经济激励模型,鼓励节点来参与区块链的安全验证工作,包括发行机制,分配机制的设计等。这个层级的改进貌似与区块链可扩展并无直接联系。
合约层:主要是指各种脚本代码、算法机制以及智能合约等。第一代区块链严格讲这一层是缺失的,所以它们只能进行交易,而无法用于其他的领域或是进行其他的逻辑处理,合约层的出现,使得在其他领域使用区块链成为了现实,以太坊中这部分包括了EVM(以太坊虚拟机)和智能合约两部分。这个层级的改进貌似给区块链可扩展提供了潜在的新方向,但结构上来看貌似并无直接联系
应用层:它是区块链的展示层,包括各种应用场景和案例。如以太坊使用的是truffle和web3-js.区块链的应用层可以是移动端,web端,或是是融合进现有的服务器,把当前的业务服务器当成应用层。这个层级的改进貌似也给区块链可扩展提供了潜在的新方向,但结构上来看貌似并无直接联系。
链乔教育在线旗下学硕创新区块链技术工作站是中国教育部学校规划建设发展中心开展的“智慧学习工场2020-学硕创新工作站 ”唯一获准的“区块链技术专业”试点工作站。专业站立足为学生提供多样化成长路径,推进专业学位研究生产学研结合培养模式改革,构建应用型、复合型人才培养体系。

❸ 区块链的核心技术是什么

简单来说,区块链是一个提供了拜占庭容错、并保证了最终一致性的分布式数据库;从数据结构上看,它是基于时间序列的链式数据块结构;从节点拓扑上看,它所有的节点互为冗余备份;从操作上看,它提供了基于密码学的公私钥管理体系来管理账户。
或许以上概念过于抽象,我来举个例子,你就好理解了。
你可以想象有 100 台计算机分布在世界各地,这 100 台机器之间的网络是广域网,并且,这 100 台机器的拥有者互相不信任。
那么,我们采用什么样的算法(共识机制)才能够为它提供一个可信任的环境,并且使得:
节点之间的数据交换过程不可篡改,并且已生成的历史记录不可被篡改;
每个节点的数据会同步到最新数据,并且会验证最新数据的有效性;
基于少数服从多数的原则,整体节点维护的数据可以客观反映交换历史。
区块链就是为了解决上述问题而产生的技术方案。
二、区块链的核心技术组成
无论是公链还是联盟链,至少需要四个模块组成:P2P 网络协议、分布式一致性算法(共识机制)、加密签名算法、账户与存储模型。
1、P2P 网络协议
P2P 网络协议是所有区块链的最底层模块,负责交易数据的网络传输和广播、节点发现和维护。
通常我们所用的都是比特币 P2P 网络协议模块,它遵循一定的交互原则。比如:初次连接到其他节点会被要求按照握手协议来确认状态,在握手之后开始请求 Peer 节点的地址数据以及区块数据。
这套 P2P 交互协议也具有自己的指令集合,指令体现在在消息头(Message Header) 的 命令(command)域中,这些命令为上层提供了节点发现、节点获取、区块头获取、区块获取等功能,这些功能都是非常底层、非常基础的功能。如果你想要深入了解,可以参考比特币开发者指南中的 Peer Discovery 的章节。
2、分布式一致性算法
在经典分布式计算领域,我们有 Raft 和 Paxos 算法家族代表的非拜占庭容错算法,以及具有拜占庭容错特性的 PBFT 共识算法。
如果从技术演化的角度来看,我们可以得出一个图,其中,区块链技术把原来的分布式算法进行了经济学上的拓展。
在图中我们可以看到,计算机应用在最开始多为单点应用,高可用方便采用的是冷灾备,后来发展到异地多活,这些异地多活可能采用的是负载均衡和路由技术,随着分布式系统技术的发展,我们过渡到了 Paxos 和 Raft 为主的分布式系统。
而在区块链领域,多采用 PoW 工作量证明算法、PoS 权益证明算法,以及 DPoS 代理权益证明算法,以上三种是业界主流的共识算法,这些算法与经典分布式一致性算法不同的是,它们融入了经济学博弈的概念,下面我分别简单介绍这三种共识算法。
PoW: 通常是指在给定的约束下,求解一个特定难度的数学问题,谁解的速度快,谁就能获得记账权(出块)权利。这个求解过程往往会转换成计算问题,所以在比拼速度的情况下,也就变成了谁的计算方法更优,以及谁的设备性能更好。
PoS: 这是一种股权证明机制,它的基本概念是你产生区块的难度应该与你在网络里所占的股权(所有权占比)成比例,它实现的核心思路是:使用你所锁定代币的币龄(CoinAge)以及一个小的工作量证明,去计算一个目标值,当满足目标值时,你将可能获取记账权。
DPoS: 简单来理解就是将 PoS 共识算法中的记账者转换为指定节点数组成的小圈子,而不是所有人都可以参与记账。这个圈子可能是 21 个节点,也有可能是 101 个节点,这一点取决于设计,只有这个圈子中的节点才能获得记账权。这将会极大地提高系统的吞吐量,因为更少的节点也就意味着网络和节点的可控。
3、加密签名算法
在区块链领域,应用得最多的是哈希算法。哈希算法具有抗碰撞性、原像不可逆、难题友好性等特征。
其中,难题友好性正是众多 PoW 币种赖以存在的基础,在比特币中,SHA256 算法被用作工作量证明的计算方法,也就是我们所说的挖矿算法。
而在莱特币身上,我们也会看到 Scrypt 算法,该算法与 SHA256 不同的是,需要大内存支持。而在其他一些币种身上,我们也能看到基于 SHA3 算法的挖矿算法。以太坊使用了 Dagger-Hashimoto 算法的改良版本,并命名为 Ethash,这是一个 IO 难解性的算法。
当然,除了挖矿算法,我们还会使用到 RIPEMD160 算法,主要用于生成地址,众多的比特币衍生代码中,绝大部分都采用了比特币的地址设计。
除了地址,我们还会使用到最核心的,也是区块链 Token 系统的基石:公私钥密码算法。
在比特币大类的代码中,基本上使用的都是 ECDSA。ECDSA 是 ECC 与 DSA 的结合,整个签名过程与 DSA 类似,所不一样的是签名中采取的算法为 ECC(椭圆曲线函数)。
从技术上看,我们先从生成私钥开始,其次从私钥生成公钥,最后从公钥生成地址,以上每一步都是不可逆过程,也就是说无法从地址推导出公钥,从公钥推导到私钥。
4、账户与交易模型
从一开始的定义我们知道,仅从技术角度可以认为区块链是一种分布式数据库,那么,多数区块链到底使用了什么类型的数据库呢?
我在设计元界区块链时,参考了多种数据库,有 NoSQL 的 BerkelyDB、LevelDB,也有一些币种采用基于 SQL 的 SQLite。这些作为底层的存储设施,多以轻量级嵌入式数据库为主,由于并不涉及区块链的账本特性,这些存储技术与其他场合下的使用并没有什么不同。
区块链的账本特性,通常分为 UTXO 结构以及基于 Accout-Balance 结构的账本结构,我们也称为账本模型。UTXO 是“unspent transaction input/output”的缩写,翻译过来就是指“未花费的交易输入输出”。
这个区块链中 Token 转移的一种记账模式,每次转移均以输入输出的形式出现;而在 Balance 结构中,是没有这个模式的。

❹ 区块链科普

区块链的概念这么火,竟然没有人能很好的解释基本概念。

到找了一个网站,用图示的方法解释了一些基本概念。 blockchian demo

以下是涉及到的概念。

data  hash   block   nouce  mine

prev  distributed   peer   token  coinbase

理解如下:

1 hash和data的关系。

不同的data对应不同的hash,输入相同的data,会出现相同的hash,但是你无法从hash反推出data是什么。这是由数学算法决定的。

没有数据或者海量数据,hash依旧是那么多位数。

2 block。

区块。简易版的组成:block序号。nonce。data。hash。mine。

3 nonce。mine。

nonce与hash的关系。nonce是一组数字,不同的nonce对应不同的hash,而且是一一对应。也就是说,hash改变,nonce也必须改变。

当你在block里面改变你的data时,你的hash改变了,hash是自动改变的。但是同时,你的nonce并没有改变,于是它与hash不匹配。这个时候,你的这个block就会被判定无效(invalidate)。

这个时候,通过挖矿(mine),运行算法,来给当前的hash匹配到相应的nonce,使这个block生效。mine需要耗费计算资源。

nonce被翻译成碰撞数,也是生动。

4 blockchain

blockchain就是block的链条。他们通过prev,也就是记录前一个block的hash链接起来。因此,第一个block没有prvious hash。

在blockchain中,跟block一样,如果你改变任意一个节点的data,其hash值改变后,为了让它validate,你需要mine,以匹配到nonce。我试着mine了后,发现改变data后的hash变化后,mine后的hash还会继续改变,跟nonce都变化了,这样才validate了。这里并不明白为什么。

同时,由于其后一个block继承到了新的prev hash,整个block变得invalidate,需要mine。也就是说,被改变后的block连同其后的每一个block都需要mine,才能validate。

5 distributed 分布式

一条区块链会有n个peer,是其完全相同的复制品。我的理解是:每个人都有一个完整的、与其他人相同的记录在区块链的账本。当一个blockchain里的数据改变时,它需要使用mine的方式重新使得整个blockchain有效,但与此同时,系统会发现它与其他的blockchain是不一会的(比对最后一个block的hash等就可以了),这时会判定其他多数的blockchain是有效的,用少数服从多数原则判定账本,也就是说,这个blockchain的改变会视为无效。

6  token(代币)

token的英英解释是这样的:

 A  token  is a round flat piece of metal or plastic that is sometimes used instead of money。

翻译成代币也算是准确。

token就是记录在block中data里面的交易数据,包括金额,以及from 和to。

每个block里的token记录的都是所有的转账记录。(目前的理解)也就是说,当你进行了一笔交易时,这个交易记录会被广播到所有peer的block中的token记录里。

7 coinbase

可以理解为币池,就是流通的货币总量。就是这个blockchain里面的token总额或者叫做coin有多少。

❺ 初识Hyperledger Fabric

Fabric是联盟链,Peer代表一系列组织,Peers是整个区块链网络的基础,因为它是账本和智能合约的载体。通过智能合约,账本通过不可篡改的方式记录了交易的全过程。

对于不能的公司来说,是有不同的业务的,不同的业务又与不同的公司相关联,需要创建多个联盟链,因此就需要创建多个channel,channel是多个特定成员之间以机密交易为目的建立的私网,一个peer可以加入多个channel,每个channel维护自己的账本,账本和账本之间是隔离的,每个channel可以维护一个或多个账本。所以为了满足复杂的交易需求,每个peer上可以安装不同的智能合约,当peer交易完成时,会发送事件通知Client。peer上还有一个Local MSP(成员服务提供器)服务,提供身份认证和加密签名等功能。

WorldState 以key-value的形式,维护着当前账本的当前信息。

智能合约(Smart Contract)是区块链的核心,定义了各个不同组织间的业务规范,创建交易并记录在账本里。多个智能合约可以打包到一个链码中。只有链码(Chaincode)部署之后,智能合约才能被应用使用。

不同于一般的链码运行在一个独立的容器,系统链码运行在peer进程上,实现了一些系统行为。

Fabric为了优化网络性能,提高安全性和可扩展性,将每个交易分到 Endorsing Peer Ording-Service Committting Peer 三个部分,这就需要一种安全的,可信的和可扩展的数据传输协议——Gossip Protocol。 Gossip 传输协议以随机的方式将信息散播到网络中,主要执行三个功能:

❻ 区块链节点上线的时候是怎么找到它的peer节点

本人浅见:应该是有个公共地址,大家(包括新加入的)访问这个地址,即可获取所有节点的地址信息。类似的,迅雷下载,bt下载等 p2p 传输,也离不开一个公共地址来存放所有节点的地址信息。

❼ 区块链 --- 共识算法

PoW算法是一种防止分布式服务资源被滥用、拒绝服务攻击的机制。它要求节点进行适量消耗时间和资源的复杂运算,并且其运算结果能被其他节点快速验算,以耗用时间、能源做担保,以确保服务与资源被真正的需求所使用。

PoW算法中最基本的技术原理是使用哈希算法。假设求哈希值Hash(r),若原始数据为r(raw),则运算结果为R(Result)。

R = Hash(r)

哈希函数Hash()的特性是,对于任意输入值r,得出结果R,并且无法从R反推回r。当输入的原始数据r变动1比特时,其结果R值完全改变。在比特币的PoW算法中,引入算法难度d和随机值n,得到以下公式:

Rd = Hash(r+n)

该公式要求在填入随机值n的情况下,计算结果Rd的前d字节必须为0。由于哈希函数结果的未知性,每个矿工都要做大量运算之后,才能得出正确结果,而算出结果广播给全网之后,其他节点只需要进行一次哈希运算即可校验。PoW算法就是采用这种方式让计算消耗资源,而校验仅需一次。

 

PoS算法要求节点验证者必须质押一定的资金才有挖矿打包资格,并且区域链系统在选定打包节点时使用随机的方式,当节点质押的资金越多时,其被选定打包区块的概率越大。

POS模式下,每个币每天产生1币龄,比如你持有100个币,总共持有了30天,那么,此时你的币龄就为3000。这个时候,如果你验证了一个POS区块,你的币龄就会被清空为0,同时从区块中获得相对应的数字货币利息。

节点通过PoS算法出块的过程如下:普通的节点要成为出块节点,首先要进行资产的质押,当轮到自己出块时,打包区块,然后向全网广播,其他验证节点将会校验区块的合法性。

 

DPoS算法和PoS算法相似,也采用股份和权益质押。

但不同的是,DPoS算法采用委托质押的方式,类似于用全民选举代表的方式选出N个超级节点记账出块。

选民把自己的选票投给某个节点,如果某个节点当选记账节点,那么该记账节点往往在获取出块奖励后,可以采用任意方式来回报自己的选民。

这N个记账节点将轮流出块,并且节点之间相互监督,如果其作恶,那么会被扣除质押金。

通过信任少量的诚信节点,可以去除区块签名过程中不必要的步骤,提高了交易的速度。
 

拜占庭问题:

拜占庭是古代东罗马帝国的首都,为了防御在每块封地都驻扎一支由单个将军带领的军队,将军之间只能靠信差传递消息。在战争时,所有将军必须达成共识,决定是否共同开战。

但是,在军队内可能有叛徒,这些人将影响将军们达成共识。拜占庭将军问题是指在已知有将军是叛徒的情况下,剩余的将军如何达成一致决策的问题。

BFT:

BFT即拜占庭容错,拜占庭容错技术是一类分布式计算领域的容错技术。拜占庭假设是对现实世界的模型化,由于硬件错误、网络拥塞或中断以及遭到恶意攻击等原因,计算机和网络可能出现不可预料的行为。拜占庭容错技术被设计用来处理这些异常行为,并满足所要解决的问题的规范要求。

拜占庭容错系统

发生故障的节点被称为 拜占庭节点 ,而正常的节点即为 非拜占庭节点

假设分布式系统拥有n台节点,并假设整个系统拜占庭节点不超过m台(n ≥ 3m + 1),拜占庭容错系统需要满足如下两个条件:

另外,拜占庭容错系统需要达成如下两个指标:

PBFT即实用拜占庭容错算法,解决了原始拜占庭容错算法效率不高的问题,算法的时间复杂度是O(n^2),使得在实际系统应用中可以解决拜占庭容错问题
 

PBFT是一种状态机副本复制算法,所有的副本在一个视图(view)轮换的过程中操作,主节点通过视图编号以及节点数集合来确定,即:主节点 p = v mod |R|。v:视图编号,|R|节点个数,p:主节点编号。

PBFT算法的共识过程如下:客户端(Client)发起消息请求(request),并广播转发至每一个副本节点(Replica),由其中一个主节点(Leader)发起提案消息pre-prepare,并广播。其他节点获取原始消息,在校验完成后发送prepare消息。每个节点收到2f+1个prepare消息,即认为已经准备完毕,并发送commit消息。当节点收到2f+1个commit消息,客户端收到f+1个相同的reply消息时,说明客户端发起的请求已经达成全网共识。

具体流程如下

客户端c向主节点p发送<REQUEST, o, t, c>请求。o: 请求的具体操作,t: 请求时客户端追加的时间戳,c:客户端标识。REQUEST: 包含消息内容m,以及消息摘要d(m)。客户端对请求进行签名。

主节点收到客户端的请求,需要进行以下交验:

a. 客户端请求消息签名是否正确。

非法请求丢弃。正确请求,分配一个编号n,编号n主要用于对客户端的请求进行排序。然后广播一条<<PRE-PREPARE, v, n, d>, m>消息给其他副本节点。v:视图编号,d客户端消息摘要,m消息内容。<PRE-PREPARE, v, n, d>进行主节点签名。n是要在某一个范围区间内的[h, H],具体原因参见 垃圾回收 章节。

副本节点i收到主节点的PRE-PREPARE消息,需要进行以下交验:

a. 主节点PRE-PREPARE消息签名是否正确。

b. 当前副本节点是否已经收到了一条在同一v下并且编号也是n,但是签名不同的PRE-PREPARE信息。

c. d与m的摘要是否一致。

d. n是否在区间[h, H]内。

非法请求丢弃。正确请求,副本节点i向其他节点包括主节点发送一条<PREPARE, v, n, d, i>消息, v, n, d, m与上述PRE-PREPARE消息内容相同,i是当前副本节点编号。<PREPARE, v, n, d, i>进行副本节点i的签名。记录PRE-PREPARE和PREPARE消息到log中,用于View Change过程中恢复未完成的请求操作。

主节点和副本节点收到PREPARE消息,需要进行以下交验:

a. 副本节点PREPARE消息签名是否正确。

b. 当前副本节点是否已经收到了同一视图v下的n。

c. n是否在区间[h, H]内。

d. d是否和当前已收到PRE-PPREPARE中的d相同

非法请求丢弃。如果副本节点i收到了2f+1个验证通过的PREPARE消息,则向其他节点包括主节点发送一条<COMMIT, v, n, d, i>消息,v, n, d, i与上述PREPARE消息内容相同。<COMMIT, v, n, d, i>进行副本节点i的签名。记录COMMIT消息到日志中,用于View Change过程中恢复未完成的请求操作。记录其他副本节点发送的PREPARE消息到log中。

主节点和副本节点收到COMMIT消息,需要进行以下交验:

a. 副本节点COMMIT消息签名是否正确。

b. 当前副本节点是否已经收到了同一视图v下的n。

c. d与m的摘要是否一致。

d. n是否在区间[h, H]内。

非法请求丢弃。如果副本节点i收到了2f+1个验证通过的COMMIT消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求操作o,并返回<REPLY, v, t, c, i, r>给客户端,r:是请求操作结果,客户端如果收到f+1个相同的REPLY消息,说明客户端发起的请求已经达成全网共识,否则客户端需要判断是否重新发送请求给主节点。记录其他副本节点发送的COMMIT消息到log中。
 

如果主节点作恶,它可能会给不同的请求编上相同的序号,或者不去分配序号,或者让相邻的序号不连续。备份节点应当有职责来主动检查这些序号的合法性。

如果主节点掉线或者作恶不广播客户端的请求,客户端设置超时机制,超时的话,向所有副本节点广播请求消息。副本节点检测出主节点作恶或者下线,发起View Change协议。

View Change协议

副本节点向其他节点广播<VIEW-CHANGE, v+1, n, C , P , i>消息。n是最新的stable checkpoint的编号, C 2f+1验证过的CheckPoint消息集合, P 是当前副本节点未完成的请求的PRE-PREPARE和PREPARE消息集合。

当主节点p = v + 1 mod |R|收到 2f 个有效的VIEW-CHANGE消息后,向其他节点广播<NEW-VIEW, v+1, V , O >消息。 V 是有效的VIEW-CHANGE消息集合。 O 是主节点重新发起的未经完成的PRE-PREPARE消息集合。PRE-PREPARE消息集合的选取规则:

副本节点收到主节点的NEW-VIEW消息,验证有效性,有效的话,进入v+1状态,并且开始 O 中的PRE-PREPARE消息处理流程。
 

在上述算法流程中,为了确保在View Change的过程中,能够恢复先前的请求,每一个副本节点都记录一些消息到本地的log中,当执行请求后副本节点需要把之前该请求的记录消息清除掉。

最简单的做法是在Reply消息后,再执行一次当前状态的共识同步,这样做的成本比较高,因此可以在执行完多条请求K(例如:100条)后执行一次状态同步。这个状态同步消息就是CheckPoint消息。

副本节点i发送<CheckPoint, n, d, i>给其他节点,n是当前节点所保留的最后一个视图请求编号,d是对当前状态的一个摘要,该CheckPoint消息记录到log中。如果副本节点i收到了2f+1个验证过的CheckPoint消息,则清除先前日志中的消息,并以n作为当前一个stable checkpoint。

这是理想情况,实际上当副本节点i向其他节点发出CheckPoint消息后,其他节点还没有完成K条请求,所以不会立即对i的请求作出响应,它还会按照自己的节奏,向前行进,但此时发出的CheckPoint并未形成stable。

为了防止i的处理请求过快,设置一个上文提到的 高低水位区间[h, H] 来解决这个问题。低水位h等于上一个stable checkpoint的编号,高水位H = h + L,其中L是我们指定的数值,等于checkpoint周期处理请求数K的整数倍,可以设置为L = 2K。当副本节点i处理请求超过高水位H时,此时就会停止脚步,等待stable checkpoint发生变化,再继续前进。
 

在区块链场景中,一般适合于对强一致性有要求的私有链和联盟链场景。例如,在IBM主导的区块链超级账本项目中,PBFT是一个可选的共识协议。在Hyperledger的Fabric项目中,共识模块被设计成可插拔的模块,支持像PBFT、Raft等共识算法。
 

 

Raft基于领导者驱动的共识模型,其中将选举一位杰出的领导者(Leader),而该Leader将完全负责管理集群,Leader负责管理Raft集群的所有节点之间的复制日志。
 

下图中,将在启动过程中选择集群的Leader(S1),并为来自客户端的所有命令/请求提供服务。 Raft集群中的所有节点都维护一个分布式日志(复制日志)以存储和提交由客户端发出的命令(日志条目)。 Leader接受来自客户端的日志条目,并在Raft集群中的所有关注者(S2,S3,S4,S5)之间复制它们。

在Raft集群中,需要满足最少数量的节点才能提供预期的级别共识保证, 这也称为法定人数。 在Raft集群中执行操作所需的最少投票数为 (N / 2 +1) ,其中N是组中成员总数,即 投票至少超过一半 ,这也就是为什么集群节点通常为奇数的原因。 因此,在上面的示例中,我们至少需要3个节点才能具有共识保证。

如果法定仲裁节点由于任何原因不可用,也就是投票没有超过半数,则此次协商没有达成一致,并且无法提交新日志。

 

数据存储:Tidb/TiKV

日志:阿里巴巴的 DLedger

服务发现:Consul& etcd

集群调度:HashiCorp Nomad
 

只能容纳故障节点(CFT),不容纳作恶节点

顺序投票,只能串行apply,因此高并发场景下性能差
 

Raft通过解决围绕Leader选举的三个主要子问题,管理分布式日志和算法的安全性功能来解决分布式共识问题。

当我们启动一个新的Raft集群或某个领导者不可用时,将通过集群中所有成员节点之间协商来选举一个新的领导者。 因此,在给定的实例中,Raft集群的节点可以处于以下任何状态: 追随者(Follower),候选人(Candidate)或领导者(Leader)。

系统刚开始启动的时候,所有节点都是follower,在一段时间内如果它们没有收到Leader的心跳信号,follower就会转化为Candidate;

如果某个Candidate节点收到大多数节点的票,则这个Candidate就可以转化为Leader,其余的Candidate节点都会回到Follower状态;

一旦一个Leader发现系统中存在一个Leader节点比自己拥有更高的任期(Term),它就会转换为Follower。

Raft使用基于心跳的RPC机制来检测何时开始新的选举。 在正常期间, Leader 会定期向所有可用的 Follower 发送心跳消息(实际中可能把日志和心跳一起发过去)。 因此,其他节点以 Follower 状态启动,只要它从当前 Leader 那里收到周期性的心跳,就一直保持在 Follower 状态。

Follower 达到其超时时间时,它将通过以下方式启动选举程序:

根据 Candidate 从集群中其他节点收到的响应,可以得出选举的三个结果。

共识算法的实现一般是基于复制状态机(Replicated state machines),何为 复制状态机

简单来说: 相同的初识状态 + 相同的输入 = 相同的结束状态 。不同节点要以相同且确定性的函数来处理输入,而不要引入一下不确定的值,比如本地时间等。使用replicated log是一个很不错的注意,log具有持久化、保序的特点,是大多数分布式系统的基石。

有了Leader之后,客户端所有并发的请求可以在Leader这边形成一个有序的日志(状态)序列,以此来表示这些请求的先后处理顺序。Leader然后将自己的日志序列发送Follower,保持整个系统的全局一致性。注意并不是强一致性,而是 最终一致性

日志由有序编号(log index)的日志条目组成。每个日志条目包含它被创建时的任期号(term),和日志中包含的数据组成,日志包含的数据可以为任何类型,从简单类型到区块链的区块。每个日志条目可以用[ term, index, data]序列对表示,其中term表示任期, index表示索引号,data表示日志数据。

Leader 尝试在集群中的大多数节点上执行复制命令。 如果复制成功,则将命令提交给集群,并将响应发送回客户端。类似两阶段提交(2PC),不过与2PC的区别在于,leader只需要超过一半节点同意(处于工作状态)即可。

leader follower 都可能crash,那么 follower 维护的日志与 leader 相比可能出现以下情况

当出现了leader与follower不一致的情况,leader强制follower复制自己的log, Leader会从后往前试 ,每次AppendEntries失败后尝试前一个日志条目(递减nextIndex值), 直到成功找到每个Follower的日志一致位置点(基于上述的两条保证),然后向后逐条覆盖Followers在该位置之后的条目 。所以丢失的或者多出来的条目可能会持续多个任期。
 

要求候选人的日志至少与其他节点一样最新。如果不是,则跟随者节点将不投票给候选者。

意味着每个提交的条目都必须存在于这些服务器中的至少一个中。如果候选人的日志至少与该多数日志中的其他日志一样最新,则它将保存所有已提交的条目,避免了日志回滚事件的发生。

即任一任期内最多一个leader被选出。这一点非常重要,在一个复制集中任何时刻只能有一个leader。系统中同时有多余一个leader,被称之为脑裂(brain split),这是非常严重的问题,会导致数据的覆盖丢失。在raft中,两点保证了这个属性:

因此, 某一任期内一定只有一个leader
 

当集群中节点的状态发生变化(集群配置发生变化)时,系统容易受到系统故障。 因此,为防止这种情况,Raft使用了一种称为两阶段的方法来更改集群成员身份。 因此,在这种方法中,集群在实现新的成员身份配置之前首先更改为中间状态(称为联合共识)。 联合共识使系统即使在配置之间进行转换时也可用于响应客户端请求,它的主要目的是提升分布式系统的可用性。

❽ (译)超级账本官方文档 基本概念(三) - 节点(Peer)

超级账本是Linux基金会发起的项目,意在提供一套企业级区块链应用框架,便于大家开发基于区块链技术的应用。

Fabric的基本概念

最开始,应用程序会选出一组peer来生成账本更新提议。哪些peer会被选出来是依据的背书策略,这个背书策略决定了哪些组织需要在广播账本更新提议前对更新提议进行背书。这会影响到共识方式,任何一个关心更新提议是否背书的组织都会在广播给peer更新提议并被peer接受前确认提议是否有背书。

peer对一个提议响应进行背书,就是把自己的数字签名加入到响应中,并用自己的私钥对整个响应签名。背书内容随后可以被用于证明这个响应是某个组织的peer生成的。在我们的例子中,如果peer P1属于组织1(Org1),那么背书E1就相当于可以证明L1上的交易T1和响应R1是由Org1的peer P1提供的。

当应用程序得到了足够多的签名的提议响应时,第一阶段就结束了。
我们注意到peer可能返回不同的信息,因此同一笔交易可能有不一致的返回信息。这可能由于响应是在不同时间,不同peer,在不同账本状态下生成的,大多数情况下应用程序可以多次请求更新的提议响应。另外更严重,但概率很小的原因是因为链码的不确定性导致的响应不一致。不确定性是链码和账本的大敌,如果这种情况发生了,对提议交易来说是很严重的,不一致的提议响应肯定不能提交到账本中。一个独立的节点是不可能知道交易结果是非确定性的交易,在检测到非确定性交易前,必须将交易汇总比较(严格地说,即使这还不够,但我们将此讨论推迟到交易部分,其中详细讨论了非确定性)。

在第一阶段结束时,如果应用程序希望如此的话,可以放心丢弃不一致的响应以提前结束交易流程。后面我们会看到如果应用程序使用不一致的响应提交到账本时,会被拒绝。

过程2 打包
第二个交易流程是打包。Orderer节点这个过程关键的点,它接收来自很多应用传来的背书过的提议交易响应。Orderer对交易进行排序,并将大量的交易打包进区块,并准备将区块分发到所有连接到Orderer的peer,包括背书peer。

orderer的第一个角色就是打包账本更新提议。在上图的例子中,应用A1发送给Orderer O1一个被E1和E2背书的交易T1。同时,应用A2发送给Orderer O1一个被E1背书的交易T2。O1将A1传来的交易和A2传来的交易以及其它交易共同打包进区块B2。我们可以看到区块B2里的交易排序是T1,T2,T3,T4,T6,T5,并不一定是按照到达orderer节点的顺序(这个例子展示了一个非常简单的orderer配置)。

Orderer节点会同时收到网络Channel中不同应用程序发送的账本更新提议。Orderer节点的任务就是按照事先定义好的顺序整理这些更新提议,并把它们打包进区块,为下一步的分发做准备。这些区块将构成区块链。一旦Orderer节点生成了期望大小的区块,或者超过最大等待时间,Orderer会向连接到它特定Channel的Peer发送区块。第三个过程会详述这个流程。

区块中的交易排列顺序和交易到达Orderer节点的顺序没有直接关系。交易在区块中可以是任意的排列顺序,这个次序就是交易执行的顺序。重点是有一个严格的交易排序,但具体是怎样的排序并不重要。

区块中的严格交易顺序排列使得Fabric与公链中一笔交易可以被打包进多个不同区块的情况不同。在Fabric中,这不可能发生,由多个Orderer生成的区块就是最终的区块,因为交易被写入区块后,交易的位置顺序就确定了。这意味着Fabric不会存在分叉。一旦交易被写入区块,以后就不能再重写了。

我们可以看到,peer是存储账本和链码的,orderer完全不会存储这些。每一笔交易到达orderer时,orderer只是机械的将交易打包进区块,而不会理会交易的价值,额度等。这是Fabric的一个重要特性,所有交易都会按照一个严格的顺序进行整理,没有交易会被抛弃掉。

到第二阶段结束时,我们可以了解到orderer的责任就是进行必要的,简单的收集交易更新提议,将他们排序,打包进区块,准备分发出去。

过程3 认证
最后一个交易工作流程是分发和验证从orderer到peer的区块,如果验证成功,将会被提交到账本中。
特别的,在每个peer中,在区块中的每一笔交易在更新到账本之前都是验证过的,以保证所有交易都是由相关的组织背书过的。失败的交易会保留,作为日后审查用,并不会更新到账本中。

Orderer除了在过程2中的打包角色外,在过程3中还负责分发区块到peer节点。在这个例子中,O1分发区块到P1和P2。P1处理区块2,然后将区块2添加到P1的账本L1中。同时,P2处理区块2,然后将区块2添加到P2的账本L1中。一旦操作完成,账本L1在P1和P2中都被更新了,每个Peer都可以向连接到他们的应用程序发送处理结果。

Orderer向连接到他的Peer分发区块是过程3的开始。连接到orderer节点的某个渠道的peer,会收到orderer生成的新区块的一份拷贝。每个peer节点都会独立的处理收到的区块,但所有peer处理区块的方式都是相同的。采用这种方式,不同peer中的账本可以达成共识。并不是所有的peer都必须连接到orderer节点,peer和peer之间可以通过gossip协议来传递区块,这样peer也可以独立的处理相同区块。

收到一个区块后,peer会按照交易在区块中出现的顺序依次处理。对于每一笔交易,peer会按照生成这笔交易的链码背书策略检查交易是否被与之相关组织的背书。例如,某些交易可能只需要一个组织背书,而另一些交易需要多个组织同时背书才有效。这个验证过程验证了所有相关组织产生的结果或者输出是否一致。同时请注意,第三阶段的验证和第一阶段不同,阶段一只是应用程序收到背书节点的响应,判断是否需要发送交易提议。如果应用程序发送错误的交易,违反了背书策略,在第三阶段的验证过程中peer还是可以拒绝本次交易。

如果交易背书正确,peer将尝试把交易提交到账本中。为了能写账本,peer必须进行账本一致性检查,保证当前账本的状态与账本更新后的状态一致。这个状态并不总会是一致的,即使交易拥有完整的背书。举个栗子,另外一笔交易可能已经更新了账本中的同一个资产,以至于我们正要更新的交易将永远不会被写入账本。这样的话,每个节点中的账本必须通过网络保持共识,每个节点的验证方式是一样的。

在peer验证完每笔独立交易后,将更新账本。失败的交易会保存下来作为审查资料。这意味着peer中的区块和从orderer中收到的区块一致,除了区块中指示交易成功或失败的标志。

我们也要注意到,第三阶段并没有执行链码,这一步只会在第一阶段完成,这很重要。这意味着链码只在背书节点可用,而不是整个网络中都可用,这保证了链码在背书组织中的安全及私密。这和收到链码的执行结果不同,执行结果会分享到所有在Channel里的peer,不论他是否能背书交易。背书节点的这种设计方式是为了方便扩展。

最后,每次区块被提交到peer的账本中时,这个peer会生成对应的事件。区块事件包含区块的所有内容,而区块交易事件只包含简要信息,比如每笔区块中的交易是否有效。由链码的执行而产生的链码事件也可以在这个时候发布。应用程序可以注册这些事件,当这些事件发生时,可以收到通知。这些通知在交易工作流程的第三阶段和最后阶段完成。

总的来说,我们可以知道第三阶段由orderer产生的区块被不断地同步到账本中。区块中交易的严格排序能让每个peer在区块链网络中始终如一地验证交易并提交到账本中。

Orderer和共识
整个交易工作流程被称为共识,因为所有peer都认同交易的排序和内容,在执行过程中由orderer节点来协调。共识是多步骤的过程,应用程序只会在共识过程结束时收到通知,但通知的时间在不同的peer上可能不同。

我们将会在后面更多的探讨orderer,现在,把orderer仅仅当做从应用程序收集、分发账本更新提议到peer,由peer进行验证及更新账本的过程。

❾ 浅析 Fabric Peer 节点

Hyperledger Fabric,也称之为超级账本,是由 IBM 发起,后成为 Linux 基金会 Hyperledger 中的区块链项目之一。

Fabric 是一个提供分布式账本解决方案的平台,底层的账本数据存储使用了区块链。区块链平台通常可以分为公有链、联盟链和私有链。公有链典型的代表是比特币这些公开的区块链网络,谁都可以加入到这个网络中。联盟链则有准入机制,无法随意加入到网络中,联盟链的典型例子就是 Fabric。

Fabric 不需要发币来激励参与方,也不需要挖矿来防止有人作恶,所以 Fabric 有着更好的性能。在Fabric 网络中,也有着诸多不同类型的节点来组成网络。其中 Peer 节点承载着账本和智能合约,是整个区块链网络的基础。在这篇文章中,会详细分析 Peer 的结构及其运行方式。

在本文中,假设读者已经了解区块链、智能合约等概念。

本文基于 Fabric1.4 LTS。

区块链网络是一个分布式的网络,Fabric 也是如此,由于 Fabric 是联盟链,需要准入机制,所以在网络结构上会复杂很多,下面是一个简化的 Fabric 网络:

各个元素的含义如下:

对于 Fabric 网络,外部的用户需要通过客户端应用,也就是图中的 A1、A2 或者 A3 来访问网络,客户端应用需要通过 CA 证书表明自己的身份,这样才能访问到 Fabric 网络中有权限访问的部分。

在上面的网络中,共有四个组织,R1、R2、R3 和 R4。其中 R4 是整个 Fabric 网络的创建者,网络是根据 NC4 配置的。

在 Fabric 网络中,不同的组织可以组成联盟,不同的联盟之间数据通过 Channel 来隔离。Channel 中的数据只有该联盟中的组织才能访问,每一个新的 Channel 都可以认为是一条新的链。与其他的区块链网络中通常只有一条链不一样,Fabric 可以通过 Channel 在网络中快速的搭建出一个新的区块链。

上面 R1 和 R2 组成了一个联盟,在 C1 上交易。R2 同时又和 R3 组成了另外一个联盟,在 C2 上交易。R1 和 R2 在 C1 上交易时,对 R3 是不可见的,R2 和 R3 在 C2 上交易时,对 R1 是不可见的。Channel 机制提供了很好的隐私保护能力。

Orderer 节点是整个 Fabric 网络共有的,用来为所有的交易排序、打包。比如上面网络中 O4 节点。本文不会对 Orderer 节点进行详细说明,可以把这个功能理解为比特币网络中的挖矿过程。

Peer 节点表示网络中的节点,通常一个 Peer 就表示一个组织,Peer 是整个区块链网络的基础,是智能合约和账本的载体,Peer 也是本文讨论的重点。

一个 Peer 节点可以承载多套账本和智能合约,比如 P2 节点,既维护了 C1 的账本和智能合约,也维护了 C2 的账本和智能合约。

为了可以更深入了解 Peer 节点的作用,先了解一下 Fabric 整体的交易流程。整体的交易流程图如下:

Peer 节点按照功能来分可以分为 背书节点 记账节点

客户端会提交交易请求到背书节点,背书节点开始模拟执行交易,在模拟执行之后,背书节点并不会去更新账本数据,而是把这个交易进行加密和签名,然后返回给客户端。

客户端收到这个响应之后就会把响应提交到 Orderer 节点,Orderer 节点会对这些交易进行排序,并打包成区块,然后分发到记账节点,记账节点就会对交易进行验证,验证结束之后,就会把交易记录到账本里面。

一笔交易是否能成功是根据背书策略来指定的,每一个智能合约都会指定一个背书策略。

Peer 节点代表着联盟链中的各个组织,区块链网络也是由 Peer 节点来组成的,而且也是账本和智能合约的载体。

通过对上面交易过程的了解可以知道,Peer 节点是主要的参与方。如果用户想要访问账本资源,都必须要和 peer 节点进行交互。在一个 Peer 节点中,可以同时维护多个账本,这些账本属于不同的 Channel 。每个 Peer 节点都会维护一套冗余账本,这样就避免了单点故障。

Peer 节点根据在交易中的不同角色,可以分成背书节点(Endorser)和记账节点(Committer),背书节点会对交易进行模拟执行,记账节点才会真正将数据存储到账本中。

账本可以分成两个部分,一部分是区块链,另一部分是 Current State,也被称之为 World State。

区块链上只能追加,不能对过去的数据进行修改,链上也包含两部分信息,一部分是通道的配置信息,另一部分是不可修改,序列化的记录。每一个区块记录前一个区块的信息,然后连成链,如下图所示:

第一个区块被称之为 genesis block,其中不存储交易信息。每个区块可以被分为 区块头 区块数据 区块元数据 。区块头中存储着当前区块的区块号、当前区块的 hash 值和上一个区块的 hash 值,这样才能把所有的区块连接起来。区块数据中包含了交易数据。区块元数据中则包括了区块写入的时间、写入人及签名。

其中每一笔交易的结构如下,在 Header 中,包含了 ChainCode 的名称、版本信息。Signature 就是交易发起用户的签名。Proposal 中主要是一些参数。Response 中是智能合约执行的结果。Endorsements 中是背书结果返回的结果。

WorldState中维护了账本的当前状态,数据以 Key-Value 的形式存储,可以快速查询和修改,每一次对 WorldState 的修改都会被记录到区块链中。WorldState 中的数据需要依赖外部的存储,通常使用 LevelDB 或者 CouchDB。

区块链和 WorldState 组成了一个完整的账本,World State 保证的业务数据的灵活变化,而区块链则保证了所有的修改是可追溯和不可篡改的。

在交易完成之后,数据已经写入账本,就需要将这些数据同步到其他的 Peer,Fabric 中使用的是 Gossip 协议。Gossip 也是 Channel 隔离的,只会在 Channel 中的 Peer 中广播和同步账本数据。

智能合约需要安装到 Peer 节点上,智能合约是访问账本的唯一方式。智能合约可以通过 Go、Java 等变成语言进行编写。

智能合约编写完成之后,需要打包到 ChainCode 中,每个 ChainCode 中可以包含多个智能合约。ChainCode 需要安装,ChainCode 需要安装到 Peer 节点上。安装好了之后,ChainCode 需要在 Channel 上实例化,实例化的时候需要指定背书策略。

智能合约在实例化之后就可以用来与账本进行交互了,流程图如下:

用户编写并部署实例化智能合约之后,就可以通过客户端应用程序来向智能合约提交请求,智能合约会对 WorldState 中数据进行 get、put 或者 delete。其中 get 操作直接从 WorldState 中读取交易对象当前的状态信息,不会去区块链上写入信息,但 put 和 delete 操作除了修改 WorldState,还会去区块链中写入一条交易信息,且交易信息不能修改。

区块链上的信息可以通过智能合约访问,也可以在客户端应用通过 API 直接访问。

Event 是客户端应用和 Fabric 网络交互的一种方式,客户端应用可以订阅 Event,当 Event 发生时,客户端应用就会接受到消息。

事件源可以两类,一类是智能合约发出的 Event,另一类是账本变更触发的 Event。用户可以从 Event 中获取到交易的信息,比如区块高度等信息。

在这篇文章中,首先介绍了 Fabric 整体的网络架构,通过对 Fabric 交易流程的分析,讨论了 peer 节点在交易中的作用,然后详细分析了 peer 节点所维护的账本和智能合约,并分析了 peer 节点维护账本以及 peer 节点执行智能合约的流程。

文 / Rayjun

[1] https://hyperledger-fabric.readthedocs.io/zh_CN/release-1.4/whatis.html

[2] https://developer.ibm.com/zh/technologies/blockchain/series/os-academy-hyperledger-fabric/

[3] https://en.wikipedia.org/wiki/Gossip_protocol

❿ 区块链中点对点分布式技术是指什么

“一种基于网络的计算机处理技术,与集中式相对应。由于个人计算机的性能得到极大的提高及其使用的普及,使处理能力分布到网络上的所有计算机成为可能。分布式计算是和集中式计算相对立的概念,分布式计算的数据可以分布在很大区域。”

热点内容
区块链技术法律监督探究本科论文 发布:2025-02-23 20:47:24 浏览:633
win764位不能挖矿 发布:2025-02-23 20:20:20 浏览:754
利用trx拉伸 发布:2025-02-23 20:16:09 浏览:417
黑石区块链官网 发布:2025-02-23 20:10:19 浏览:767
btc资管 发布:2025-02-23 20:07:01 浏览:217
我要看小格挖矿游戏解说 发布:2025-02-23 20:00:30 浏览:126
我的世界链锁挖矿mod怎么添加空手 发布:2025-02-23 19:44:40 浏览:51
比特币地址怎么申请 发布:2025-02-23 19:44:33 浏览:11
区块链技术大咖 发布:2025-02-23 19:44:25 浏览:908
在币圈投资的最佳方法 发布:2025-02-23 19:39:20 浏览:288