以太坊黄皮书连载(四)

天露   |     |   1321 次阅读

翻译作者:Jorden Gao 邮箱:gaotl33@126.com / tianlu.jorden.gao@gmail.com
微信账号:wa713714
本文作者:Dr. Gavin Wood,以太坊&Ethcore的创始者 邮箱:GAVIN@ETHCORE.IO

公式解释说明:由于网页不默认word公式的格式,以下为公式的解释说明:
1.B_20中为下角标;
2. f
^* ((x_0,x_1,…))≡( f_ (x_0),f_ ^ (x_1),…) 中^为上角标;
3. R_u∈P ∩〖 R〗b∈B_256 中〖 〗忽略不计;
4. D(H)≡ {(D_0^ if H_i^( )=0
{ max⁡〖(D_0^ ,P(H)
(H_d^ )^ +x*ε1+ϵ) if H_i^( )<〗 N_H^( )
{max⁡(D_0^ ,P(H)_(H_d^ )^ +x*ε2+ϵ) otherwise)

中3 { 是一个大个{
若有公式疑问,建议下载原文对应公式看;再次抱歉!(等全文翻译完成,可去百度文库下载全文word形式,此word形式无公式问题)

7. 创建合约(“Contract Creation”)
当创建一个账号这里会产生大量的内部参数以一个任意字节长度数组存储,i,:发送者(s),原始交易者(o),有效的燃料(g),燃料价格(p),天赋(“endowment”)(v)和EVM的初始化和最后表现出来的信息调用/合约创建堆栈(e)的深度。
我们正式的定义这个创建函数作为一个函数Λ,用来估计它的值,并且与状态σ构成一个新的状态,剩余的燃料和产生的交易子状态(σ_ ^',g_ ^',A),在第六小结:
(81) σ_ ^',g_ ^',A≡Λ(σ,s,o,g,p,v,i,e)
这个新账号的地址被定义为仅仅包含发送者和随机数结构RLP编程Keccak哈希值的最右边160位。然后我们定义这个最后的地址给一个新的账号a:
(82) a≡B_(96..255)^ (KEC(RLP((s,σ[s]n^ -1))))
其中KEC是Keccak 256位哈希值函数,RLP是RLP编译函数,B
(a..b)^ (X)赋值到包含二进制数据X中范围为[a,b]内的位索引值,σ[x]是x地址状态,或用∅表示没有值出现。注意我们使用的是一个比发送者随机数要小的值;我们声称我们会增加发送者账号的随机数在这个交易呼叫之前,所以在这个有效的交易或者VM操作开始之前这个被用过的值则是这个发送者的随机数。
这个账号的随机数开始被定义为0,余额则为之前的值,存储空间为空和哈希代码为Keccak 256位的空字符串哈希值;当前发送者的余额同时会从之前值中被减少。因此这个变化的状态变成σ_ ^:
(83) σ_ ^
≡σ except
(84) σ_ ^* [a]≡(0,v+v_ ^',TRIE(∅),KEC(( ) ) )
(85) σ_ ^* 〖[s]〗(b )^ ≡σ ^ 〖[s]〗(b )^ -v
其中v
^'是当前账号中提前出现的值,在事件中它是事先出现的:
(86) v_ ^'≡{ (0 if σ_ ^ 〖[a]〗_ ^ =∅
{ σ_ ^ 〖[a]〗(b )^ otherwise)┤
最后,这个账号是通过执行模型(见小结9)中初始化的EVM代码i的执行被初始化。代码执行能影响几个不是在从内部到执行状态事件:当前账号的存储能被改变,未来账号能被创建和未来的信息调用能被产生。同样的,这个代码执行函数Ξ赋值到最后的状态σ
^()的数组中,有效的剩余燃料g_ ^(),当前产生的子状态A和账号o的代码本身。
(87) (σ_ ^(),g_ ^(),A,o)≡Ξ(σ_ ^*,g,I)
其中I包含这个执行环境的参数,它定义在小结9:
(88) I_( a)^ ≡ a
(89) I_( o)^ ≡ o
(90) I_( p)^ ≡ p
(91) I_( d)^ ≡( )
(92) I_( s)^ ≡ s
(93) I_( v)^ ≡ v
(94) I_( b)^ ≡ i
(95) I_e^ ≡ e
I_( d)^ 赋值到空的数字中,当做这里没有一个输入数据到这个调用中。I_H^ 没有特别的待遇而且它是从区块链中被决定。
代码执行消耗燃料,而且燃料不可能低于0,因此执行可能退出在代码已经变成一个自然完整的状态前。在这个(或几个)特例(“exception”)中我们说缺乏燃料(“out-of-gas”)已经产生:这个赋值状态是作为一个空的集合∅被定义,并且这所有创建的操作不会受到这个状态的影响,有效地离开它就像它是立即去尝试创建。
如果这个初始化代码成功地编译,一个最终的合约创建费用被消费,堆积代码c将成与创建合约全代码的大小成比例的消费:
(96) c ≡ G_codedeposit^ ×|o|
如果这里没有充足剩余燃料去支付这个费用,比如g_ ^()< c,然后我们也声明一个缺乏燃料异议。
剩余燃料将变为0在任意一个像这样的特例中,例如:如果这个创建作为一个交易收据被引导,然后它不会影响合约创建内部消耗的账单;换句话说它无论如何都必须支付。然后,这个交易的数值不是被转变成遗弃交易的地址当我们声明缺乏燃料。
如果像一个这样的特例没有出现,然后这个剩余燃料是被返回到最原始的发送者和新改变的状态是被允许保留。形式上,我们可能具体指明这个最后的状态,燃料,和子状态(σ_ ^’,g_ ^’,A):
(97) g_ ^'≡{(0 if σ_ ^()=∅
@g_ ^() if g_ ^()<c∩ H_(i )^ <N_H^
@g_ ^()-c otherwise)┤

(98) σ_ ^'≡{(σ if σ_ ^()=∅
@σ_ ^() if g_ ^()<c∩ H_(i )^ <N_H^
@σ_ ^() except:
@σ_ ^' [a](c )^ =KEC(O) otherwise)┤
在新状态σ
^'中的特例规定了o,从初始化代码执行中最后的字节顺序,具体说明了最后代码本身
是为了新创建账号。
注意区块N_H^ (家园版)的目的是成功地产生一个新的合约的能力,或者不是新的账号在没有转移这个值的情况下。在家园版之前,如果这里没有充足的燃料去支付c,则一个账号在新合约地址下将被创建伴随着所有初始化次要的影响,而且这个值会被转移,但是没有合约代码被编译。

7.1微妙(“Subtleties”).注意当这个初始化代码正在执行时,新创建的地址出现但是不会出现内部的本身代码。因此任意信息调用在这段时间内处理因为没有代码被执行。如果这个初始化执行结束于一个自杀(“SUICIDE”)指令,则这件事无意义因为这个账号将被删除在交易被完成交易之前。由于一个正常的停止(“STOP”)代码,或者如果这个返回的代码是其他空形式。然后这个状态是通过一个僵尸账号被遗弃,而且任何剩余的余额将被永远地锁定在账号中。

8.信息调用(“Message Call”)
在信息调用执行的情况下,几个参数是被要求的:发送者(s-sender),交易的创建者(o-originator),接受者(r-recipient),此账号中被执行过的代码(c-code,通常就是接受者),有效的燃料(g-gas),值(v-value),和燃料价格(p-price)与一个任意长度字节的数组(d),这个调用的输入数据和最后信息调用/合约创建当前深度的堆栈(e)。
除了赋值给一个新的状态和交易子状态,信息调用也有一个额外的元素 —— 用字节数组o表示的输出数据。这些将会被忽略当正在执行交易,然而信息调用能被初始化因为在这种情况下VM代码的执行和信息被使用。
(99) (σ_ ^(),g_ ^(),A,o)≡Θ(σ,s,o,r,c,g,p,v,v ̃,d,e)
注意我们需要从执行内容中v ̃去区分被转移的值v,为了委托调用(“DELEGATECALL”)指令。
我们定义σ(1 )^ ,将第一个交易状态作为原始的状态但是伴随从发送者到接受者的转移值:
(100) σ
(1 )^ [r](b )^ ≡σ ^ [r](b )^ +v ∩ σ(1 )^ [s](b )^ ≡σ ^ [s](b )^ -v

总体来说,当前的工作是被认为如果σ
(1 )^ [r]( )^ 最初是没有被定义,它将被创建作为一个没有代码和状态或者余额为0和随机数的账号。因此之前的等式应该会被表示为:
(101) σ
(1 )^ ≡σ(1 )^' except
(102) σ
(1 )^ [s](b )^ ≡σ ^ [s](b )^ -v

(103) and σ
(1 )^' ≡ σ_ ^ except
(104) {(σ(1 )^' [r]≡(v,0,KEC(( ) ),TRIE(∅) ) if σ ^ [r]= ∅
1^' 〖[r]〗(b )^ ≡ σ_ ^ 〖[r]〗(b )^ +v o otherwise)┤
当前账号关联的代码(定义整个Keccak哈希的碎片为σ
^ 〖[c]〗(c )^ )是依靠执行模式(见小结9)被执行。仅仅作为合约创建,如果这个执行暂停在一个特别的方式中(例如:由于一个消耗完的燃料补给,堆栈溢出,无效的跳转目的地或者无效的指令),然后没有燃料是被返回到调用者,而且这个状态是立即地被回复到这个点在余额转移之前(比如 σ ^ )。
(105) 〖σ_ ^ 〗_ ^'≡{(σ_ ^ if σ_ ^( )=∅
@σ_ ^( ) otherwise)┤
(106) (σ_ ^(),g_ ^',s,o)≡{(ΞECREC (σ(1 )^ ,g,I) if r=1
SHA256 (σ(1 )^ ,g,I) if r=2
SHA160 (σ(1 )^ ,g,I) if r=3
ID (σ(1 )^ ,g,I) if r=4
@Ξ_ (σ(1 )^ ,g,I) otherwise)┤
(107) I
( a)^ ≡r
(108) I_( o)^ ≡ o
(109) I_( p)^ ≡ p
(110) I_( d)^ ≡d
(111) I_( s)^ ≡ s
(112) I_( v)^ ≡ v ̃
(113) I_e^ ≡ e
(114) Let KEC(I_( b)^ ) ≡σ_ ^ 〖[c]〗(c )^
它是被认为它的客户将在某个点的时候已经存储这对(KEC(I
( b)^ ),I_( b)^ )数据为了去产生I_( b)^ 的可行性。
正如我们所见,这里有为了信息调用赋值的一般执行框架Ξ的四种惯用特例;他们四个被称为‘提前编译的’(‘precompiled’)合约,意思是作为一个后期可能成为与生俱来的扩展名的最初的设计成本价格。这四个合约地址分别为1,2,3,和4,且分别执行椭圆形重获公共钥匙函数(“SCREC”),SHA2 256位哈希方案,RIPEMD 160位哈希方案和一致性函数。
他们整个正式的定在是在附件E。

**
 
3 人喜欢