请选择 进入手机版 | 继续访问电脑版
开启辅助访问
QQ登录|微信登录|登录 |立即注册

盖茨网区块链技术社区

以太坊基础原理理论

1.区块浏览器
目前整体情况如下:
QQ图片20180326100048.png

浏览器上面查看产线上最新的一笔交易:
前一块区块
  1. Height:        < Prev   4896777   Next >
  2.   TimeStamp:        1 min ago (Jan-12-2018 03:43:47 PM +UTC)
  3.   Transactions:        246 transactions and 14 contract internal transactions in this block
  4.   Hash:        0x43e69979a11aec5bdcdec5e8021b7b8d73f4d6c5ed40a36ab59e760f01670a5d
  5.   Parent Hash:        0xe9d552d54266947fdb5312eea9dcd824143cb10b57d2c45f96e35b4e2fcb28d3
  6.   Sha3Uncles:        0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
  7.   Mined By:        0xea674fdde714fd979de3edf0f56aa9716b898ec8 (Ethermine) in 25 secs
  8.   Difficulty:        2,079,662,402,903,195
  9.   Total Difficulty:        2,040,977,597,418,315,199,265
  10.   Size:        33907 bytes
  11.   Gas Used:        7,999,312 (99.99%)
  12.   Gas Limit:        8,000,029
  13.   Nonce:        0x88e1f88e08244ea0bd
  14.   Block Reward:        3.224291759561512113 Ether (3 + 0.224291759561512113)
  15.   Uncles Reward:        0
  16.   Extra Data:        ethermine-asia4 (Hex:0x65746865726d696e652d6173696134)
复制代码
后一块区块
  1. Height:        < Prev   4896778   Next >
  2.   TimeStamp:        22 hrs 16 mins ago (Jan-12-2018 03:44:09 PM +UTC)
  3.   Transactions:        232 transactions and 10 contract internal transactions in this block
  4.   Hash:        0x58733dcef5a28f2f8de2b40bd3bfd5e4e5894a18aff20f50023eefc2b02cd32b
  5.   Parent Hash:        0x43e69979a11aec5bdcdec5e8021b7b8d73f4d6c5ed40a36ab59e760f01670a5d
  6.   Sha3Uncles:        0x8d0cb901e561c36a7773047c465215f8e8f85bb66a90a34059a059e66285d3d3
  7.   Mined By:        0xea674fdde714fd979de3edf0f56aa9716b898ec8 (Ethermine) in 22 secs
  8.   Difficulty:        2,078,646,942,811,064
  9.   Total Difficulty:        2,040,979,676,065,258,010,329
  10.   Size:        34783 bytes
  11.   Gas Used:        7,985,961 (99.82%)
  12.   Gas Limit:        8,000,029
  13.   Nonce:        0x8815fe70a808f6df92
  14.   Block Reward:        3.62598404525173896 Ether (3 + 0.43848404525173896 + 0.1875)
  15.   Uncles Reward:        4.875 Ether (2 Uncles at Position 0, Position 1)
  16.   Extra Data:        ethermine-eu10 (Hex:0x65746865726d696e652d65753130)
复制代码


2.原理摘录
在Ethereum 代码里,所有用到的哈希值,都使用该Hash类型,长度为32bytes,即256 bits;Ethereum 中所有跟帐号(Account)相关的信息,比如交易转帐的转出帐号(地址)和转入帐号(地址),都会用该Address类型表示,长度20bytes。
Gas, 是Ethereum里对所有活动进行消耗资源计量的单位。这里的活动是泛化的概念,包括但不限于:转帐,合约的创建,合约指令的执行,执行中内存的扩展等等。
Ether, 是Ethereum世界中使用的数字货币,也就是常说的以太币。如果某个帐号,Address A想要发起一个交易,比如一次简单的转帐,即向 Address B 发送一笔金额H,那么Address A 本身拥有的Ether,除了转帐的数额H之外,还要有额外一笔金额用以支付交易所耗费的Gas。
如果可以实现Gas和Ether之间的换算,那么Ethereum系统里所有的活动,都可以用Ether来计量。
上面说明了GAS/Ether的关系。
区块(Block)是Ethereum的核心结构体之一,是交易的集合!
包括以下:
AccountNonce :发送者的发起的交易总数量
price:单位Gas消耗所折抵的Ether多少
GasLimit:该tx执行过程中所允许消耗资源的总上限,解决恶意占据资源的问题
Recipient:转账转入方地址
Amount:此次交易转移的以太币数量
Payload:数据成员,用于合约的数据
转出方地址是加密保护的,没有直接显示。

