资讯专栏INFORMATION COLUMN

以太坊基础概念详解

pingink / 1820人阅读

摘要:主要讲解以太坊中的一些基本元素,如区块账户状态交易费用等。所以它表示的是整个以太坊系统所有账户当前的状态。账户以太坊中有两种账户外部拥有账户,一般指自然人拥有的账户。总结以上就是以太坊里的一些基础元素,没有讲到复杂的交易执行等,后续再写。

本文不讲区块链,也就意味着你有一些区块链的基本认知。
主要讲解以太坊中的一些基本元素,如:区块、账户、状态、交易、费用等。因这些概念之间相互紧密联系,虽描述的时候尽量分出层级,但提醒看官看得时候可以前后翻阅。

对以太坊的解剖按从整体到局部的思路进行:

1、以太坊

以太坊可以用几句话道出其本质:

以太坊是一个基于交易的状态机。

全球就这一台单机(但分布存在),【系统状态】不停的改变。系统状态是一个术语,即后面讲到的world state。

这台单机主要由区块链组成,区块链上保存着状态和交易。

当我们与以太坊交互时,其实就是在执行交易、改变系统状态。

用一个简洁优美的公式表示就是:

σ′ =Υ(σ,T)

Υ是状态转换函数,T是交易,σ是状态,σ′转换后的状态。

借用一张图吧

从创世区块开始,无尽的交易不断的刷新着系统当前状态,每产生一个区块就对当前状态做一次快照(patricia trie根)存入区块头中。

patricia trie是merkle tree的变体,请自行了解merkle tree。
2、区块结构

再看一个公式

B≡ (BH,BT,BU)

意思是区块恒等于(区块头,交易列表,叔块)

所以,区块是由三大部分组成:
区块头,叔块,交易列表。请看图:

1)区块头由15个字段组成。
2)叔块其实就是孤块,因以太坊出块速度很快平均十几秒就会打包生成一个块,所以矿工挖矿的竞争性很高,可能同时产出几个都合法的区块,以太坊为了一些安全性起见,允许竞争块也挂在到主链上,同时给与挖出这些孤块的矿工们少许奖励增加工作的公平性。这些孤块最多允许6个高度,这也是6个区块确认主链说法的来源。
3)交易列表,存储的是本区块中所有的交易内容。

图中的公式后面说。

看一下一个实际的区块信息:

"blocks" : [
            {
                "blockHeader" : {
                    "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                    "coinbase" : "0x3535353535353535353535353535353535353535",
                    "difficulty" : "0x020000",
                    "extraData" : "",
                    "gasLimit" : "0x05f5e100",
                    "gasUsed" : "0x014fa1",
                    "hash" : "0x39f4659b079e257df8fd7e699528531e97a6b8a442ca0d11200c4a2f7433c483",
                    "mixHash" : "0x7379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969",
                    "nonce" : "0x8e08d7aabeee8773",
                    "number" : "0x01",
                    "parentHash" : "0xadbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3",
                    "receiptTrie" : "0xb21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316b",
                    "stateRoot" : "0xde4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7",
                    "timestamp" : "0x03e8",
                    "transactionsTrie" : "0x56445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769d",
                    "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
                },
                "rlp" : "0xf90308f901f9a0adbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347943535353535353535353535353535353535353535a0de4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7a056445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769da0b21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316bb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018405f5e10083014fa18203e880a07379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969888e08d7aabeee8773f90108f90105460183030d4094c305c901078781c232a2a521c2af7980f8385ee980b8a430c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000001ba021a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44a075af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14c0",
                "transactions" : [
                    {
                        "data" : "0x30c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
                        "gasLimit" : "0x030d40",
                        "gasPrice" : "0x01",
                        "nonce" : "0x46",
                        "r" : "0x21a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44",
                        "s" : "0x75af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14",
                        "to" : "0xc305c901078781c232a2a521c2af7980f8385ee9",
                        "v" : "0x1b",
                        "value" : "0x00"
                    }
                ],
                "uncleHeaders" : [
                ]
            }
        ]
3、区块头

区块头包含15个字段,介绍如下:

type Header struct {
        ParentHash  common.Hash    //Hp,上一区块全部内容的hash,区块因它而成链!
        UncleHash   common.Hash    //Ho,本区块的ommers(所有叔块)列表的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组合证明出块执行了足够的计算
        Nonce       BlockNonce     //Hn,64位的hash,与MixDigest组合证明出块执行了足够的计算
}

首先,ParentHash是上一个区块全部内容的hash值,下一个区块总是包含上一个区块全部内容的hash值,这就使得区块成链。

