以太坊技术栈

以太坊的介绍

以太坊简介

以太坊(Ethereum)项目的最初目标,是打造一个运行智能合约的平台(Platform for Smart Contract)。该平台支持图灵完备的应用,按照智能合约的约定逻辑自动执行,理想情况下将不存在故障停机、审查、欺诈,以及第三方干预等问题。

以太坊平台目前支持 Golang、C++、Python 等多种语言实现的客户端。由于核心实现上基于比特币网络的核心思想进行了拓展,因此在很多设计特性上都与比特币网络十分类似。

基于以太坊项目,以太坊团队目前运营了一条公开的区块链平台——以太坊网络。智能合约开发者使用官方提供的工具和以太坊专用应用开发语言 Solidity,可以很容易开发出运行在以太坊网络上的“去中心化”应用(Decentralized Application,DApp)。这些应用将运行在以太坊的虚拟机(Ethereum Virtual Machine,EVM)里。用户通过以太币(Ether)来购买燃料(Gas),维持所部署应用的运行。

以太坊和比特币的区别

以太坊的目的是创建一种去中心化应用的协议,提供一套对大量去中心化应用程序非常有用的新方案,特别强调快速开发,对小的和少数人使用的应用也非常安全(小而使用人少的应用容易被51%攻破),以及不同应用程序之间能够有效的互动。以太坊用过建立在本质上是抽象的基础层来完成这一工作;

一个区块链其内置了图灵完备的编程语言,允许任何人编写智能合约和去中心化的应用程序,在这些应用程序中,他们可以创建任意的属于他们自己的规则、交易格式和状态转换函数。名字币的一个简单版本在以太坊可以用两行代码来编写完成,而其他协议如货币和信用系统则可以用不到 20 行的代码来构建。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上构建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量,远比特币脚本所能提供的功能强大得多;

以太坊主要特点

以太坊区块链底层也是一个类似比特币网络的 P2P 网络平台,智能合约运行在网络中的以太坊虚拟机里。网络自身是公开可接入的,任何人都可以接入并参与网络中数据的维护,提供运行以太坊虚拟机的资源。

跟比特币项目相比,以太坊区块链的技术特点主要包括:

  • 支持图灵完备的智能合约,设计了编程语言 Solidity 和虚拟机 EVM;
  • 选用了内存需求较高的哈希函数,避免出现强算力矿机、矿池攻击;
  • 叔块(Uncle Block)激励机制,降低矿池的优势,并减少区块产生间隔(10 分钟降低到 15 秒左右);
  • 采用账户系统和世界状态,而不是 UTXO,容易支持更复杂的逻辑;
  • 通过 Gas 限制代码执行指令数,避免循环执行攻击;
  • 支持 PoW 共识算法,并计划支持效率更高的 PoS 算法。

此外,开发团队还计划通过分片(Sharding)方式来解决网络可扩展性问题。

这些技术特点,解决了比特币网络在运行中被人诟病的一些问题,让以太坊网络具备了更大的应用潜力。

以太坊的核心概念

智能合约

什么是智能合约

智能合约(Smart Contract)是以太坊中最为重要的一个概念,即以计算机程序的方式来缔结和运行各种合约。最早在上世纪 90 年代,Nick Szabo 等人就提出过类似的概念,但一直依赖因为缺乏可靠执行智能合约的环境,而被作为一种理论设计。区块链技术的出现,恰好补充了这一缺陷。

以太坊支持通过图灵完备的高级语言(包括 Solidity、Serpent、Viper)等来开发智能合约。智能合约作为运行在以太坊虚拟机(Ethereum Virual Machine,EVM)中的应用,可以接受来自外部的交易请求和事件,通过触发运行提前编写好的代码逻辑,进一步生成新的交易和事件,可以进一步调用其它智能合约。

智能合约的执行结果可能对以太坊网络上的账本状态进行更新。这些修改由于经过了以太坊网络中的共识,一旦确认后无法被伪造和篡改。

只能合约作用

智能合约是在以太坊虚拟机上运行的应用程序。这是一个分布的“世界计算机”,计算能力由所有以太坊节点提供。提供计算能力的任何节点都将以Ether数字货币作为资源支付。

他们被命名为智能合约,因为您可以编写满足要求时自动执行的“合同”。