交易的执行
Block 类型的基本目的之一,就是为了执行交易。狭义的交易可能仅仅是一笔转帐,而广义的交易同时还会支持许多其他的意图。Ethereum 中采用的是广义交易概念。按照其架构设计,交易的执行可大致分为内外两层结构:第一层是虚拟机外,包括执行前将Transaction类型转化成Message,创建虚拟机(EVM)对象,计算一些Gas消耗,以及执行交易完毕后创建收据(Receipt)对象并返回等;第二层是虚拟机内,包括执行转帐,和创建合约并执行合约的指令数组。
在一个Block的处理过程(即其所有tx的执行过程)中,GasPool 的值能够告诉你,剩下还有多少Gas可以使用。在每一个tx执行过程中,Ethereum 还设计了偿退(refund)环节,所偿退的Gas数量也会加到这个GasPool里。
对一个Block的处理如下:
1.购买Gas。首先从交易的(转帐)转出方账户扣除一笔Ether,费用等于tx.data.GasLimit * tx.data.Price;同时 st.initialGas = st.gas = tx.data.GasLimit;然后(GasPool) gp -= st.gas。
2.计算tx的固有Gas消耗 - intrinsicGas。它分为两个部分,每一个tx预设的消耗量,这个消耗量还因tx是否含有(转帐)转入方地址而略有不同;以及针对tx.data.Payload的Gas消耗,Payload类型是[]byte,关于它的固有消耗依赖于[]byte中非0字节和0字节的长度。最终,st.gas -= intrinsicGas
3.EVM执行。如果交易的(转帐)转入方地址(tx.data.Recipient)为空,调用EVM的Create()函数;否则,调用Call()函数。无论哪个函数返回后,更新st.gas。
计算本次执行交易的实际Gas消耗: requiredGas = st.initialGas - st.gas
4.偿退Gas。它包括两个部分:首先将剩余st.gas 折算成Ether,归还给交易的(转帐)转出方账户;然后,基于实际消耗量requiredGas,系统提供一定的补偿,数量为refundGas。refundGas 所折算的Ether会被立即加在(转帐)转出方账户上,同时st.gas += refundGas,gp += st.gas,即剩余的Gas加上系统补偿的Gas,被一起归并进GasPool,供之后的交易执行使用。
5.奖励所属区块的挖掘者:系统给所属区块的作者,亦即挖掘者账户,增加一笔金额,数额等于 st.data,Price * (st.initialGas - st.gas)。注意,这里的st.gas在步骤5中被加上了refundGas, 所以这笔奖励金所对应的Gas,其数量小于该交易实际消耗量requiredGas。
关于签名
Ethereum 中每个交易(transaction,tx)对象在被放进block时,都是经过数字签名的,这样可以在后续传输和处理中随时验证tx是否经过篡改。Ethereum 采用的数字签名是椭圆曲线数字签名算法(Elliptic Cure Digital Signature Algorithm,ECDSA)。
关于EMV
每个交易(Transaction)带有两部分内容需要执行:1. 转帐,由转出方地址向转入方地址转帐一笔以太币Ether; 2. 携带的[]byte类型成员变量Payload,其每一个byte都对应了一个单独虚拟机指令。这些内容都是由EVM(Ethereum Virtual Machine)对象来完成的。EVM 结构体是Ethereum虚拟机机制的核心。
关于合约
合约(Contract)是EVM用来执行(虚拟机)指令的结构体。
合约包含的参数:
CallerAddress :调用地址
caller :转出方地址
self :转入方地址
Code:指令数组,其中每一个byte都对应于一个预定义的虚拟机指令
Input:数据数组,是指令所操作的数据集合
create()和call()用于创建合约并完成转账,call针对处理(转帐)转入方地址不为空的情况,create用于处理(转帐)转入方地址为空的情况,会创建一个。
已定义的operation,种类很丰富,包括:
算术运算:ADD,MUL,SUB,DIV,SDIV,MOD,SMOD,EXP...;
逻辑运算:LT,GT,EQ,ISZERO,AND,XOR,OR,NOT...;
业务功能:SHA3,ADDRESS,BALANCE,ORIGIN,CALLER,GASPRICE,LOG1,LOG2...等等