再次,有三个特别的字段保存的是patricia trie的根,Root(状态hash)、TxHash(交易列表hash)、ReceiptHash(收据列表hash)。这个Root就是系统状态hash。系统状态就是以太坊整个网络中所有账户的状态,就是world state,它是一个merkle patricia trie结构。这个树(包括所有patricia trie)并不存在于区块,而存在于节点的levelDB中。只有它的根hash存在于区块头Root中,每一个区块头里的Root都是区块被挖出确认时的快照,而world state指现在所有账户的状态。

world state是跨块存在的,另外两棵树只存储本区块的交易和收据。

4、world state

再说一下world state:
world state是一颗全局状态树,在以太坊里只有一个,它被持续地更新。
这棵树包含了以太坊网络里每一个账户的key/value映射。
所以它表示的是整个以太坊系统所有账户当前的状态。

其折叠函数是:

LS(σ) ≡ {p(a) : σ[a]≠ ∅}

意味着非空p(a)的集合,p(a)就是patrcia 叶子节点的内容:

p(a) ≡  (KEC(a), RLP((σ[a]n, σ[a]b, σ[a]s, σ[a]c)))

这表示一个叶子节点是一个key/value映射,key是KEC(a)即160位的账户地址的哈希(Keccak-256算法),value是账户(nonce、balance、storageRoot、codeHash)的RLP格式序列化字节。

5、账户

以太坊中有两种账户
1、外部拥有账户(EOA),一般指自然人拥有的账户。
2、合约账户(CA),为智能合约分配的账户。

看一下账户的源码定义:

type Account struct {
    Nonce    uint64      // σ[a]n ,若为EOA是发送的交易序号,如为CA是合约创建的序号。
    Balance  *big.Int    // σ[a]b ,这个地址的余额。
     //merkle root of the storage trie
    Root     common.Hash // σ[a]s ,账户自身内容RPL编码组成的Merkle Trie的根哈希
    CodeHash []byte      // σ[a]c ,账户绑定的EVM Code,账户一经创建不可修改。
}

EOA特征
codeHash为空
storageRoot为空
通过私钥控制
发起交易(转移以太币或触发合约代码)

CA特征
不能发起交易,可以被触发执行合约代码(通过EOA发起的交易或者从其他CA接收的消息调用激活)

怎么判断一个账户是空账户?

EMPTY(σ,a)≡ σ[a]c =KEC(()) ∧ σ[a]n =0 ∧ σ[a]b =0

从公式看,一个账户的Root为空且nonce为0且余额为0,则说明这是一个空账户。

6、交易

再回顾一个公式

σ′ =Υ(σ,T)

以太坊是一个基于交易的状态机。
任意两个账户之间的交易都会引起world state的改变。
两个相邻区块之间的状态差别很小,patricia trie这种数据结构能高效的处理整个系统账户变化的部分。

交易基本定义:【从外部拥有账户】发送的加密签名序列化指令。换句话说交易必须是从EOA发起的才能叫交易,CA之间的通信叫消息也有叫内部交易的,现在是有区别,以后这个区别会不会模糊化不知道。

交易类型有两种:
1、消息调用(Td
2、合约创建(Ti

从EOA到EOA的交易仅是转账。
EOA到CA可以激活各种操作。

看交易的源码定义:

type txdata struct {
    AccountNonce uint64          //Tn
    Price        *big.Int        //Tp
    GasLimit     uint64          //Tg
    Recipient    *common.Address //Tt
    Amount       *big.Int        //Tv
    Payload      []byte          //Td || Ti 
    V *big.Int
    R *big.Int
    S *big.Int
    // This is only used when marshaling to JSON.
    Hash *common.Hash
}

Tn必须等于发起交易的账户的nonce(翻阅前面说法可知,账户nonce是该账户发起的第几笔交易的序号,如果是创建合约则代表第几次创建合约的序号)
Tp是这笔交易消耗的gas单价
Tg是你愿意为这笔交易最多可以支付的上限
Tt是接收账户的地址,如果为空说明接受账户是一个CA,否则是EOA
Tv是到接收者的额度
Td或Ti,如果交易类型是消息调用则Palload写为Td,表示输入数据,例如消息的参数,假设有一个注册域名的合约服务,则Td就是该服务需要的参数如IP等。如果交易类型是创建合约,则Payload写为Ti,表示一段代码,这段代码用于创建合约账户,这段初始化代码只会被执行一次就丢弃掉,第二次执行的是创建完的合约代码体。

交易的公式:

可以看到当接收账户不同时,区别仅仅是Td和Ti的区别。

另外,一个区块里交易的顺序由装配这个区块的矿工决定。

7、费用

以太坊网络里任何计算都要支付gas(燃料),
思考为什么不直接用eth做费用?
答案是用两个概念gas和eth区别价值和价格,gas是一种固定衡量的价值,而eth是市场上快速变化的价格,很多EVM(以太坊虚拟机)的操作指令都需要消耗固定的费用就用gas来计价,gas的最小单位是wei,1eth = 1018wei = 109gwei。所以eth和gas之间是有汇率的。

GasPrice:燃料单价
GasLimit:愿意支付的燃料上限

GasLimit × GasPrice = 愿意支付的最大费用
10000 × 100gwei = 1015wei = 0.001eth

这图要说明的是:
一笔交易中,你设置的最大费用如果没有消耗完,多出的会返回给你。如果最大费用不够计算的花费,那么交易会终止、已改变的状态会回滚、但是钱被消耗不会退回了。这些已消耗的费用都奖励给矿工了。

计算都是有费用的,初次之外还有一些东西需要缴费:

费用的三种不同构成:
1)计算操作的固定费用
2)交易(合约创建或消息调用)费用
3)存储(内存、存储账户合约数据)费用

