以太坊手续费详细分析

前言

以太坊是新兴的区块链技术平台,其目标是成为“永不停机的世界计算机”,人们在其上可以部署各种应用供全世界使用。以太币是以太坊公链这台虚拟世界计算机器运行的“燃油”(以太坊英文名Ethereum词根eum含有燃油的意思),其理念是以太坊平台运行需要消耗资源,比如各节点的CPU、存储、带宽等资源,而这些资源消耗由以太坊平台给以计量和计价,并通过挖矿时对矿工的奖励给予补偿,这种奖励同时也是以太币去中心化的发行机制。

 

一、以太坊转账手续费的特点

对资源消耗的计量和计价,在以太坊中有专有的名词,叫某笔交易的gasUsed和gasPrice。前者体现了这笔交易消耗了以太坊这台虚拟世界计算机的资源的量(比如多少CPU时间之类),后者体现了这笔交易消耗的资源的量的单位价格(比如每单位CPU时间值多少以太币)。用开车打个比方,比如你出去旅行一趟,过程消耗燃油20升,当前油价每升6元,相当于你这次旅行的燃油成本是(20升 * 6元每升 = 120元)。同样地,一笔以太坊交易的手续费,其计算公式就是:

交易手续费Fee(单位:以太) = 过程油耗gasUsed * 当前油价gasPrice

以太坊交易的手续费,有三个特点,值得注意:

  1. 手续费和转账金额无关。不像银行,转钱越多手续费越高。
  2. 手续费给谁事先是不知道的。不像银行,手续费肯定是给银行的。
  3. 费用不会固定。由于油价gasPrice的实时变化,经常是相隔几分钟的交易,其消耗的手续费都是不同的。

 

例如给4位同事转以太币,每个同事2个以太币,实际情况取截图说明。如下交易都是相隔较短时间内相继完成的。

 

  1. 交易编号:0x1ed1dbbe611cbaf6447aab61165b4d5ff49c061cad7665d6a23ec8df346412d1 (给A同事,价格10 Gwei每单位油耗)

  1. 交易编号:0x0b6e798951aa7786b6484df6e2924489af338c9dbb8c30bd64c9954e56ea55c0 (给B同事,价格7 Gwei每单位油耗)

  1. 交易编号:0x7df8116e1825c944f260e71ab8f0e00da6e45859afa7a196ebe7258656f31d60 (给C同事,价格12 Gwei每单位油耗)

  1. 交易编号:0xa9787e69f484329723dbb46b0c446f1756301c28e70929fda5f358958ebbee50 (给D同事,价格9 Gwei每单位油耗)

如上记录的发给4位同事的交易记录表明同样类型的交易但金额不同;每次油耗都一样,但是油价却不一样。看来,以太坊交易的gasPrice就像现实生活的油价,也会起起落落,取决于计算资源和交易量之间的供求关系。

 

 

  • 手续费具体的计算和扣收过程

一笔交易,手续费计算有3次,最后进行扣收。

  1. 第一次检查是交易pending的时候,这时候的手续费计算是简单看其余额是否足够支付手续费,是单个交易的模拟检查,并没有将这笔交易纳入到整个区块的整体中计算

|--JsonRpcImpl.eth_sendTransaction(CallArguments args)

|---前端新发一笔交易请求到节点时的程序入口      

|----EthereumImpl.submitTransaction(tx)

|-----节点接收到后,进行初步的数据非空检查后创建一个Transaction对象并提交

|------pendingState.addPendingTransaction(transaction)

|-------节点新建一个广播任务,将交易异步广播出去;并加入本地的待确认交易表

|--------PendingStateImpl.addPendingTransactionImpl(final Transaction tx)

|---------对该笔交易进行验证,各数据项格式是否符合要求,并起模拟环境验证        

|----------PendingStateImpl.executeTx(tx)

|-----------该处执行交易沙盒验证,因为是单笔交易验证,会创建一个假区块

|-----------假区块中无其他交易,已发生油耗也设为0,这样只校验单笔是否超标

       

2)第二次检查是区块挖出前进行模拟计算,这时候就是一个区块的整体了,除了检查账户中是否有足够支付单笔交易手续费的余额,还看区块中所有交易的手续费加起来是否超过区块的手续费总额限制,检查开始有了整体观