例如,想象一下在以太坊之上建立一个类似Kickstarter的众筹服务。有人可以建立一个以太坊智能合约,将资金汇集到别人身上。这个智能合约可以写成这样的话:当将100,000美元的货币添加到池中时,它将全部发送给收件人。或者,如果一个月内没有达到100,000美元的门槛,所有的货币都将被发回给货币的原始持有人。当然,这将使用以太币代替美元。

这一切都将根据智能合同代码进行,智能合同代码可自动执行交易,而无需可信任的第三方持有货币并签署交易。例如,Kickstarter在5%的付款处理费之上收取5%的费用,这意味着在$100,000的众筹项目中将收取8000到10000美元的费用。智能合约不需要向像Kickstarter这样的第三方支付费用。

智能合约可以用于许多不同的事情。开发人员可以创建智能合约,为其他智能合约提供功能,类似于软件库的工作方式。或者,智能合约可以简单地用作应用程序来存储以太坊区块链上的信息。

为了真正执行智能合同代码,有人必须发送足够的以太网代币作为交易费 - 多少取决于所需的计算资源。这为以太坊节点参与并提供计算能力付出了代价。

账户ACCOUNT

账户介绍

在之前章节中,笔者介绍过比特币在设计中并没有账户(Account)的概念,而是采用了 UTXO 模型记录整个系统的状态。任何人都可以通过交易历史来推算出用户的余额信息。而以太坊则采用了不同的做法,直接用账户来记录系统状态。每个账户存储余额信息、智能合约代码和内部数据存储等。以太坊支持在不同的账户之间转移数据,以实现更为复杂的逻辑。

具体来看,以太坊账户分为两种类型:合约账户(Contracts Accounts)和外部账户(Externally Owned Accounts,或 EOA)。

  • 合约账户:存储执行的智能合约代码,只能被外部账户来调用激活;
  • 外部账户:以太币拥有者账户,对应到某公钥。账户包括 nonce、balance、storageRoot、codeHash 等字段,由个人来控制。

在以太坊中,全网的状态是由被“账户”的对象组成的,账户之间可以直接的进行价值和信息的转移,一个以太坊的账户包含下面 4 个字段:

  • 随机数, 一个计数器,用以确保每个交易都只会被处理一次
  • 账户当前的以太币额度
  • 账户的合约代码, 如果有的话
  • 这个账户的 存储 (默认空)

合约账户外部账户之间关系

当合约账户被调用时,存储其中的智能合约会在矿工处的虚拟机中自动执行,并消耗一定的燃料。燃料通过外部账户中的以太币进行购买。

对于大多数用户来说,最基本的区别在于,用户掌握着 EOA 账号,因为用户掌握着控制 EOA 账号的私钥。而合约账号由内部程序代码来控制的,当然掌控私钥的 EOA 账户可以通过编写特定的程序代码来掌控合约账户。流行的术语“智能合约”就是合约账号中的代码,当一个交易被发送到该账户时,合约中的代码就会被执行。用户可以通过把代码部署到区块链中来创建一个新合约,也即创建了一个新的合约账户。

合约账户只有在 EOA 账户发出一个指令的时候才会去执行一个操作。所以一个合约账户是不可能自己去执行一个操作的,如生产一个随机数或执行一个 API 调用等,它只有在 EOA 账户作出确认的情况下才会去做这些事情。这是因为以太坊要求节点能够对计算的结果无论对错都达成一致,这就对操作有了一个必定会执行的要求。

从外部拥有账户到合约账户的消息会激活合约账户的代码,允许它执行各种动作。(比如转移代币,写入内部存储,挖出一个新代币,执行一些运算,创建一个新的合约等等)。

1553157948362

以太币

以太币(Ether)是以太坊网络中的货币。

以太币主要用于购买燃料,支付给矿工,以维护以太坊网络运行智能合约的费用。以太币最小单位是 wei,一个以太币等于 10^18 个 wei。

以太币同样可以通过挖矿来生成,成功生成新区块的以太坊矿工可以获得 3 个以太币的奖励,以及包含在区块内交易的燃料费用。用户也可以通过交易市场来直接购买以太币。

目前每年大约可以通过挖矿生成超过一千万个以太币,单个以太币的市场价格目前超过 300 美金。

燃料Gas

