主页 > imtoken钱包官方下载最新版 > 区块链安全——详谈共识攻击(四)

区块链安全——详谈共识攻击(四)

以太坊共识算法_以太坊共识机制_以太坊通缩机制

图片.png

一、简介

在上一篇文章中,我们描述了许多区块链在过去几年中发展和演变的共识机制。 在前面的内容中,我们描述的共识大多属于区块链1.o和2.0的知识。 本次重点介绍区块链3.0时代HyperLedger Fabric中的共识机制及相关特性。 如今,比特币和以太坊在币圈应用中居多。 但是根据目前业界发现的情况来看,Hyperledger未来的发展更倾向于商业落地项目,所以对此类机制的深入研究对我们后续的发展大有裨益。 益处。

Fabric 是 Hyperledger 项目组的一个项目。 从区块链的演进来看,Fabric属于区块链3.0的技术范畴。 但是它具有区块链1.0和2.0系统的特点,比如可以共享账本,有智能合约,可以通过共识算法保证数据安全。 但是,作为典型的区块链3.0技术平台,Fabric拥有与其他区块链不同的技术,以确保其更适合项目的落地。

2. Fabric共识机制

Fabric 中不同成员发起的交易按照一定的顺序写入区块链,区块链连接起来形成区块链。 在交易排序过程中需要防止恶意篡改。 仅针对比特币,它采用 Pow 并解决了这个问题。 对于Fabric,它支持Solo(单节点共识)、Kafka(分布式队列)和SBFT(简单拜占庭容错)。 前两个已经应用到Fabric上,第三个会在以后实际应用。

在Fabric中,共识过程是指多个Peer节点对某一批交易的顺序、合法性、账本状态的更新达成共识。

要真正了解 Fabric 共识如何协同工作,我们需要了解各种组件。 在 Fabric 中以太坊共识机制,通过背书、排序和验证三个环节来保证共识。

背书过程:背书节点根据自己的逻辑对收到的客户端请求(交易提议)进行校验,决定是否支持。

对于调用某个chaincode的交易,需要获得一定条件的背书才被认为是合法的。 例如,必须是某些特定身份成员的一致同意; 或组织中超过一定数量成员的支持; 这些背书策略可以在实例化之前由链码指定。

排序过程:一段时间内一批交易在网络中达成全局一致的排序。

Fabric中采用可插拔架构,solo模式,CFT类型后端包括Kafka,BFT类型后端。

验证过程:在将有序的一批交易提交到账本之前对其进行最终检查的过程。

验证过程包括验证交易结构本身的完整性、背书签名是否满足背书策略、交易的读写集是否满足多版本并发控制等。

其中最重要的是订购服务。 Fabric 中的所有交易在交付给 Committer 进行验证和验收之前,都需要通过排序服务进行全局排序。 排序服务提供原子广播排序。 只有排序后,每笔交易都有其先后顺序,任务才能合理执行。

1 独奏模式

Solo 方法是指在单个节点中完成的排序算法。 这种模式的安全性和稳定性都比较差。 如果单点出现问题,整个区块链系统将无法正常运行。 所以Solo用于演示系统和原生开发。

Solo机制是一种非常容易部署在非生产环境中的共识排序节点。 它只有一个客户端-服务器单节点,因此不需要“共识”。 因为它有一个中央权威,所以它不具有高可用性或相应的可扩展性。 order-solo模式是一种单节点通信模式,所有从peer接收到的消息都在本节点上进行排序并生成数据块。

2 卡夫卡模式

Kafka 是一个高吞吐量的分布式发布-订阅消息系统。 在Fabric的Kafka模式中,排序节点从Kafka集群中获取对应的topic数据,保证事务的顺序。 借助Kafka的特性,排序节点也可以集群化,可以有效避免单点故障导致整个网络崩溃。 具体来说,它是一个支持多通道分区的集群定时服务。 它可以容忍一些节点故障(崩溃),但不能容忍恶意节点。 基于zookeeper进行Paxos算法选举,支持2f+1个节点集群。 f代表失效节点数。 即Kafka可以容忍不到一半的共识节点失效。

具体过程分为以下两步。 ① 任务下发后,节点向背书节点发送背书请求。 节点在验证身份、签名和读写集后,将其标记为正确信息。 背书节点会提前执行相关任务,包括验证任务是否合法,模拟任务执行结果等,然后我们进入第二步。 ② 之后,任务会被发送到orderer节点,但是在单节点solo中,只有一个orderer,所以不涉及集群的协同排序。 而Kafka涉及多个orderer节点以太坊共识机制,因此其核心功能是将全局的tx(背书请求后)作为输入,在集群中形成统一的、唯一的、确定性的、有序的tx输出。