3)第三次检查及最后的手续费扣收,是区块挖出后的实际执行,检查限制是同第二次,但这时候是实际扣缴了,而且就算合约交易在虚拟机中执行失败,手续费是照旧扣收的

如上第2、3小点流程基本一致,区别在于执行环境是否为真,调用关系如下:

|----BlockchainImpl.createNewBlock(parent, txs, uncles, time)

|-----第2点中,创建新区块时需要模拟校验该手续费情况,沙盒执行

|----BlockchainImpl.addPendingTransaction(transaction)

|-----第3点中,区块挖矿出来后最终执行交易,扣收手续费,真实环境执行

|--------BlockchainImpl.applyBlock(repo, block)

|---------传入执行环境和当前块,对区块中的交易进行验证        

|----------for (Transaction tx : block.getTransactionsList())

|-----------对于区块中的每笔交易进行手续费的检查并执行

|-----------2、3小点区别在于前者是模拟执行环境,后者是真是执行环境

 

以太坊交易过程中有4个重要的函数,分别是:init()、execute()、go()、finalization()

(图全貌见附录)

 

 

 

对应的手续费有3个动作:

  • 事前:真正开始交易钱先检查手续费,这时候要计算一次手续费,看账户中余额是否够手续费
  • 事中:交易过程中对手续费的扣缴,因为以太坊交易分3类,普通转账,合约创建,合约执行,这3种口手续费的地方都不一样
  • 事后:最后一次计算,有手续费剩余的时候(leftover),这部分预交冻结的手续费要返回给发起者

 

注意,上述手续费检查的限制都是针对gas量,最终手续费的计算还要乘以gasPrice。

针对这部分的代码分析:

四个变量:

  1. currentBlock.getGasLimit() 动态的本区块所能消耗的gas量的限制  
  2. gasUsedInTheBlock 简单累加计算得到的本区块已经消耗的gas量 
  3. tx.getGasLimit() 复杂计算统计各个指令得到的本交易所能消耗的gas量 
  4. basicTxCost 读取配置得基本交易gas量

两个判断关系:

1)如果:(tx.getGasLimit() + gasUsedInTheBlock) > currentBlock.getGasLimit()

   则提示:Too much gas used in this block:

   业务含义是本区块已经消耗的gas,加上本交易消耗的gas如果超过了整个区块的gasLimit,就报错

2)如果:txGasLimit.compareTo(BigInteger.valueOf(basicTxCost)) < 0

   则提示:Not enough gas for transaction execution: Require: basicTxCost Got: txGasLimit

   业务含义是如果这个交易消耗的gas,太大了就超出了区块的gasLimit,如果太小了就不符合最低交易手续费的要求

 

 

  • 手续费中油耗是如何计算的

以太坊不像比特币那样,手续费统一,因为以太坊设计成可以运行智能合约,而各个智能合约其消耗的资源显然是不一样的,所以不能收统一的手续费。故而,以太坊将各种基本操作分类,评估每个细节操作的耗费,汇总起来就是一个指令的油耗

如何计算见《以太坊黄皮书》中附录,费率表:

不同种类指令有不同的费用,目前最贵的合约创建,花费32000单位的油耗,最便宜的跳转指令只要花费1单位的油耗,最贵最便宜资源消耗量相差了32000倍!

最常用的交易指令就是普通的转账交易,按下表定义是21000个单位的油耗,之前的实际操作例子也显示确实是21000单位的油耗。

 

 

  • 手续费中油价的形成机制

以太坊的油价是每时每刻在变动的,如果你打开以太坊钱包的客户端,比如Mist,打开转账界面,在未输入金额等要素的时候,钱包就已经显示了本次手续费,并随着油价的变动,页面会刷新并发生变化。

那么油价的形成机制是怎么样的呢?有点类似于股票交易所的股票报价。

首先,油价由矿工节点生成。

其次,矿工是根据待确认交易池中的交易列表,按gasPrice进行排序,考虑历史区块的影响后,最终取一个中间值并发布生成的。由于新交易不断的涌入,各交易gasPrice报价可能不同,从而产生不断变化的gasPrice报价。

|--GasPriceTracker.onBlock

|---每当一个新区块加入区块链时,就用区块中的交易的gasPrice计算更新本类参数      