燃料(Gas),控制某次交易执行指令的上限。每执行一条合约指令会消耗固定的燃料。当某个交易还未执行结束,而燃料消耗完时,合约执行终止并回滚状态。

Gas 可以跟以太币进行兑换。需要注意的是,以太币的价格是波动的,但运行某段智能合约的燃料费用可以是固定的,通过设定 Gas 价格等进行调节。

以太坊虚拟机

以太坊是一个可编程的区块链,不仅仅是给用户一些预定义操作(如比特币只交易),以太坊允许用户创建属于他们自己的复杂的操作。以太坊作为一个平台为不同的区块链应用提供服务。

狭义来说,以太坊是一系列协议,其核心就是一个以太坊虚拟机,能执行遵守协议的任何复杂的代码。以太坊虚拟机是图灵完备的,开发者可以在虚拟机上使用像 javascript,python 这样的友好的编程语言来创建应用。

和任何的区块链一样,以太坊包含了一个点对点的网络协议。这以太坊区块链是被链接着这个网络的各个节点维护和更新的。网络中的各个节点的虚拟机都执行相同的指令来共同维护区块数据库,因为这个原因,以太坊有时候被人称为“世界计算机”。

以太坊全网的大规模并行计算不是只为了提计算效率,而是为了保证全网的数据一致性。实际上,这使得在以太网上的 运算要比传统的电脑慢的多,成本也昂贵得多。全网中的每一台虚拟机的运行都是为确保全网数据库的一致性。去中心化的一致性给全网极端的容错能力;抗审查能力和永不宕机能力等。

以太坊账户

以太坊的基本单元是账号。每一个账户都有一个 20 个字节长度的地址 。以太坊区块链跟踪每一个账号的状态,区块链上所有状态的转移都是账户之间的令牌(令牌即以太币)和信息的转移。以太坊有 2 种账户类型:

  • 外部账号,简称 EOA,是由私钥来控制的。
    • 有一个以太币的余额
    • 可以发送交易(以太币转账或者激活合约代码)
    • 通过私钥控制
    • 没有相关联的代码
  • 合约帐户,由合约代码来控制,且只能由一个 EOA 账号来操作
    • 有一个以太币余额
    • 相关联的代码
    • 代码执行是通过交易后者其他的合约发送的call来激活
    • 当被执行时 – 运行在随机复杂度(图灵完备性) – 只能操作其拥有的特定存储, 例如可以拥有其永久的state – 可以call其他合约

运行环境和语言

运行环境

以太坊采用以太坊虚拟机作为智能合约的运行环境。以太坊虚拟机是一个隔离的轻量级虚拟机环境,运行在其中的智能合约代码无法访问本地网络、文件系统或其它进程。

对同一个智能合约来说,往往需要在多个以太坊虚拟机中同时运行多份,以确保整个区块链数据的一致性和高度的容错性。另一方面,这也限制了整个网络的容量。

开发语言

以太坊为编写智能合约设计了图灵完备的高级编程语言,降低了智能合约开发的难度。

目前 Solidity 是最常用的以太坊合约编写语言之一。

智能合约编写完毕后,用编译器编译为以太坊虚拟机专用的二进制格式(EVM bytecode),由客户端上传到区块链当中,之后在矿工的以太坊虚拟机中执行。

消息和交易

以太坊交易

交易(Transaction),在以太坊中是指从一个账户到另一个账户的消息数据。消息数据可以是以太币或者合约执行参数。

名词“交易”在以太坊中是指签名的数据包,这个数据包中存储了从外部账户发送的消息,以太坊是用交易作为操作的最小单位,交易包含以下内容:

  • 消息的接受者
  • 一个可以识别发送者的签名
  • 发送方给接收方的以太币数量
  • 一个可选的数据字段
  • 一个 STARTGAS 值, 表示执行这个交易允许消耗的最大计算步骤
  • 一个 GASPRICE 值, 表示发送方的每个计算步骤的费用

前面三个是每一个加密货币都有的标准字段。默认情况下第四个数据字段没有任何功能,但是合约可以访问这里的数据;举个例子,如果一个合约是在一个区块链上提供域名注册服务的,那么它就会想把这数据字段中的数据解析成 2 个字段,第一个字段是域名,第二个字段是域名对应的 IP 地址。这个合约会从数据字段中读取这些值,然后适当把它们保存下来。

