Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

以太坊智能合约的生命周期

只铃识
272 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-
. Z; R9 K/ s0 L$ d5 G
( O# k% }  v( _; }7 `5 P首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。5 U, a, L: `- [; n* C
7 F  D& a* b9 T- ^+ o; }5 a" R
其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。
- t9 t4 |& s- o( d1 \( @+ k5 T. M( [5 r) w2 D8 o/ p
再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。4 _8 L) S. ^# S$ v" C: H, M# H
) h7 W1 g: U: W( r- a
最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。# G. w( D, S* C# C' T

! Y6 g1 n- G" i7 J$ P- M合约创建3 \/ I  T8 q: s

0 u' k1 b* G3 Z% i" d$ U这里我们用用户 A 的例子做说明。
( a. c9 a& E; D$ g  @: }
* T6 W" ]3 ]4 w5 p/ v& k1 C8 R4 X用户 A 使用 solidity 等语言创建一份合约代码$ m, ]' m% S) N6 d4 f) k6 ?
, ?; J7 {" C) _* l0 `
A 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction)
* W# ^; B3 ]4 [8 \7 C
2 [$ H( ~; u/ X客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。& Z1 J& T2 [0 t5 X$ W
. [: k  V5 d0 J$ f3 r( g: u4 F3 t
该 tx 广播到网络上,B 节点收到该 tx。# T: m7 q- N9 u; @( ~
3 [4 d6 Q! q3 `$ y) c% o( e/ b) q
B 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。
9 D3 Q2 }0 ~& |, F+ v' s* m: ~0 {3 v6 E7 S
对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。" W* a+ k$ n' [% w& r$ ^5 i0 P8 f

3 T1 j. A/ F; j7 C# g2 W6 t合约部署  ?) p; `' _# m# v* U7 u  H) x
: r+ H* n4 M- E
我们加入矿工B和C。
5 L8 h6 y' \7 A% I1 m6 n& a# o1 c" x$ R7 Y% B' |" z
-部署与挖矿过程-
! S/ g. s$ f! r0 `' D
/ i9 n( b* Y& P7 B( z6 J8 jB 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。
" }" z) }' A: E  N+ x" e$ C
6 Z0 J3 r4 s& d2 A' f. ^假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A
4 E# o+ v& s/ r6 r$ S2 _( k: s
" \& s8 s2 H9 ^B 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。- k* m; a0 Y9 H4 v! N

$ a; W# Q. o' S7 a! vC 接收到该区块,验证区块,如果区块通过验证:" o2 L2 B, N# |) U! p
9 g% a) \  |0 h( `* o
a. C 从内存池中删除 A 创建的智能合约交易请求
; B: O5 z. x- l/ J' i% E% p- j. T
b. C 将区块链接到本地最长链上(同步区块)
2 v7 s+ |: Y/ ^: `3 e
" @0 h2 B" ]! F: ]3 nc. C 将 A 的智能合约部署在本地区块链中。& e4 y& w! P" V( w! ?) i3 k6 j
& O/ A- d! }) T  e4 G& `
-区块验证过程-& l  s9 D* u+ G. N- S0 I, M# \
; E, i; {# }& g
合约执行; Z! `) s. M( ?1 H

% P& ?0 x7 c% `! h, b, g-合约执行过程-4 M8 _( Q! `! ]5 i9 f
% b( `. Y, k$ E, t' y/ \/ j
用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。
5 u: {$ X; M% Y; u/ R7 c! U( Z/ q' i2 M: Q
B 同步到此交易,检查交易是否有效、格式是否正确。2 ?$ }5 [8 J8 O6 b8 E$ U* _

6 u2 [8 ?) k$ F+ ^, U- w符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.
  [* P* O; t8 a: C* [5 k  W" Q$ T/ R3 N9 ~5 ^7 p
B 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。
0 Q* V$ d6 U5 i8 \: ~* U5 j8 |3 t3 ^1 x( j5 r# F
C 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。2 Y* L' I1 g" I- E% ^& Q
- J8 m* S. n. `) W( H* F8 V/ q! O
网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码
2 E3 N  ~* p: i. O  @$ O
& D3 D9 w) h7 X5 K5 J合约升级
1 Q) i/ v) V# F4 V% y+ _5 c& J; k- f* u+ O2 P8 @
部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)4 b) @6 ~+ g: o. @

0 V8 R1 L; T& V4 r智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。# J7 Q& T& }& Z4 G

9 _9 r; ~/ [' H/ rhacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。
+ b6 l2 }! v+ w% q5 W5 P
; S0 Q7 X" ~* c" X" b9 ~合约销毁
  \% q( s2 \' v& k. Z0 y+ g$ Z/ P# v% R: `
合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2