以太坊共识算法_以太坊共识机制_以太坊通缩机制

图片.png

具体内容可参考Kafka共识机制分析

3. Fabric 技术细节 1 Ledger 特点

以太坊通缩机制_以太坊共识算法_以太坊共识机制

在 Fabric 诞生之前,区块链平台只有一个账本,所有的记录都在一个账本里。 这样做有很多缺点,比如会导致账本存储量巨大,比如现在的比特币账本已经有160G了。 久而久之,这种设计就很成问题了。 在 Fabric 中,我们有私有链、联盟链和公有链。 对于公链,其劣势与比特币体系一致,但对于其他链模型,Fabric采用多账本设计模型。

Fabric 中有通道的概念。 一个通道包含多个成员,他们共享同一个账本,共享账本数据并维护账本。 对于不同的通道,账本的数据格式是不同的。 在Fabric中,账本的存储方式被设计成插件的方式,不同的成员可以根据情况选择不同的存储方式。

它具有以下特点:

2 Fabric 智能合约

Fabric中的智能合约称为Chaincode,Chaincode是用计算机语言编写的程序。 它运行在容器中,Fabric通过调用链码读取和修改账本的数据,并将交易日志保存在状态数据库中。 可以使用Go、java、node.js开发。

下面向读者展示用GO语言编写的链码。

GO的包的引入
package main
import (
//"bytes"
"encoding/json"
"fmt"
"strconv"
//"strings"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"time"
)
 
这些是经常用的包

以太坊通缩机制_以太坊共识机制_以太坊共识算法

Main main是入口 // SimpleChaincode example simple Chaincode implementation type SimpleChaincode struct { } // =================================================================================== // Main // =================================================================================== func main() { err := shim.Start(new(SimpleChaincode)) if err != nil { fmt.Printf("Error starting Simple chaincode: %s", err) } } Init chaincode 包含一个Init和一个Invoke函数。

以太坊共识算法_以太坊通缩机制_以太坊共识机制

Init是初始化的地方,还需要注意以后版本升级时能够通用 // Init initializes chaincode // =========================== func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { return shim.Success(nil) } Invoke 所有的调用都进入到这里,然后分发出去。 // Invoke - Our entry point // ======================================== func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { function, args := stub.GetFunctionAndParameters() fmt.Println("invoke is running " + function) // Handle different functions if function == "initProvider" { // create Provider return t.initProvider(stub, args) } else if function == "initBeneficiary" { // create beneficiary return t.initBeneficiary(stub, args)

以太坊共识机制_以太坊共识算法_以太坊通缩机制

} fmt.Println("invoke did not find func: " + function) //error return shim.Error("Received unknown function ") }

在链码中,我们首先需要init函数进行初始化,然后我们可以调用invoke函数来查询或插入数据。

3 Fabric权限系统

在Fabric系统中,我们需要知道它是通过什么机制来保证安全的。 我们知道Fabric是有多通道机制的,那么它的安全性应该怎么保证呢? 对此,我们这里就说一下它的权限系统。

Fabric 与其他区块链最大的区别在于它的网络是不公开的。 如果要进入网络,则必须获得授权。 因此,Fabric 是联盟链的唯一代表。 而且我们知道比特币和以太坊没有身份验证系统,任何人都可以在任何时间任何地点连接到网络。 连接后,可以按照 Pow 机制与其他人竞争记账权。

但是Fabric中没有类似Pow的机制,所以会员要想加入网络就必须获得合法的授权,否则无论你有多少算力都无法进入网络。 为了解决会员授权的问题,Fabric中有一个会员服务系统MSP。 MSP是基于PKI规范的用户证书和私钥系统。 MSP是Fabric中非常重要的内容,包含了Fabric的账户体系,并据此生成相应的私钥签名,以保证其能够顺利获得联盟的认证,成功接收到区块链中相应的交易信息。

4. Casper 共识

Casper是以太坊提出的下一代共识机制。 原则上,Casper 属于 POS。 Casper 的共识是通过区块达成的,而不是像 POS 那样通过链来达成。

Casper的核心是一个基于存款的经济激励共识协议。 在正常参与系统的过程中,协议中的节点需要成为“锁定保证金的验证者”。 他们必须先支付保证金(这一步称为锁定保证金,“绑定”),然后才能参与区块生成和共识形成。