这个 STARTGAS 和 GASPRICE 字段 是以太坊的预防拒绝式攻击用的,非常重要。为了防止在代码中出现意外或敌对的无限循环或其他计算浪费,每个交易都需要设置一个限制,以限制它的计算总步骤是一个明确的值。这计算的基本单位是“汽油(gas)”; 通常,一个计算成本是一个 1 滴汽油,但是一些操作需要消耗更多的汽油,因为它们的计算成本更高。在交易数据中每一个字节需要消耗 5 滴汽油。这样做的目的是为了让攻击者为他们所消耗的每一种资源,包括计算,带宽和存储支付费用;所以消耗网络资源越多,则交易成本就越大。

交易模型

UTXO模型

UTXO 模型中,交易只是代表了 UTXO 集合的变更。而账户和余额的概念是在 UTXO 集合上更高的抽象,账号和余额的概念只存在于钱包中。

1548750482724

优点:

  1. 计算是在链外的,交易本身既是结果也是证明。节点只做验证即可,不需要对交易进行额外的计算,也没有额外的状态存储。交易本身的输出 UTXO 的计算是在钱包完成的,这样交易的计算负担完全由钱包来承担,一定程度上减少了链的负担。
  2. 除 Coinbase 交易外,交易的 Input 始终是链接在某个 UTXO 后面。交易无法被重放,并且交易的先后顺序和依赖关系容易被验证,交易是否被消费也容易被举证。
  3. UTXO 模型是无状态的,更容易并发处理。
  4. 对于 P2SH 类型的交易,具有更好的隐私性。交易中的 Input 是互不相关联的,可以使用 CoinJoin 这样的技术,来增加一定的隐私性。

缺点:

  1. 无法实现一些比较复杂的逻辑,可编程性差。对于复杂逻辑,或者需要状态保存的合约,实现难度大,且状态空间利用率比较低。
  2. 当 Input 较多时,见证脚本也会增多。而签名本身是比较消耗 CPU 和存储空间的。
ACCOUNT模型

出于智能合约的便利考虑,以太坊采用了账户的模型,状态可以实时的保存到账户里,而无需像比特币的 UXTO 模型那样去回溯整个历史。

对于 Account 模型,Account 模型保存了世界状态,链的状态一般在区块中以 StateRoot 和 ReceiptRoot 等形式进行共识。交易只是事件本身,不包含结果,交易的共识和状态的共识本质上可以隔离的。

1548761576193

优点:

  1. 合约以代码形式保存在 Account 中,并且 Account 拥有自身状态。这种模型具有更好的可编程性,容易开发人员理解,场景更广泛。
  2. 批量交易的成本较低。设想矿池向矿工支付手续费,UTXO 中因为每个 Input 和 Out 都需要单独 Witness script 或者 Locking script,交易本身会非常大,签名验证和交易存储都需要消耗链上宝贵的资源。而 Account 模型可以通过合约的方式极大的降低成本。

缺点:

  1. Account 模型交易之间没有依赖性,需要解决重放问题。
  2. 对于实现闪电网络/雷电网络,Plasma 等,用户举证需要更复杂的 Proof 证明机制,子链向主链进行状态迁移需要更复杂的协议。