Ethereum的数据结构:
StateDB---交易和操作的结果
Block(head,body)
BlockChain
LevelDB
Merkle-PatriciaTrie(MPT)数据结构
Block
Block(区块)是Ethereum的核心数据结构之一。所有账户的相关活动,以交易(Transaction)的格式存储,每个Block有一个交易对象的列表;每个交易的执行结果,由一个Receipt对象与其包含的一组Log对象记录;所有交易执行完后生成的Receipt列表,存储在Block中(经过压缩加密)。不同Block之间,通过前向指针ParentHash一个一个串联起来成为一个单向链表,BlockChain 结构体管理着这个链表。
Block结构体基本可分为Header和Body两个部分
Header是Block的核心,包含以下参数:
ParentHash:指向父区块(parentBlock)的指针。除了创世块(Genesis Block)外,每个区块有且只有一个父区块。
Coinbase:挖掘出这个区块的作者地址。在每次执行交易时系统会给与一定补偿的Ether,这笔金额就是发给这个地址的。
UncleHash:Block结构体的成员uncles的RLP哈希值。uncles是一个Header数组,它的存在,颇具匠心。
Root:StateDB中的“state Trie”的根节点的RLP哈希值。Block中,每个账户以stateObject对象表示,账户以Address为唯一标示,其信息在相关交易(Transaction)的执行中被修改。所有账户对象可以逐个插入一个Merkle-PatricaTrie(MPT)结构里,形成“state Trie”。
TxHash: Block中 “tx Trie”的根节点的RLP哈希值。Block的成员变量transactions中所有的tx对象,被逐个插入一个MPT结构,形成“tx Trie”。
ReceiptHash:Block中的 "Receipt Trie”的根节点的RLP哈希值。Block的所有Transaction执行完后会生成一个Receipt数组,这个数组中的所有Receipt被逐个插入一个MPT结构中,形成"Receipt Trie"。
Bloom:Bloom过滤器(Filter),用来快速判断一个参数Log对象是否存在于一组已知的Log集合中。
Difficulty:区块的难度。Block的Difficulty由共识算法基于parentBlock的Time和Difficulty计算得出,它会应用在区块的‘挖掘’阶段。
Number:区块的序号。Block的Number等于其父区块Number +1。
Time:区块“应该”被创建的时间。由共识算法确定,一般来说,要么等于parentBlock.Time + 10s,要么等于当前系统时间。
GasLimit:区块内所有Gas消耗的理论上限。该数值在区块创建时设置,与父区块有关。具体来说,根据父区块的GasUsed同GasLimit * 2/3的大小关系来计算得出。
GasUsed:区块内所有Transaction执行时所实际消耗的Gas总和。
Nonce:一个64bit的哈希数,它被应用在区块的"挖掘"阶段,并且在使用中会被修改

StateDB作为本地存储模块,它面向业务模型,又连接底层数据库,内部利用两极缓存机制来存储和更新所有代表“账户”的stateObject对象。
stateObject除了管理着账户余额等信息之外,也用了类似的两级缓存机制来存储和更新所有的State数据。