|----GasPriceTracker.onTransaction

|-----该类有长度为512的价格池,每笔价格从后往前加入池,加满则循环覆盖

|------GasPriceTracker.getGasPrice

|-------另一个线程负责发布实时油价

具体如何综合价格池中价格发布一个油价,代码如下:

public long getGasPrice() {
      if (!filled) { //如果始终没有交易,则返回默认油价
          return defaultPrice;
      } else {
          if (lastVal == 0) { //若该标志为0,则重新计算油价,这标志是价格池满时设置的
            long[] longs = Arrays.copyOf(window, window.length);
            Arrays.sort(longs); //排序
            lastVal = longs[longs.length / 4];  // 取第25% percentile位置的油价
          }
          return lastVal;
      }
    }

有个专门统计以太坊油价的网站:http://ethgasstation.info/,图形化方式展示了油价变化。

 

 

  • 以太坊手续费发挥的经济调控作用

以太坊手续费不单纯是个技术问题,更是一个经济学问题。前面文章提到过,我们可以把以太坊当作一台超级计算机,而智能合约是这个计算机上运行的程序。因为这个计算机不是我们自己的,更像一台我们在网上租用的服务器,因此,我们想使用的话必须花费成本。

如果gas使用得越多,而gasPrice价格不变的话,使用以太坊搭建分布式应用的成本将会越来越高(上图等式cost越来越大)。而实际上,以太坊为了解决这个问题,特地将ether(ETH的单位)与gas进行解耦,保持gasPrice与ether的一种动态变化,使得ETH价格大幅上涨时,gasPrice价格下降(以ether计算的价格);ETH价格下跌时,gasPrice价格上升(以ether计算的价格)。这样才能使得使用以太坊的成本处于一个合理的、不会大幅波动的范围。

 

以太坊gasPrice的动态变化图:

之前以太币价格低,gasPrice相对比较高,随着以太币的升值,gasPrice价格下降,维持了以太坊运行成本保持稳定,发挥了市场的调节作用。

另外,比特币目前遇到扩容问题,因为刚开始设计时的考虑不足,比特币的手续费未能像以太坊那样进行起动态调节的机制,目前遇到交易拥堵的问题,交易体验远不如以太坊。因此比特币社区目前在讨论扩容问题。而以太坊就没有这个问题,以太坊的gasLimit可以动态调整,容纳交易的能力也可以动态扩展,如下是截稿时,最新10个区块的交易数量:

最新区块(第300多万个)的交易容纳量可以达到100级别,而比对刚开始的第13万个区块附近的交易容量和gasLimit如下:

gasLimit从3141592增长到4712394,交易容量相应增加,由此可见,以太坊自身可以动态调整容量,适应了交易量增加的需求

 

附件:以太坊交易整体过程:

 

 

 

  • 公链调用实验:为了弄清楚以太坊公链上部署合约和调用,实际上花多少钱,进行了如下真金白银的实验:

目前调用了5次,费用每次约10元人民币左右。

注:由于gasPrice等因素,每次调用花费不一样,综合同事们提供的调用费用,列举如下:

调用次数

手续费(Ether)

1

0.0058

2

0.0052

3

0.0048

4

0.0049

5

0.0079

 

目前以太坊上的合约调用活动已经比较频繁,各种合约账户达75万个(也就是有75万种合约),区块链应用呈现落地的趋势。如下是调用存证系统时,同区块的其他调用合约的交易。

 

 

 

 

 

 

 