UTXO和ACCOUNT区别
  1. 计算问题

    UTXO 交易本身对于区块链并没有复杂的计算,这样简单的讲其实并不完全准确,原因分有两个,一是 Bitcoin 本身的交易多为 P2SH,且 Witness script 是非图灵完备的,不存在循环语句。而对于 Account 模型,例如 Ethereum,由于计算多在链上,且为图灵完备,一般计算较为复杂,同时合约安全性就容易成为一个比较大的问题。当然是否图灵完备对于是否是账户模型并没有直接关联。但是账户模型引入之后,合约可以作为一个不受任何人控制的独立实体存在,这一点意义重大。

  2. UTXO更易并发

    在 UTXO 模型中,世界状态即为 UTXO 的集合,节点为了更快的验证交易,需要在内存中存储所有的 UTXO 的索引,因此 UTXO 是非常昂贵的。对于长期不消费的 UTXO,会一直占用节点的内存。所以对于此种模型,理论上应该鼓励用户减少生产 UTXO,多消耗 UTXO。但是如果要使用 UTXO 进行并行交易则需要更多的 UTXO 作为输入,同时要产生更多的 UTXO 来保证并发性,这本质上是对网络进行了粉尘攻击。并且由于交易是在钱包内构造,所以需要钱包更复杂的设计。反观 Account 模型,每个账户可以看成是单独的互不影响的状态机,账户之间通过消息进行通信。所以理论上用户发起多笔交易时,当这些交易之间不会互相调用同一 Account 时,交易是完全可以并发执行的。

  3. Account模型的交易重放

    Ethereum 使用了在 Account 中增加 nonce 的方式,每笔交易对应一个 nonce,nonce 每次递增。这种方式虽然意在解决重放的问题,但是同时引入了顺序性问题,同时使得交易无法并行。例如在 Ethereum中,用户发送多笔交易,如果第一笔交易打包失败,将引起后续多笔交易都打包不成功。在 CITA 中我们使用了随机 nonce 的方案,这样用户的交易之间没有顺序性依赖,不会引起串联性失败,同时使得交易有并行处理的可能。

  4. 存储问题

    因为 UTXO 模型中,只能在交易中保存状态。而 Account 模型的状态是在节点保存,在 Ethereum 中使用 MPT 的方式存储,Block 中只需要共识 StateRoot 等即可。这样对于链上数据,Account 模型实际更小,网络传输的量更小,同时状态在节点本地使用 MPT 方式保存,在空间使用上也更有效率。例如 A 向 B 转账,如果在 UTXO 中假设存在 2 个 Input 和2个 Output,则需要 2 个 Witness script 和 2 个 Locking script;在 Account 模型中则只需要一个签名,交易内容只包含金额即可。在最新的隔离见证实现后,Bitcoin 的交易数据量也大大减少,但是实际上对于验证节点和全节点仍然需要针对 Witness script 进行传输和验证。

  5. 轻节点获取地址状态难易

    例如钱包中,需要向全节点请求所有关于某个地址的所有 UTXO,全节点可以发送部分 UTXO,钱包要验证该笔 UTXO 是否已经被消费,有一定的难度,而且钱包很难去证明 UTXO 是全集而不是部分集合。而对于 Account 模型则简单很多,根据地址找到 State 中对应状态,当前状态的 State Proof 则可以证明合约数据的真伪。当然对于 UTXO 也可以在每个区块中对 UTXO 的 root 进行验证,这一点与当前 Bitcoin 的实现有关,并非 UTXO 的特点。

综上

​ 综上来看,Account 模型在可编程性,灵活性等方面更有优势;在简单业务和跨链上,UTXO 有其非常独到和开创性的优点。对于选择何种模型,要从具体的业务场景进行出发。

UTXO和ACCOUNT的对比

1553158315268

以太坊消息

合约具有发送”消息”到其他合约的能力。消息是一个永不串行且只在以太坊执行环境中存在的虚拟对象。他们可以被理解为函数调用(function calls)。

一个消息包括:

  • 明确的消息发送者
  • 消息的接收者
  • 一个可选的数据域,这是合约实际上的输入数据
  • 一个GASLIMIT值,用来限制这个消息出发的代码执行可用的最大gas数量

总的来说,一个消息就像是一个交易,除了它不是由外部账户生成,而是合约账户生成。当合约正在执行的代码中运行了CALL 或者DELEGATECALL这两个命令时,就会生成一个消息。消息有的时候也被称为”内部交易”。与一个交易类似,一个消息会引导接收的账户运行它的代码。因此,合约账户可以与其他合约账户发生关系,这点和外部账户一样。有许多人会误用交易这个词指代消息,所以可能消息这个词已经由于社区的共识而慢慢退出大家的视野,不再被使用。

以太坊状态转移函数

1548230766703

