您的位置:首页 > 其它

账户类型、Gas和交易

2018-02-24 11:56 176 查看

说明:以太坊官方文档翻译,原文地址

http://ethereum-homestead.readthedocs.io/en/latest/contracts-and-transactions/account-types-gas-and-transactions.html

英文水平一般,有错请在留言指出,感谢!

EOA VS 合约账户

在以太坊中有两种账户

外部账户
 合约账户
但是这两种账户的区别并不是很明显。(?原句:This distinction might be eliminated in Serenity.)

外部账户(EOAs)

一个外部控制的账户中

有以太币的余额
能发送交易(以太币的转移或者是触发合约代码)
能被私钥控制
没有关联代码

合约账户

一个合约

有以太币的余额
有关联代码
有交易发生或者是从其它合约收到消息会触发代码的执行
代码执行:
       ——可以执行任意复杂度的操作(图灵完备性)
       ——可以操作它的存储状态(例如,可以拥有它自己的持久状态)
       ——可以调用其他合约
所有在以太坊区块链的动作都由外部账户引发的交易所触发的。每当合约账户收到一个交易时,它的代码就会根据交易所发送的输入参数指示的执行。合约代码将被,网络中节点上的以太坊虚拟,机验证新区块时,作为其中一部分(工作)所执行。
执行的结果还需要被确认,它(当前)还只是区块链中的一个块的上下文和它本身的数据(通俗来讲,就是说当前执行的结果还只是将执行的相关信息存储在区块链上)。区块链上的区块代表的是一个时间单元,区块链本身也是一个时间维度的东西,它由一个一个区块在离散的时间点上链接而成,代表着这些区块的所有状态的历史。
所有的以太币的余额和价值都用单位wei表示:1以太币= 1e18 wei。
ü 注意
以太坊的合约不应该被看作是“执行”或者是“编译”,相反,它们更像是一种在以太坊执行环境中的“自治代理”,总是在消息或交易发生时触发特定的代码执行,通过它们拥有的以太坊账户完成控制,并且通过他们拥有的键/值(秘钥?)来完成状态的存储。
 

什么是交易?

以太坊中的“交易”是指存储信息的签名的数据包通过区块链从一个外部账户发送到另外一个外部账户的过程。
 
一个交易交易包括:

接收者的消息
一个识别发送方和证明它们通过区块发送消息给接收者意图的签名
VALUE字段——从发送者转移到接收者的以太币(wei)的数量
一个可选字段,包括发送给合约的消息
STARTGAS值,代表交易被允许执行的计算的最大计算步骤
GASPRICE值,代表发送者愿意支付的gas值。一个单位的gas对应一个原子指令的执行,例如,一个计算步骤

什么是消息?

合约具有发送“消息”到其他合约的能力。消息是无序的虚拟的对象,它们仅仅存在于以太坊执行环境中。也可以认为它们就是函数的调用。
 
一个消息包括:

消息的发送者
 消息的接收者
VALUE字段——将消息传递到合约地址的以太币(wei)的数量
STARTGAS值,消息触发合约代码执行的最大gas值
 
本质上消息其实就像一个交易,只是它是由合约产生的而不是由外部参与者产生的。合约执行代码执行CALL或者DELEGATECALL操作码产生一个消息,CALL和DELETEGATECALL用来执行消息。和交易类似,消息会导致接收者账户执行它的代码。因此,合约可以和其他合约发生关系,就和外部账户(发生关系)一样。

什么是gas?

以太坊在区块链上实现的执行的环境叫以太坊虚拟机(EVM)。网络中的每个节点都运行EVM作为区块验证协议的一部分。通过区块中的交易列表,当交易发生时触发它们在EVM验证和执行代码。网络上的每个全节点都做着同样的计算,存储同样的值。所以,很显然以太坊并没有优化计算效率。它是一种冗余并联的并行处理。这是为了在不需要第三方系统、权威或者暴力垄断的情况下,提供一种有效的方法达成系统的共识状态。但是更重要的是,它们并不是优化计算。事实上,合约的执行是通过节点冗余复制,自然使它们(合约的执行)产生昂贵的代价,这样通常创建一个不用区块链做计算的激励可以做到offchain。
 
当你运行一个去中心化的应用程序(dapp),通过与区块链的交互来读取或者修改它的状态,但是dapps通常只为区块链共识放入关键的业务逻辑和状态。
 
