一、整体框架
1、以太坊介绍
以太坊是一个开放的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供以太虚拟机(Ethereum Virtual Machine)来处理去中心化合约应用。
以太虚拟机
以太坊虚拟机(EVM):可以执行复杂算法的编码的,具备图灵完备的基于栈的虚拟机。
以太坊使用场景
支付系统:用于去中心数字货币交易,价值互换
去中心化应用:黄金和股票的数字化应用、金融衍生品应用、数字认证、追踪溯源、游戏等
以太坊特点
智能合约(smart contract):存储在区块链上的程序,由各节点运行,需要运行程序的人支付手续费给节点的矿工或权益人。
代币(tokens):智能合约可以创造代币供分布式应用程序使用。分布式应用程序的代币化让用户、投资者以及管理者的利益一致。代币也可以用来进行首次代币发行。
叔块(uncle block):将因为速度较慢而未及时被收入母链的较短区块链并入,以提升交易量。
账户系统和世界状态:以太坊不采用UTXO,容易支持更复杂的逻辑
状态通道(state channels):原理类似比特币的闪雷网络,可提升交易速度、降低区块链的负担,并提高可扩展性。尚未实现,开发团队包括雷电网络(Raiden Network)和移动性网络(Liquidity Network)。
以太坊缺点
性能有待提升:虽然以太坊相比比特币而言,性能有了大幅提升,比特币目前每秒能处理7笔交易,以太坊目前每秒能够处理大概25笔交易,目前以太坊上还没有出现支持过亿用户的DAPP,一旦出现大规模交易就会造成网络拥堵。
业内其他方案对比
方案 | 数据模型 | 共识算法 | 智能合约 | 性能 |
---|---|---|---|---|
比特币 | 基于交易 | PoW | 基于栈的非图灵完备合约 | 7笔/秒 |
以太坊 | 基于账号 | Pow/ Pos/ PBFT(fisco版本) | EVM(Solidity) | 主链18笔/秒 |
Fabric | 基于账户 | PBFT | ChainCode(Go/Java) | 理论最高1万 |
EOS | 基于账号 | BFT-DPoS | WASM | 理论上百万级,目前主链最高3996 |
2、以太坊核心架构
层级架构
如图所示:以太坊核心架构从上层到底层主要包括:
顶层应用:Solidty智能合约语言、去中心化应用DPP、普通支付交易
API接口服务:提供Http、TCp相关的接口RPC框架服务
分布式账本:包括交易、区块、区块校验工具、回执、状态数据、交易池相关信息。
以太坊虚拟机(EVM):智能合约的核心执行层
共识:金联盟fisco以PBFT为主,以太坊公链为POW算法,以太坊测试网也有POS的共识算法
网络服务:点对点节点发现及链接服务,区块链同步服务
底层服务:数据库(leavelDB等)、密码学(椭圆曲线算法等)、基础算法(MPT/布隆/RLP等)
生命周期架构
如图所示以太坊集群下的生命周期模型,其中主要分为八个阶段。
1、建立链接:在以太坊节点启动或者节点链接数过小或者接受到其他节点链接时,节点需要通过P2P网络机制与其他节点建立链接。P2P网络的建立涉及到基于Kad通信协议的节点发现机制、TCP连接建立以及session模型建立。
2、同步交易/区块:当一个节点启动并与附件节点建立链接之后,会进行区块数据的同步:节点在区块链长度落后全网的时候,会通过全网节点进行同步构建best链。同时区块同步还涉及到主动同步及交易同步。当区块导入成功,成为最长区块链后,会将最新的区块信息在全网进度主动同步,以使保持全网的状态一致;节点收到客户端的交易时,会对最新交易进行相互同步
3、以太坊节点接收client发送的交易:以太坊节点接收来自DAPP应用、支付交易的客户端请求。以太坊通过防双花等基础校验加入到交易池中TxPool,进行交易排队,等待交易被同步或打包出块。
4、区块链打包交易:以太坊节点根据不同共识算法的逻辑打包交易出块,如PBFT根据出块节点算法轮到某个节点出块、PoW根据节点为最长链时打包出块。打包出块中会根据一定是打包算法,将交易池中的N笔交易打包进未确定区块。这里的区块并未加入的区块链中,也不包括交易执行完成的hash信息。未确定区块打包完成,即进行交易执行及共识阶段。
5、交易执行:新区块中的每一笔交易都会交给以太坊虚拟机(EVM)进行交易执行,这个过程涉及到合约账号的EVM交易执行器的初始化、执行、evm堆栈指令运行 以及运行结果汇总。EVM执行过程中会涉及到状态数据的查询及存储、交易回执的产生;在所有交易执行完成后,会对未确定区块设置交易头信息,包括TransactionReceipt、logbloom 、gasUsed 等内容。 ps:交易执行分布在共识流程中的一个阶段中,和共识阶段并行执行,同时交易执行涉及的点比较多,故这里将交易执行及共识阶段做分开处理
6、区块共识阶段:以太坊公链中目前采用POW共识算法,设计到节点的工作量证明(Ethash 共识)。在fisco联盟链中,主要采用PBFT的三阶段共识,主要是Prepare阶段、Sign阶段、Commit阶段。共识消息将通过第一步已经建立的P2P网络进行发送。
7、区块导入阶段:当 待出区块 历经打包完成 以及共识成功后,就会进入导入流程,导入流程主要时将共识完成的区块 落盘,落盘过程中,一方面,将Block 中相关的信息 其中包括 Transaction 列表、TransactionReceipt 列表、LogBloom 列表 、账号状态树 以及对应的查找索引等;另一方面,会处理 链分叉的情况,并构建最长best区块链。
8、客户端查询:在一次区块出块成功后,客户端会对交易结果,最新区块信息,交易回执,合约数据等信息的查询。
与此同时,
这里还设计到几个基础技术:
- RLP:以太坊序列化算法,在通讯 以及 存储 等核心功能中,均需依赖于 rlp 的解码 以及 编码 的功能。
- MPT:是一种经过改良的、融合了Merkle tree和前缀树两种树结构优点的数据结构,以太坊中应用于全局状态树、交易树、收据树。
- LogBloom and Filter:布隆过滤器在以太坊中用于检索交易日志log,方便交易结果的查询以及交易事件通知。
- 账户模型:以太坊账户模型分为普通账户及合约账户,两类账户地址格式一致存储的数据信息不同
- 区块及链模型:以太坊区块数据结构包括区块头(Header)、区块体(交易信息);以太坊区块链数据结构包括区块链头信息(HeaderChain)、创世区块信息(genesisBlock)、以及当前最长区块信息、区块缓存信息。
- 密码学知识:椭圆曲线数字签名算法
- EVM虚拟机:EVM是一种基于栈的虚拟机(区别于基于寄存器的虚拟机),用于编译、执行智能合约,是一种图灵完备的编译器。
3、以太坊源码模块
abi | CNS(合约命名服务)模块代码 | |
eth | 主入口目录,其中main.cpp包含main函数入口 | |
libchannelserver | AMOP(链上链下通信协议)实现目录 | |
libdevcore | 基础通用组件实现目录,如工具类函数、基础数据类型结构定义、IO操作函数、读写锁、内存DB、TrieDB、SHA3实现、RLP编解码实现、Worker模型等等 | |
libdiskencryption | 落盘存储加密实现目录 | |
libethcore | 区块链核心数据结构目录。如ABI、秘钥管理、区块头、预编译、交易结构等等 | |
libethereum | 区块链主框架逻辑目录。如交易池、系统合约、节点管理、块链、块、链参数等等 | |
libevm | 虚拟机主目录。如解释器、JIT等等 | |
libevmcore | OPCODE指令集定义、定价 | |
libp2p | 区块链P2P网络主目录。如握手、网络包编解码、会话管理等等 | |
libpaillier | 同态加密算法目录 | |
libpbftseal | PBFT共识插件实现目录 | |
libraftseal | RAFT共识插件实现目录 | |
libstatistics | 访问频率统计与控制实现目录 | |
libweb3jsonrpc | web3 RPC实现目录 | |
sample | 一键安装与部署 | |
scripts | 与安装相关的脚本 | |
systemproxy | 系统合约实现目录 |
二、基础技术
1、RLP
RLP是Recursive Length Prefix的简写。是以太坊中的序列化方法,以太坊的所有对象都会使用RLP方法序列化为字节数组。RLP 在整个区块链技术体系中,承担着基石的作用,在通讯 以及 存储 等核心功能中,均需依赖于 rlp 的解码 以及 编码 的功能。
RLP几种编码规则:总体可以概括为: 内容 (单字节) , 前缀+内容 (总长<55) , 或 前缀+长度+内容 (总长>55)
- 规则1:(内容)… [0x00, 0x7f] 范围内的 单个字节 , RLP 编码内容就是字节内容本身。
- 规则2:(前缀+内容)…0-55字节长度的字符串,RLP编码是 前缀(0x80+len(字符串))+字符串内容
- 规则3(前缀+长度+内容)… >55字节长度字符串, RLP编码是 前缀(0xb7+len(len(字符串)))+len(字符串)+字符串内容
- 规则4(前缀+内容). . 列表的总长度(列表的总长度指的是它包含的项的数量加它包含的各项的长度之和)是0-55字节,它的RLP编码是 前缀(0xc0+len(列表总))+列表中各元素项的RLP编码 ,前缀取值范围是 [0xc0, 0xf7] 。
- 规则5(前缀+长度+内容)…列表的总长度大于55字节,它的RLP编码是 前缀(0xf7+len(len(列表总)))+len(列表总)+列表中各元素项的RLP编码 ,前缀取值范围是 [0xf8, 0xff] 。
2、MPT
MPT是一种经过改良的、融合了Merkle tree和前缀树两种树结构优点的数据结构,用于以太坊的状态数据的存储。
MPT的节点类型:
- 叶字节点(Leaf): 叶字节点包含两个字段, 第一个字段是剩下的Key的半字节编码,而且半字节编码方法的第二个参数为true, 第二个字段是Value
- 扩展节点(Extention): 扩展节点也包含两个字段, 第一个字段是剩下的Key的可以至少被两个剩下节点共享的部分的半字节编码,第二个字段是n(J,j)
- 分支节点(Branch): 分支节点包含了17个字段,其前16个项目对应于这些点在其遍历中的键的十六个可能的半字节值中的每一个。第17个字段是存储那些在当前结点结束了的节点
MPT在以太坊中的应用:
- 状态树:涉及到以太坊平台账号及合约账号的数据存储。
- 交易树:每一个区块中的每笔交易内容(from,to,gas,data等等)构建的交易树
- 收据树:以太坊中的每一笔交易都有对应的收据,收据树的信息是为了方便一些相关账户的查询。
3、LogBloom and Filter
以太坊的区块头中包含了一个叫做logsBloom的区域。 这个区域存储了当前区块中所有的收据的日志的布隆过滤器,一共是2048个bit。也就是256个字节。
而我们的一个交易的收据包含了很多的日志记录。 每个日志记录包含了 合约的地址, 多个Topic。 而在我们的收据中也存在一个布隆过滤器,这个布隆过滤器记录了所有的日志记录的信息。布隆过滤器在以太坊中可以方便交易结果的查询以及交易事件通知。
布隆过滤器构建过程:
布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k。
以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3(这里元素个数和哈希函数的数量没有直接关系)。
1、将位数组进行初始化,将里面每个位都设置位0。
2、对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。
3、查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。
注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。
4、账户模型
以太坊账户模型分为普通账户及合约账户:
- 外部账户地址:普通用户拥有的公私钥配对的账户,也就是我们常用的存储自己代币的账户地址。
- 合约账户地址:合约账户地址指智能合约的账户地址。
在以太坊账户中,我们维护以下几个状态:
- nonce:外部账户为交易次数,合约账户为创建的合约序号。
- balance:此地址的以太币余额。
- storageRoot:账户存储内容组成的默克尔树根的哈希值。
- codeHash:账户EVM代码的hash值。合约账户即为合约代码的哈希值,外部账户为空字符串的哈希值
5、区块及链模型
区块及链模型主要包括区块(block)及区块链(blockchain)。
区块(block)是Ethereum的核心数据结构之一。所有账户的相关活动,以交易(Transaction)的格式存储,每个Block有一个交易对象的列表;每个交易的执行结果,由一个Receipt对象与其包含的一组Log对象记录;所有交易执行完后生成的Receipt列表,存储在Block中(经过压缩加密)。不同Block之间,通过前向指针ParentHash一个一个串联起来成为一个单向链表。
区块链(blockchain)管理整个区块单向链表,在一个Ethereum客户端软件(比如钱包)中,只会有一个BlockChain对象存在。同Block/Header的关系类似,BlockChain还有一个成员变量类型是HeaderChain, 用来管理所有Header组成的单向链表。当然,HeaderChain在全局范围内也仅有一个对象,并被BlockChain持有。
6、椭圆曲线数字签名算法
以太坊中的数字签名全部采用椭圆曲线数字加密算法(ECDSA), 它的理论基础是椭圆曲线密码学(ECC),而ECC存在的理论基础是点倍积(point multiplication)算式 Q = dP 中的私钥 d (几乎)不可能被破译。ECC相对于基于大质数分解的RSA,在提供相同安全级别的情况下,仅需长度更短的公钥。
以太坊椭圆曲线数字签名算法使用场景:
- 一是在生成每个交易(Transaction, tx)对象时,对整个tx对象进行数字签名;
- 二是在共识算法的Clique算法实现中,在针对新区块进行授权/封印的Seal()函数里,对新创建区块做了数字签名
7、EVM虚拟机
以太坊虚拟机(environment virtual machine,简称EVM),作用是将智能合约代码编译成可在以太坊上执行的机器码,并提供智能合约的运行环境。
EVM的特点:
- EVM是一种基于栈的虚拟机(区别于基于寄存器的虚拟机),用于编译、执行智能合约
- EVM是图灵完备的(图灵完备是指:具有无限存储能力的通用物理机器或编程语言,简单来说就是可以解决一切可计算的问题)
- EVM是一个完全隔离的环境,在运行期间不能访问网络、文件,即使不同合约之间也有有限的访问权限
- 操作数栈调用深度为1024
- 机器码长度一个字节,最多可以有256个操作码
三、核心功能拆解
1、P2P网络
以太坊作为一个去中心化的系统,其底层个体相互间的通信显然非常重要,所有数据的同步,各个个体状态的更新,都依赖于整个网络中每个个体相互间的通信机制。以太坊的网络通信基于peer-to-peer(p2p)通信协议,又根据自身传输数据类型(区块,交易,哈希值等),网络节点业务相关性等需求,在各方面做了特别设计。
基于Kad通信协议的节点发现机制
如今很多P2P网络的实现都采用DHT的方式实现查找,其中Kademlia(简称Kad)算法由于其简单性、灵活性、安全性成为主流的实现方式。
以太坊Kademlia算法不断的从附近节点发现新的节点,并刷新本地的k桶, Kad算法设计以下几个方面:
- K桶:Kad的路由表是通过称为K桶的数据构造而成,K桶记录了节点NodeId,distance,endpoint,ip等信息。以太坊K桶按照与target节点距离进行排序,共256个K桶,每个K桶包含16个节点。
- 以太坊Kad网络中节点间通信基于UDP,主要由PING、PONG、FINDNODE、NEIGHBORS等4种UDP协议包。
分类 | 描述 |
---|---|
Ping | 探测一个节点,判断其是否在线 |
Pong | PING命令响应 |
FINDNODE | 向节点查询某个与目标节点ID距离接近的节点 |
NEIGHBORS | FIND_NODE命令响应,发送与目标节点ID距离接近的K桶中的节点 |
建立TCP连接
以太坊节点会开启一个TCP端口,用于承载业务数据,TCP的建立主要涉及到基于RLPx协议的两阶段握手过程。简单来说是:1.client 端与 server 端建立链接,交换公钥;2.通过共享秘钥加密交换Hello消息
session模型建立
在client 端与 server 端完成链接的建立后,会通过节点网络业务相关性建立不同的session模型,比如全节点业务类型、轻节点业务类型,并提供相应的广播等服务。
2、交易/区块同步
交易/区块同步同步模式分为:Fast节点、全节点、轻节点。
- full 模式,从开始到结束,获取区块的header,获取区块的body,从创始块开始校验每一个元素,需要下载所有区块数据信息。速度最慢,但是能获取到所有的历史数据。
- fast模式,获取区块的header,获取区块的body,在同步到当前块之前不处理任何事务。下载的数据大小约为50GB(截止2018-02-04)。然后获得一个快照,此后,像full节点一样进行后面的同步操作。这种方法用得最多,目的在不要在意历史数据,将历史数据按照快照的方式,不逐一验证,沿着区块下载最近数据库中的交易,有可能丢失历史数据。此方法可能会对历史数据有部分丢失,但是不影响今后的使用。
- light模式,仅获取当前状态。验证元素需要向full节点发起相应的请求
交易/区块同步方式还包括主动同步:
- 自身节点导入成功一个 best block 时,会将 block 拆解成 block header 以及 block body 进行广播
- 自身节点导入一笔交易后,也会进行同步
3、交易流程
一笔交易的执行,主要包括交易接收、防双花、交易入队,然后在节点区块阶段进行交易打包,之后进行交易执行及共识,最后在通过区块队列导入到最长区块链中。
防双花核心点:交易队列的去重检查、历史区块集的交易去重检查、区块高度范围检查
交易打包核心点:打包策略、同步交易队列
交易执行核心点:evm编译器初始化、gas扣减策略、执行流程
区块导入核心点:区块最长链构建,区块数据存储一致性
4、共识引擎
以太坊公链中目前采用POW共识算法,设计到节点的工作量证明(Ethash 共识)。在fisco联盟链中,主要采用PBFT的三阶段共识。
以下为PBFT 的模型总结:
阶段 | broadcast msg | PBFTPacketType | handle msg |
---|---|---|---|
第一阶段 | broadcastPrepareReq | PrepareReqPacket | handlePrepareMsg |
第二阶段 | broadcastSignReq | SignReqPacket | handleSignMsg |
第三阶段 | broadcastCommitReq | CommitReqPacket | handleCommitMsg |
异常处理 | broadcastViewChangeReq | ViewChangeReqPacket | handleViewChangeMsg |
PBFT的三阶段共识:
- PBFT正常流程的三阶段是指:1. Prepare阶段 2. Sign阶段 3. Commit阶段。
- PBFT中,由 N个节点组成的的共识网络最多可以容忍 f=(N-1)/3个节点作恶。
- 在Sign阶段和Commit阶段,只有收到足够的来自其他节点的消息才能进入下一步。这里的足够是指数量达到quorum=N-f
PBFT三阶段流程是正常情况完成共识的流程。实际环境下可能因为网络传输时延、主节点作恶、EVM执行超时等原因导致共识无法正常完成,上述问题统称为异常。在异常流程中,PBFT会进行视图切换。
5、客户端RPC信息查询
以太坊提供http及tcp的RPC方式提供给客户端进行交易发送及数据查询。
其中客户端可以对区块中的交易结果,最新区块信息,交易回执,合约数据等信息进行查询。
交易结果查询包括:eth_getTransactionByHash,
区块信息查询包括:eth_getBlockByHash、eth_getBlockByNumber,
合约内数据查询包括:eth_call,涉及到 Message call
交易回执事件注册包括:eth_newFilter
来源:CSDN
作者:逆月林
链接:https://blog.csdn.net/niyuelin1990/article/details/104003786