着重说一下存储费用:
存储收费是因为假如你的合约使得状态数据库存储增大,所有节点都会增加存储。
以太币是鼓励尽量保持少量存储的。
但是如果有操作是清除一个存储条目,这个操作的费用不但会被免除,而且由于释放空间还会获得退款。

总结

以上就是以太坊里的一些基础元素,没有讲到复杂的交易执行、EVM等,后续再写。

下面是一个区块链小程序,供大家参考:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24001.html

相关文章

  • Java开发区块链的三大sdk库

    摘要:是企业与区块链相遇的地方。的框架旨在成为开发区块链解决方案的支柱。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 如果你想将区块链合并到一个Java项目中,现在我们来看看就是这个细分领域中三个最大的OSS玩家。 好的伙计们,我们都听说过比特币,以太坊或其他加密货币,其中有一些时髦的名字围绕着我们常见的新闻,但我们作为Java开发人员知道如何轻松地与这些区块链技术进行交互吗?以...

    iKcamp 评论0 收藏0
  • 区块链开发中使用的最流行的编程语言

    摘要:我们目前正处于一个新兴的区块链开发行业中。,一种在以太坊开发人员中流行的新的简单编程语言,因为它是用于开发以太坊智能合约的语言。它是全球至少万开发人员使用的世界上最流行的编程语言之一。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 我们目前正处于一个新兴的区块链开发行业中。区块链技术处于初期阶段,然而这种颠覆性技术已经成功地风靡全球,并且最近经历了一场与众不同的繁荣。由于许多...

    2shou 评论0 收藏0
  • 以太将成为新互联网的支柱

    摘要:以太坊将成为新互联网的支柱,我为什么这么说正在以太坊上构建我们的第层,而不是其他区块链平台这就是原因。以太坊不会牺牲去中心化的原则而下沉权力在区块链方面,有一项称为可扩展性三难的基本法则。 以太坊将成为新互联网的支柱,我为什么这么说?Loom Network正在以太坊上构建我们的第2层,而不是其他区块链平台——这就是原因。 每个月都有其他的公司发布白皮书,声称已经解决了以太坊所面临的可...

    liuhh 评论0 收藏0
  • solidity语言开发智能合约中的继承

    摘要:你首先编写基本智能合约并告知你的新智能合约将从基础合约继承。这些函数和状态变量只能在内部访问即从当前合约或从中派生的合约中,而其他情况不使用它。私有函数和状态变量仅对定义它们的智能合约可见,而不是在派生合约中可见。这里是原文语言开发中的继承 我们已经探索了很多主题,在编写智能合约时我们发现经常使用相同的模式:例如,智能合约具有在构造函数中设置的所有者,然后生成修改器以便仅让所有者使用一...

    lifesimple 评论0 收藏0
  • 如何理解比特币和区块链?

    摘要:比特币区块链无疑是当今业界的最热门的。目前,每个成功的矿工获得可能每年更换一次或通过比特币社区决策作为成功向区块链添加一块交易的奖励。填写其他详细信息,例如比特币金额和可选说明。 比特币区块链无疑是当今业界的最热门的。通过这篇博客,我将尽力向大家介绍加密货币比特币的概念,以及它如何创造我们称之为区块链的革命性技术。 这个问题经常引起混淆。这篇文章可以快速解释和清理这方面的混乱! 什么是...

    Kosmos 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<