当消息或交易触发合约执行时,每个指令在网络中的每个节点上都会执行。这就会有一个成本:每个操作的执行都会有一个特定的成本,用一定数量的gas单元表示。
 
Gas就是执行费用,是每个交易的发送者需要为以太坊区块链上做的每个操作支付的费用。Gas就像是汽油,驱动智能合约的执行。用以太币交易的Gas是从矿工那里的来,用来执行合约代码。Gas和以太币的故意区分开,是因为gas是由于计算有着固定的成本,而以太币的价格却常常是市场波动的结果。这两个都会由自由市场调节:gas的价格实际上有矿工决定,当一个交易的最低gas价格低于矿工挖矿的最低价格时,矿工可以拒绝处理则个交易。为了得到gas,你需要给你账户增加以太币。以太坊客户端会自动将你在交易中指定的最大支出金额换成gas。合约或者交易执行的每一步,以太坊协议都会收费,这是为了防止蓄意攻击和以太坊网络的滥用。每一个交易都包含一个gas的上限和该交易愿意为每个gas支付的费用。矿工可以选择是否确认这个交易并且收取费用。如果交易产生的计算步骤所需要的gas总量,包括处理原始消息以及其触发的任何子消息,只要小于或等于gas的限制,这个交易都会被执行。如果总的gas值超过了gas限制,所有的改变(之前的处理)将恢复,除非交易仍然有效,此情况下矿工将仍然收取费用。所有的没有被交易执行花掉的gas将以以太币的形式偿还给发送者。你不用担心超支的情况,因为你仅仅只为你消费的gas支付。这意味着设置估计之上的gas限制对发送交易的安全是非常有用的。
 

估计交易成本

一个交易的总成本(以太币)主要取决于两个因素:
gasUsed交易消费的总的gas数量
gasPrice交易中指定的一单元gas的价格(以太币)
总成本 = gasUsed*gasPrice

gasUsed

以太坊虚拟机上的每个操作都会指定需要消费多少个gas。gasUsed就是(交易或消息中)所有操作执行的总的gas数量。这里有一个电子表格(链接)提供了背后的分析。
 
为了估计gasUsed,以太坊提供了一个估计Gas的API(链接),但是这些API有一些注意事项。

gasPrice

用户可以构建和签署一个交易,每个用户都能指定他们希望的gasPrice,即使这个值是0.但是以太坊(Frontier)客户端推出的默认值gasPrice是0.05e12 唯。因为矿工想得到更多的收入,如果大多数交易提交的时候gasPrice都是0.05e12 唯,那么如果一个交易的gasPrice低于这个值或者甚至是0,就很难被执行。

交易成本的例子

让我们创建一个合约,这个合约只是对两个数进行相加。EVM的ADD操作码需要话费3gas。
 
使用默认的gas价格(2016年1月的价格)计算出来的近似成本是:
3*0.05e12 = 1.5e11唯
1以太币是1e18唯,所以总的话费就是0.00000015以太币。
 
这其实只是一种简化的估计,因为我们忽略了一些其他的成本,比如进行相加之前把两个数传给合约。
 

问题
Gas费用
Gas成本计算器
以太坊gas价格
 
操作名称
gas成本
说明
step
1
每个执行周期中的默认值
stop
0
免费
suicide
0
免费
sha3
20
 
sload
20
从永久存储中读取
sstore
100
放入永久存储中
balance
20
 
create
100
创建合约
call
20
启动一个只读调用
memory
1
扩展内存时每增加一个字
txdata
5
数据的每个字节或交易的代码
transaction
500
交易的费用基数
contract creation
53000
从homestead时从21000增加到53000
 
 

一个账户交互示例——赌博合约

如前文所述,有两种类型的账户:

外部账户:这个账户由私钥控制,如果你拥有这个账户的私钥,你就可以通过这个账户发送以太币或者是消息。
合约账户:这个账户拥有它自己的代码,并且被这个代码所控制。
 
默认情况下,以太坊执行环境是没有生命的;什么都不会发生,并且每个账户的状态都会保持一样。但是,任何用户都可以通过外部账户发送一个交易来触发一个动作的产生,从而使以太坊的车轮转动(就是指以太坊环境发生变化)。如果交易的目标是另外一个外部账户,那么交易将只是发送一些以太币而其它什么也不做。但是如果交易的目标是合约的话,那么这个合约将会激活,然后自动执行它的代码。
 
