- 数据层:本质是一个数据库,存储区块链中的所有信息内容,以太坊的存储是由leveldb数据 库保存的,leveldb的数据是以键值对的形势存储。所有与交易,操作相关的数据,都保存在 区块中,并且每个区块链接起来,则构成更大的区块体系,称为区块链。所有交易或操作, 存在各个个体账户的状态(state)中,账户的呈现形式是为stateObject有statedb统一管理。
- 网络层:以太坊底层分布式网络即P2P网络,使用了经典的Kademlia网络,可以称为kad, kad是一种能在本身节点边查找临近节点的算法,最终通过UDP实现网络广播,为了能够在 全互联网实现通讯,以太坊采用NAT穿透技术实现路由器的穿透,确保全世界以太坊全节点 信息保持一致。
- 共识层:共识层就是规定通过何种方式实现交易记录的过程。比如比特币用的是工作量证明 机制,用PoW标示,该共识算法完全取决于电脑的性能越好,越容易获取到货币奖励。以太 坊也是采用P〇W算法,但是PoW存在很多大弊端,比如非常费电浪费资源,所以以太坊有从 PoW转向PoS算法的趋势。我自己理解这种方式是必然趋势,但是这样会破坏以太坊现有架 构,所以难度非凡。
- 激励层:以太坊采用PoW方式实现挖矿机制。
- 合约层:最早的公链是没有这一层的,所以最初的公链只能进行交易,而无法用于其他的领 域或是进行其他的逻辑处理。由以太坊的出现,合约层显体现出重大作用,通过合约层开发 者可以开发任意多的DAPP,实现完整的区块链生态系统,以太坊中这部分包括了坊虚拟机 EVM和智能合约两部分。
- 应用层:以太坊最上层,也是显示层。如以太坊使用的是truffle和web3-js技术。可以是移动 端或者web端,目前在应用层开发的产品层次不穷,比如以太坊加密猫、fomo3D都是风靡 一时的应用层产品。基于此层开发DAPP,发行代币等都是在这个层面,通过DAPP提供的 Web应用和智能合约交互。
三、从结构上分析以太坊
我们看一下以太坊层次图
以太坊最上层的是DApp。它通过Web3.js和智能合约层进行交互。所有的智能合约都运行在 EVM (以太坊虚拟机)上,并会用到RPC的调用。在EVM和RPC下面是以太坊的四大核心内容, 包括:blockChain,共识算法,挖矿以及网络层。除了DApp外,其他的所有部分都在以太坊的客 户端里,目前最流行的以太坊客户端就是Geth (Go-Ethereum)
四、从体系上分析以太坊
- 1区块链范式
- 1.1基于交易的状态机系统
- 1.1.1创世区块起源(genesis) -1.1.2状态改变到最终状态 。1.2账户状态 -1.2.1账户余额 -1.2.2名誉度 -1.2.3信誉度 -1.2.4显不世界附属 -1.2.5扫绘信息
- 1.3交易是链的两个状态桥梁
- 1.4 一个有效的状态是通过交易进行的
- 1.5区块链中交易信息,通过Hash算法连接
- 1.6挖矿
- 1.6.1付出一些列工作量还蠃得交易记账权
- 1.6.2 Proof Of Work
- 1.7单位
- 1.7.1内置货币单位
- 1.7.2换算
- 1.7.3价值标示W曰单位计算
- 1.7.3.1 货币
- 1.7.3.2 余额
- 1.7.3.3 支付
- 1.8系统多状态共存Ghost协议
- 2约定
- 3区块状态和交易
五、以太坊简易框架
如果阅读当前版本的以太坊难度大,那么我们不读一下github上的以太坊最初版本,通过阅读这 个代码可以加深理解以太坊的模块组成,揣测设计的想法和思路。去掉单元测试文件,整个项目 最重要的部分其实只有以下部分
big.go vm.go parsing.go transaction.go block.go block_manager.go ethereum.go serialization.go
8个文件。这8个文件都比较小,功能比较简单,也很好理解。 数学封装 big.go封装了大整数的指数运输。 虚拟机 vm.go主要作用为通过操作码编译只能合约,定义了虚拟机操作码,操作码类型,虚拟机结构和虚拟机的实现。
以太坊vm的实现是基于栈的完成的,实现相对比较简单。
智能合约编译parsing.go主要实现的是智能合约的编译和对编译后的代码进行处理,后续供虚拟机执行。
交易transaction.go定义了交易的结构,还有费用和收益变量。一笔交易包括发起者, 接受者,交易的数量,交易的费用,编译后的脚本源码,运行需要内存,交易签名和地址。费用和收益变量只有初始化赋值,没有具体使用。脚本源码是智能合约的雏形,为了方便描述和理解 还是称呼它为智能合约。此时的智能合约语言和x86intel汇编类似,语法比较简单,一个操作指 令加上操作数,操作数的个数最常见是0个,1个,2个和3个,设计者实现的时候,最多可以支持 6个。操作指令和操作数之间用空格分开,操作数与操作数之间也用空格分开。
vm运行时,根据编译规则的逆规则,解析出指令码和操作数,根据指令码的功能,进行下一步 处理。运行需要内存没有使用,猜测是用作运行智能合约。签名字段没有使用,猜测是校验交易 是否篡改过。地址是对transaction结构序列化后的字节数组取sha256的前20位。 区块 block.go用来定义块结构,非常简单,仅包含一个transaction数组. 区块管理器 Wock_manager.go是定义块管理器,用来处理块,持有一个vm指针,依次执行块里面的每一个 交易的智能合约。 以太坊入口 ethereum.go是demo程序入口,mock两笔交易,打印vm执行的日志,最后打印了其中一笔交易 的序列化结果。 交易序列化 serialization.go实现序列化功能,采用的是RLP编码,只能对字符串编码。编码规则是:
- 如果是字符串,编码结果是"\x00"加上字符串的长度,再加上原字符串。计算字符串的长度有 一个规则,确保编码无二义性,能正确解码。 如果是字符串数组,编码结果是"\x01"加上每一个字符串编码结果的长度和的编码,再加上每 一个字符串的编码结果。有点绕口,这是个递归的过程。
- 如果是其他类型需要转换成字符串或者字符串数组。
- RLP编码的规律是以数据类型开始,字符串是"\x00",字符串数组是"\x01,然后是数据长度,最后 是数据内容。
RLP编码和解码是互逆过程,实现比较简单,编码紧凑,传输效率较高,后续版本中,在网络传 输和本地存储都有RLP编码。
总结
总体来说,这个版本的代码比较简单,是geth的初始设计和验证,不过对于初次学习geth源码, 整体认识geth还是有一定的意义。
2018-2022, allenzhang Revision
9beab6e