关于Uncle Block
L5CY}M1KA09J6$E21XK6O{W.png
Uncle区块
以太坊为什么要这么设计呢?因为以太坊的区块时间是20秒左右,相对于比特币,更容易出现临时分叉和孤儿区块。而且较短的区块时间,也使得区块在整个网络中更难以充分传播,尤其是对那些网速慢的矿工,这是一种极大的不公平。为了平衡各方利益,才设计了这样一个叔块机制。叔块在全部挖掘出来的区块中占的比例叫叔块率,目前叔块率在9.7%左右。

生产一个区块
对于一个新区块被挖掘出的过程,代码实现上基本分为两个环节:一是组装出一个新区块,这个区块的数据基本完整,包括成员Header的部分属性,以及交易列表txs,和叔区块组uncles[],并且所有交易已经执行完毕,所有收据(Receipt)也已收集完毕,这部分主要由worker完成;二是填补该区块剩余的成员属性,比如Header.Difficulty等,并完成授权,这些工作是由Agent调用<Engine>接口实现体,利用共识算法来完成的。
环节一:
worker.update()分别监听ChainHeadEvent,ChainSideEvent,TxPreEvent几个事件
ChainHeadEvent:新的区块已经挖好。准备下一个
ChainSideEvent:有Uncle块产生,加入Uncle队列
TxPreEvent:指的是一个新的交易tx被加入,没有挖掘,则执行该tx
对于任何一个Ethereum网络中的节点来说,挖掘一个新区块和从其他节点下载、同步一个新区块,根本是相互冲突的。

环节二:
Ethash共识算法-正式环境
Ethash算法又被称为Proof-of-Work(PoW),是基于运算能力的授权/封印过程。Ethash实现的Seal()函数,其基本原理可简单表示成以下公式:
RAND(h, n) <= M / d
这里M表示一个极大的数,比如2^256-1;d表示Header成员Difficulty。RAND()是一个概念函数,它代表了一系列复杂的运算,并最终产生一个类似随机的数。这个函数包括两个基本入参:h是Header的哈希值(Header.HashNoNonce()),n表示Header成员Nonce。整个关系式可以大致理解为,在最大不超过M的范围内,以某个方式试图找到一个数,如果这个数符合条件(<=M/d),那么就认为Seal()成功。
我们可以先定性的验证一个推论:d的大小对整个关系式的影响。假设h,n均不变,如果d变大,则M/d变小,那么对于RAND()生成一个满足该条件的数值,显然其概率是下降的,即意味着难度将加大。考虑到以上变量的含义,当Header.Difficulty逐渐变大时,这个对应区块被挖掘出的难度(恰为Difficulty本义)也在缓慢增大,挖掘所需时间也在增长,所以上述推论是合理的。
Clique共识算法-测试环境
Clique算法又称Proof-of-Authortiy(PoA),它实现的Seal()其实是一个标准的数字签名加密过程,可由下列公式表示:
n = F(pr, h)
其中F()是数字签名函数,n是生成的数字签名,pr是公钥,h是被加密的内容。具体到Clique应用中,n是一个65 bytes长的字符串,pr是一个common.Address类型的(长度20 bytes)地址,h是一个common.Hash类型(32 bytes)的哈希值,而签名算法F(),目前采用的正是椭圆曲线数字签名算法(ECDSA)。
关于以太钱包
以太坊中代码中,accounts.Manager是管理账户信息的模块。Manager可以管理多个<Wallet>的实现,每个<Wallet>实现拥有多个Account账户,每个Account对应一个Address地址,而以太币Ether存放于每个Address上。以太坊同时提供软件版和硬件版的<Wallet>实现。
以太坊中,每个Address类型变量均来自于椭圆曲线数字签名算法(ECDSA)所用的公钥,因此钱包程序还必须提供管理数字签名公钥密钥的功能。软件版accounts.<Wallet>实现叫keystore,通过在本地文件系统中分别显式存储账户信息和加密存储公钥密钥的方式,提供以上功能。
以太坊客户端程序之间,会通过accounts.Manager模块相互订阅Wallet更新事件,以保证每个客户端个体(peer),都能及时更新全网络中的完整Wallet列表。
客户端程序的核心是eth.Ethereum,它以RPC service的形式,向外提供内部各模块的功能,诸如挖掘区块, 数据库读写,p2p下载等。
Key{}通过ecdsa.PrivateKey对象从而同时携带ECDSA所用的公钥密钥,所以这里涉及到公钥密钥部分,都是针对Key对象做的操作。keystore机制中,在本地存储的是经过加密的Key对象的JSON格式,所用的加密方法被称为Web3 Secret Storage.
关于钱包
下载一个钱包,我选择了本地网络,因为测试网络很难拿到测试Eth,所以只能本地挖矿了。
列举下常用的功能:
  • 创建账户,需要输入密码,产生一个账户地址
  • 备份KeyStore文件
  • 查询账户余额
  • 发送交易
  • 部署合约
  • 发送数据,执行合约

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则