以太坊是一个平台,它上面提供各种模块让用户来搭建应用,如果将搭建应用比作造房子,那么以太坊就提供了墙面、屋顶、地板等模块,用户只需像搭积木一样把房子搭起来,因此在以太坊上建立应用的成本和速度都大大改善。具体来说,以太坊通过一套图灵完备的脚本语言(Ethereum Virtual Machinecode,简称EVM语言)来建立应用,它类似于汇编语言。我们知道,直接用汇编语言编程是非常痛苦的,但以太坊里的编程并不需要直接使用EVM语言,而是类似C语言、Python、Lisp等高级语言,再通过编译器成EVM语言。上面所说的平台之上的应用,其实就是合约,这是以太坊的核心。合约是一个活在以太坊系统里的自动代理人,他有一个自己的以太地址,当用户向合约的地址里发送一笔交易后,该合约就被激活,然后根据交易中的额外信息,合约会运行自身的代码,最后返回一个结果,这个结果可能是从合约的地址发出另外一笔交易。需要指出的是,以太坊中的交易,不单只是发送以太而已,它还可以嵌入相当多的额外信息。如果一笔交易是发送给合约的,那么这些信息就非常重要,因为合约将根据这些信息来完成自身的业务逻辑。合约所能提供的业务,几乎是无穷无尽的,它的边界就是你的想象力,因为图灵完备的语言提供了完整的自由度,让用户搭建各种应用。白皮书举了几个例子,如储蓄账户、用户自定义的子货等。 2013年年末,以太坊创始人Vitalik Buterin发布了以太坊初版白皮书,启动了项目。2014年7月24日起,以太坊进行了为期42天的以太预售。2016年初,以太坊的技术得到市场认可,价格开始暴涨,吸引了大量开发者以外的人进入以太坊的世界。中国三大比特交易所之二的火网及OKCoin行都于2017年5月31日正式上线以太坊。 [1] 自从进入2016年以来,那些密切关注数字货产业的人都急切地观察着第二代加密货平台以太坊的发展动向。作为一种比较新的利用比特技术的开发项目,以太坊致力于实施全球去中心化且无所有权的的数字技术计算机来执行点对点合约。简单来说就是,以太坊是一个你无法关闭的世界计算机。加密架构与图灵完整性的创新型结合可以促进大量的新产业的出现。反过来,传统行业的创新压力越来越大,甚至面临淘汰的风险。比特网络事实上是一套分布式的数据库,而以太坊则更进一步,她可以看作是一台分布式的计算机:区块链是计算机的ROM,合约是程序,而以太坊的矿工们则负责计算,担任CPU的角色。这台计算机不是、也不可能是免费使用的,不然任何人都可以往里面存储各种垃圾信息和执行各种鸡毛蒜皮的计算,使用它至少需要支付计算费和存储费,当然还有其它一些费用。最为知名的是2017年初以摩根大通、芝加哥交易所集团、纽约梅隆银行、汤森路透、微软、英特尔、埃森哲等20多家全球top金融机构和科技公司成立的企业以太坊联盟。而以太坊催生的加密货以太近期又成了继比特之后受追捧的资产。  智能合约的潜在应用很多。彭博社商业周刊称它是“所有人共享但无法篡改的软件”。更高级的软件有可能用以太坊创建网络商店。区块链程序以太坊可以用来创建去中心化的程序、自治组织和智能合约,据纽约时报的报导,在2016年5月已经有数十个可用的程序。预期的应用目标涵盖金融、物联网、农田到餐桌(farm-to-table)、智能电网、体育,菠菜等。去中心化自治组织有潜力让许多原本无法运行或成本过高的营运模型成为可能。较知名的应用有:去中心化创业投资:The DAO用以太资金创立,目标是为商企业和非营利机构创建新的去中心化营业模式、The Rudimental让独立艺术家在区块链上进行群众募资。社会经济平台:Backfeed。去中心化预测市场:Augur。物联网:Ethcore(一间以太坊公司)研发的客户端、Chronicled(一间区块链公司)发表了以太坊区块链的实物资产验证平台;芯片公司、物理IP创建者和生产者可以用植入的蓝牙或近场通信进行验证。Slock.It开发的智能锁可以在付费后自动打开,让用户在付费后可以帮电动车充电、或是打开租屋的房门。虚拟宝物交易平台:FreeMyVunk。版权授权:Ujo Music平台让创作人用智能合约发布音乐,消费者可以直接付费给创作人。伊莫珍·希普用此平台发布了一首单曲。智能电网:TransActive Grid让用户可以和邻居买卖能源。去中心化期权市场:Etheropt。钉住汇率的代:DigixDAO提供与黄金挂钩的代,在2016年四月正式营运。Decentralized Capital提供和各种货挂钩的代。移动支付:Everex让外劳汇款回家乡。客户端软件以太坊的两个主要的客户端软件是Geth和Parity。企业软件企业软件公司也正测试用以太坊作为各种用途。已知有兴趣的公司包括微软、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值