以太坊的状态转移函数 APPLY(S,TX) -> S’ 可以被定义成下面的:

  1. 检查这个交易是不是合法的 ,签名是不是合法的, 这随机数是不是匹配这个发送者的账户,
    如果答案是否定的,那返回错误。
  2. 用 STARTGAS * GASPRICE 计算交易的费用,并且从签名中确定这个发送者的地址。 从发送
    者的余额中减去费用,并且增加发送者的随机值。如果余额不够,则返回错误。
  3. 初始化 GAS = STARTGAS, 并根据这交易中的字节数拿走一定量的汽油。
  4. 把交易的值从发送的账户转移到接收者的账户。如果接收者的账户还不存在,就创建一个。
    如果这个接收者的账户是一个合约,那么就运行合约的代码直到完成,或者报汽油消耗光的
    异常。
  5. 如果值转移失败了,因为发送者没有足够多的余额,或代码执行消耗光了汽油,恢复除了支
    付的费用外的所有的状态,并且把这个费用添加到矿工的账户上。
  6. 另外,把所有剩下的汽油退还给发送者,然后把用于支付费用的汽油发送给矿工。
    举例,假设合约的代码是这样的:
    if !self.storage[calldataload(0)]:
    self.storage[calldataload(0)] = calldataload(32)
    注意,真实的合约代码是用底层的 EVM 代码编写的;这个列子是用一个叫 Serpent 的高级语言写
    的。假设这个合约的存储开始是空的,并且发送了一个交易,其中包含 10 个以太币,2000 个汽
    油,汽油价格是 0.001 比特币,和 64 字节的数据,其中 0-31 字节代表数字 2,32-63 字节代表字符
    串 CHARLIE。在这个案例中,这状态转移函数的处理如下:
  7. 检查者交易是否有效并且格式完好。
  8. 检查者交易的发送者是否至少有 2000 * 0.001 = 2 以太币。如果有,则从发送者的账户中
    减去 2 以太币。
  9. 初始化 汽油(gas)= 2000;假设这个交易是 170 个字节长度并且每个字节的费用是 5,那么
    减去 850,汽油还剩 1150。
  10. 从发送者的账户减去 10 个以太币,并且添加到合约的账户中。
  11. 运行合约的代码. 在这里例子中:检查合约的存储的第 2 个索引是否已经被使用,注意到它没
    有,然后就把这数据存储的第二个索引的值设置为 CHARLIE. 假设这个操作消耗了 187 个汽
    油,那么剩下的汽油总量是 1150 – 187 = 963
  12. 把 963 * 0.001 = 0.963 以太币加到发送者的账户,然后反正结果状态。
    如果交易的接收端没有合约,那么这总的交易费用就简单的等于汽油的价格乘以这个交易的字节长
    度,与交易一起发送的数据字段的数据将无关重要。
    注意,在恢复这个方面,消息和交易的处理方式是相同的: 如果一个消息执行消耗光了汽油,那么
    这消息的执行和其他被触发的执行都会被恢复,但是父类的执行不会恢复。

Gas的详细介绍

什么是gas

以太坊在区块链上实现了一个运行环境,被称为以太坊虚拟机(EVM)。每个参与到网络的节点都会运行都会运行EVM作为区块验证协议的一部分。他们会验证区块中涵盖的每个交易并在EVM中运行交易所触发的代码。每个网络中的全节点都会进行相同的计算并储存相同的值。合约执行会在所有节点中被多次重复,这个事实得使得合约执行的消耗变得昂贵,所以这也促使大家将能在链下进行的运算都不放到区块链上进行。对于每个被执行的命令都会有一个特定的消耗,用单位gas计数。每个合约可以利用的命令都会有一个相应的gas值。这里列了一些命令的gas消耗。

交易消耗的gas

每笔交易都被要求包括一个gas limit(或startGas)和一个交易愿为单位gas支付的费用。矿工可以有选择的打包这些交易并收取这些费用。在现实中,今天所有的交易最终都是由矿工选择的,但是用户所选择支付的交易费用多少会影响到该交易被打包所需等待的时长。如果该交易由于计算,包括原始消息和一些触发的其他消息,需要使用的gas数量小于或等于所设置的gas limit,那么这个交易会被处理。如果gas总消耗超过gas limit,那么所有的操作都会被复原,但交易是成立的并且交易费任会被矿工收取。区块链会显示这笔交易完成尝试,但因为没有提供足够的gas导致所有的合约命令都被复原。所以交易里没有被使用的超量gas都会以以太币的形式打回给交易发起者。因为gas消耗一般只是一个大致估算,所以许多用户会超额支付gas来保证他们的交易会被接受。这没什么问题,因为多余的gas会被退回给你。