保证金在这里起着巨大的作用。 协议中的节点将通过对这些存款的控制来直接约束参与验证者的行为。 简单来说,如果一个验证者做了任何 Casper 认为“无效”的事情,他的保证金将被罚款,出块和参与共识的权利也将被取消。 这对节点来说是非常昂贵的。 在经典的Pos协议中,做坏事的成本是很低的,但是保证金的引入很好的解决了“nothing at stake”的问题。 既然有了代价,那些干坏事的节点就会为自己的行为付出相应的代价。

在Casper共识中,不得不提到:Gambling on Consensus的概念。

Casper共识要求参与验证的验证者用大部分押金押注共识结果。 通过验证者的投注情况形成共识结果。 与游戏行为类似,验证者需要猜测其他人会在哪个区块上下注获胜,并在这个区块上下注。 如果赌对了,他们会拿回保证金加上交易费,也许还有一些新铸造的货币作为好处。 如果投注结果没有很快通过,他们也可以取回部分押金。

为了防止验证者在不同的世界提供不同的赌注,还有一个简单而严格的条款:如果你有两个相同序列号的赌注,或者如果你提交了一个无法被 Casper 合约处理的赌注,你将损失所有存款。 这种惩罚机制总是警告节点。

经过上述过程,整个合约就到了最后一步:交易的最终确认。

当绝大多数锁定押金的验证者(满足协议定义的阈值的一组验证者:押金比例达到67%~90%之间的某个百分比)押注某笔资金时,其他人不可能forked blocks to win,也就是说这个区块终于被确认了。

此时,所有客户端都会收到高度为H的区块最终确认的消息。 那么如果用户收到一个高度小于H的分叉,并且依次执行这些完整的区块得到的状态是不同的,此时节点就不能对它采取信任的态度。

五、时间戳依赖详解

简单解释一下时间戳的概念:

以太坊共识机制_以太坊通缩机制_以太坊共识算法

时间戳通常是一串字符,可以唯一标识某个时刻,可以表示一段数据在某个时间之前是否存在,是否完整,是否可验证。

物品数据时间戳常用来调用随机函数,根据时间戳锁定资金一段时间,根据时间的各种变化做条件语句。

根据以太坊的规定,当矿工处理一个新区块时,如果新区块的时间戳大于前一个区块的时间戳,并且时间戳之间的差值小于900秒,则新区块的时间戳为合法的。 时间戳依赖,顾名思义,就是智能合约的执行依赖于当前区块的时间戳。 时间戳不同,合约的执行结果也不同。

矿工可以篡改区块的时间,通过设置区块的时间戳来尽可能满足对自己有利的条件,并从中获利。 例如:

function play() public {
    require(now > 999999 && neverPlayed == true);
    //规定了时间要>999999,所以这里需要进行篡改处理。
    neverPlayed = false;
    msg.sender.transfer(999 ether);
    }

下面我们可以举出相关的例子进行讨论:

如果有一个彩票合约,它的规则规定要根据当前时间戳和一些变量来计算一个“幸运数字”。 奖励规则是,如果这个号码与官方号码相同,就可以获得奖品。 那么矿工们可以在挖矿过程中提前尝试不同的时间戳,计算出这个“幸运数字”,从而把奖品送给他们想要的中奖者。

以太坊共识算法_以太坊共识机制_以太坊通缩机制

图片.png

对于它的检测方法:我们可以为timestamp变量设置一个特殊的符号来检测是否存在依赖于该符号的路径。 时间通常用于条件判断或随机数生成,编程时使用不可更改的属性代替时间戳(如区块索引)。

6. 贪婪合约漏洞

余额被锁定在合约中,无法分配:以太分配函数依赖的库函数失效。

简单来说,就是指那些永远留在以太坊上的智能合约。 例如,Parity 漏洞就是一种贪心合约。 它将智能合约涉及的商品和加密货币锁定在以太坊中,交易双方均无法获取或取消。

漏洞特征:当合约余额大于0时,不调用CALL函数(或调用了CALL但没有发生Ether交换),DELEGATECALL或SUICIDE。

七、遗嘱合约的漏洞

在那些完成或关闭的智能合约中,虽然它们的代码和全局变量被清除了,但其中一些仍然继续执行。 遗嘱合约和贪婪合约一样,是以太坊的错误造成的,目前还不能被黑客利用。

8. 参考文献

首发于:https://xz.aliyun.com/t/3268