代码能够读/写它的内部存储(一个32-字节键值到32-字节数据映射的数据库),读取收到的消息的存储,并且发送消息到其它合约,然后触发它们的执行。一旦执行停止,所有被这个消息触发的子执行也会停止(一切都是按照确定和同步的顺序发生,例如在父调用做进一步操作之前需要做完子调用的所有操作),执行环境也将再次停止,直到下一次被下一个交易唤醒。
 
合约通常有四个目的:

维护一个存储数据,这不管是对其它合约来说还是外部世界来说都是非常有用的;一个例子就是一个虚拟的合约,另一个是记录特定组织中成员身份的合约。
作为拥有复杂访问策略的外部账户;也就是所谓的“代理合约(forwarding contract)”,它通常在满足某些条件的时候简单的重新传入一些消息到期望的目的地;例如,有一个代理合约,这个代理合约将一直等待直到三个私钥中有个两个确认了特定的消息,确认过后合约将重发这个消息。更复杂的代理合约在消息发送的基础上还有不同的条件。此功能最简单的一个用例就是通过一些更复杂的访问过程忽略来撤回限制。一个钱包合约就是一个很好的例子。
管理一个正在进行的合约或者是多个用户之间关系。比如,一个金融合同,某种特定介质集合的托管,或者是某种保险。你也可以有一个开放的合约,其中一部分是开放的,可以让其他任何一方任何时候来履行;例如,有一个合约自动支付奖金给那些为某些数学难题提交了有效解决方案的人,或者是能证明提供了一些计算资源的人。
为其他合约提供功能,类似于软件库。
 
合约通过“调用”或者“发送消息”来进行交互。消息是一个对象,它包括一定数量的以太币,一个任意大小的字节数组,消息的发送者和接收者。当一个合约收到一个消息,它可以选择返回一些消息原始发送者马上就能使用的数据。因此,发送消息就类似于调用一个函数。
 
因为合约能够扮演不同的角色,所以我们希望合约和不同的对象交互。举个例子,考虑这种情况,Alice和Bob用100GavCoin打赌,San Francisco明年任何时候的温度都不会超过35℃。但是Alice是一个非常有安全意识的人,因为她的初始账户用了一个代理合约(forwarding contract),只有三分之二的私钥通过才会发送消息。Bob则是个对量子密码持怀疑态度的人,所以他使用一个只能发送由Lamport签名和传统ECDSA签名处理过的消息的代理合约(forwarding contract)(因为他守旧,他喜欢用一个基于SHA256Lamport版本,但是这个版本并不能直接支持以太坊)。
 
这个赌博合约就需要从其它一些合约获取San Francisco的天气数据,同时还需要告诉GavCoin合约在需要的时候把真正的GavCoin发送给Avlice或者是Bob(更精确的说,是发送给Avlice或Bob的代理合约(forwarding contract))。我们可以用下图表示账户间的关系:
 
 


 
当Bob想结束这个打赌时,将会发生以下步骤:
1、一个交易将被发送,触发一个Bob外部账户到他的代理合约(forwarding contract)的消息。
2、Bob的代理合约发送消息的哈希值和Lamport签名给一个用来做Lamport签名校验库的合约。
3、Lamport签名校验库就会看到Bob想要一个SHA256-based的Lamport签名,所以它调用SHA256库多次来验证这个签名。
4、一旦Lamport签名校验库返回1,这就说校验成功,它就会发送消息到打赌合约。
5、打赌合约就会检查提供San Franciso 温度数据的合约,看看当前的温度是多少。
6、如果打赌合约发现温度超过35℃,那么它就发送消息给GavCoin合约,将GavCoin合约账户中的GavCoin发送Bob的代理合约。 
值得注意的是,GavCoin全部都在GavCoin合约账户的数据库中存储;步骤6中的账户是指GavCoin合约的内部会有一个以这个对赌合约地址为键,以其余额为值的数据项。当收到这个消息后,GavCoin合约会减掉一定的GavCoin,同时给Bob的代理合约地址加上这个GavCoin。我们可以在下图中看到这些步骤:
 


 

线下签名交易

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: