以太坊原理分析(二)以太坊区块结构和账户体系

1、引言

       区块链的本质是一个分布式的数据库。因此不同时刻的用户数据的写入对应着不同的状态。比特币使用UTXO来表示状态的转移,而以太坊使用账来表示状态的转移。

2、账户

       以太坊中存在两种账户,分别是外部账户和合约账户。

外部账户EOA:一般自然人分配的账户,被私钥控制且没有任何代码与之关联。
合约账户CA:给智能合约分配的账户,被合约代码控制且有代码与之关联。
    账户在源码中的定义如下:

    typeAccountstruct{

            Nonce    uint64

            Balance  *big.Int

            Root     common.Hash//merklerootofthestoragetrie

            CodeHash[]byte }

Nonce:如果当前账户为EOA,则Nonce为发送的交易序号;如果当前账户为CA,则Nonce为合约创建的序号。
Balance:账户余额,表示账户所对应地址的余额。
Root:存储为状态树的根hash,在EOA中,此字段为空。
CodeHash:账户绑定的EVM code,在EOA中,此字段为空。

图1 此图片来自网络
    EOA账户只能发起交易,例如转移以太币或者触发合约代码。CA账户不能发起交易,可以被触发执行合约代码。

    外部账户对应转账地址,由用户创建;合约账户在以太坊中由EVM根据合约地址创建(在代码vm文件夹下evm.go文件中)。

3、交易

typeTransactionstruct{

    datatxdata

    //caches

    hashatomic.Value

    sizeatomic.Value

    fromatomic.Value

}

typetxdatastruct{

    AccountNonceuint64         

    Price        *big.Int       

    GasLimit     uint64         

    Recipient    *common.Address

    Amount       *big.Int       

    Payload      []byte         

 

    //Signaturevalues

    V*big.Int`json:"v"gencodec:"required"`

    R*big.Int`json:"r"gencodec:"required"`

    S*big.Int`json:"s"gencodec:"required"`

    //ThisisonlyusedwhenmarshalingtoJSON.

    Hash*common.Hash`json:"hash"rlp:"-"`

}

 

AccountNonce:发起者发起的交易总数量        
Price:此次交易的gas price
GasLimit:本交易允许消耗的最大gas数 
Recipient:交易接收者的地址
Amount:此次交易转移的以太币数量 
Payload:其中每个byte对应一个单独虚拟机指令
V签名数据
R签名数据
S签名数据
hash交易的hash
size交易数据的大小
from交易的发起地址
3、区块头


typeHeaderstruct {

        ParentHash common.Hash    //Hp,上一区块全部内容的hash           

        UncleHash  common.Hash    //Ho,本区块的所有叔块列表的hash

        Coinbase   common.Address //Hc,成功挖出本区块的矿工地址

        Root       common.Hash    //Hr,本区块所有交易的状态tree的根hash

        TxHash     common.Hash    //Ht,本区块所有交易tree的根hash

        ReceiptHash common.Hash   //He,本区块所有交易收据tree的根hash

        Bloom      Bloom          //Hb,交易收据日志组成的Bloom过滤器

        Difficulty    *big.Int      //Hd,本区块难度级别

        Number     *big.Int       //Hi,区块序号,从创世块0递增

        GasLimit     uint64         //Hl,每个区块当前的gas limit

        GasUsed     uint64         //Hg,本区块交易消耗的总gas

        Time        *big.Int       //Hs,本区块创建时的Unix时间戳

        Extra        []byte         //Hx,区块附加数据,<=32字节

        MixDigest    common.Hash   //Hm,256位的hash

        Nonce       BlockNonce     //Hn,64位的hash

 }

图2 此图片来自网络


Root(状态hash):整个系统状态的hash,也就是所有账户状态树的根hash。

TxHash(交易列表hash):本区块中所有交易默克尔树的根hash。

ReceiptHash(收据列表hash):收据默克尔树的根hash。

       状态树并不存在于链上,而存在于节点的levelDB中。只有它的根hash存在于区块头Root中,每一个区块头里的Root都是区块被挖出确认时的快照。
补充(此内容来自于网络)

三棵树允许轻客户端轻松地进行并核实以下类型的查询答案:

1)        这笔交易被包含在特定的区块中了么?

2)        告诉我这个地址在过去30天中,发出X类型事件的所有实例(例如,一个众筹合约完成了它的目标)

3)        目前我的账户余额是多少?

4)        这个账户是否存在?

5)        假装在这个合约中运行这笔交易,它的输出会是什么?

       第一种是由交易树(transaction tree)来处理的;第三和第四种则是由状态树(state tree)负责处理,第二种则由收据树(receipt tree)处理。计算前四个查询任务是相当简单的。服务器简单地找到对象,获取梅克尔分支,并通过分支来回复轻客户端。第五种查询任务同样也是由状态树处理,但它的计算方式会比较复杂。

总结

整个以太坊维持一个所有账户状态的树,这棵树的hash会打包在整个链上;
账户状态树本身的信息不会上链,保存在leveldb中;
交易(狭义的)、消息等相关信息通过交易(广义的)的方式打包在区块上;
交易的执行可大致分为内外两层结构:第一层是虚拟机外,包括执行前将Transaction类型转化成Message,创建虚拟机(EVM)对象,计算一些Gas消耗,以及执行交易完毕后创建收据(Receipt)对象并返回等;第二层是虚拟机内,包括执行转帐,和创建合约并执行合约的指令数组;
合约账户在创建合约时生成,不管是合约还是交易,都会和账户(EOA、CA)相关,所以区块中交易树hash、状态树hash、收据树hash三者能保证链的一致性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值