区块的gas limit是由在网络上的矿工决定的。与可调整的区块gas limit协议不同的是一个默认的挖矿策略,即大多数客户端默认最小区块gas limit为4,712,388。

以太坊上的矿工需要用一个挖矿软件,例如ethminer。它会连接到一个geth或者Parity以太坊客户端。Geth和Pairty都有让矿工可以更改配置的选项。这里是geth挖矿命令行选项以及Parity的选项。

估算交易消耗

一个交易的交易费由两个因素组成:

  • gasUsed:该交易消耗的总gas数量
  • gasPrice:该交易中单位gas的价格(用以太币计算)

交易费 = gasUsed * gasPrice

gasUsed

每个EVM中的命令都被设置了相应的gas消耗值。gasUsed是所有被执行的命令的gas消耗值总和。

gasPrice

一个用户可以构建和签名一笔交易,但每个用户都可以各自设置自己希望使用的gasPrice,甚至可以是0。然而,以太坊客户端的Frontier版本有一个默认的gasPrice,即0.05e12 wei。矿工为了最大化他们的收益,如果大量的交易都是使用默认gasPrice即0.05e12 wei,那么基本上就很难又矿工去接受一个低gasPrice交易,更别说0 gasPrice交易了。

以太坊挖矿

以太坊挖矿过程

1548231579370

这以太坊的区块链和比特币的区块链有很多相似的地方,也有很多不同的地方。这个以太坊和比特币在区块链体系中最重要的不同点是 :以太坊的区块同时包含了交易列表和最近区块的状态。除此之外,2 个其他的值,区块的编号和难度值也存在在区块中。以太坊中最基本的区块验证算法如下:

  1. 检查上一个区块是否存在和其有效性。
  2. 检测这区块的时间戳,是不是比上一个区块的大,并且小于 15 分钟
  3. 检查这区块编号,难度值,交易根(transaction root) , 叔根(uncle root)和汽油限制是否有效
  4. 检查这区块的工作证明是否有效
  5. 把 S[0] 设置成上一个区块的末端的状态
  6. 让 TX 成为这区块的交易列表,如果有 n 个交易。则做 for 循环 For i in 0…n-1, 设置 S[i+1] = APPLY(S[i],TX[i]). 如果任何一个应用发生错误,或这区块中汽油的总的消耗达到了 GASLIMIT, 则返回一个错误.
  7. 让 S_FINAL 等于 S[n], 但是把支付给矿工的奖励添加到这区块里。
  8. 检查这个状态 S_FINAL 的默克尔树树根是不是和区块头信息中所提供的状态根是一样的。如果是,则区块有效,不然则无效。

乍看上去,这种方法似乎效率很低,因为它需要将整个状态存储在每个块中,但在现实中,效率应该与比特币相当。原因在于,状态存储在树结构中,并且每个块后,只需要修改树的一小部分。此外,由于所有的状态信息都是最后一个区块的一部分,所以不需要存储整个区块链的历史——这一策略,如果它可以应用于比特币,那么它的磁盘空间将节省 5-20 倍。

以太坊网络中交易会被验证这网络的节点收集起来。这些“矿工”在以太坊网络中收集、传播、验证和执行交易,然后整理归档这些交易,打包成一个区块,与别的矿工竞争将区块添加到区块链中,添加成功的矿工将收到奖励。通过这样的措施,鼓励人们为区块链全网提供更多的硬件和电力支持。

共识机制

以太坊目前采用了基于成熟的 PoW 共识的变种算法 Ethash 协议作为共识机制。

为了防止 ASIC 矿机矿池的算力攻击,跟原始 PoW 的计算密集型 Hash 运算不同,Ethash 在执行时候需要消耗大量内存,反而跟计算效率关系不大。这意味着很难制造出专门针对 Ethash 的芯片,反而是通用机器可能更加有效。

虽然,Ethash 相对原始的 PoW 进行了改进,但仍然需要进行大量无效的运算,这也为人们所诟病。

社区已经有计划在未来采用更高效的 Proof-of-Stake(PoS)作为共识机制。相对 PoW 机制来讲,PoS 机制无需消耗大量无用的 Hash 计算,但其共识过程的复杂度要更高一些,还有待进一步的检验。

刘小恺(Kyle) wechat
如有疑问可联系博主