Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

只铃识
335 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-
0 L# K9 f9 e+ x* o  \
0 O8 d2 }  Q" i% J2 F- b1 R首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。
, w5 \7 O4 S; Y; H
1 Z1 Y" J, b5 I$ C& Z& c其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。- X& k+ O, k6 [6 K/ b

( `; p2 Y& E7 ]( A" q  }( J再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。
/ \) p& x7 [. i$ p& H0 v* E
  }( z- p( ]3 o最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。$ E) o% f2 M6 |2 e( `7 F

% c5 u) q2 S) J合约创建2 T( r$ T: X! n9 p3 H
) T) m6 F0 X4 X! C! S" [
这里我们用用户 A 的例子做说明。
. c% {. q. {* ~" F& _7 ]) v- ?& C  D8 U/ e
用户 A 使用 solidity 等语言创建一份合约代码# o$ h" z" d! }0 k

' J" l5 k, ~2 M$ IA 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction)
/ k) I, ~$ G( q& i4 J8 I: E& k7 P+ j  t6 }) [2 w
客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。; @- ]# K0 I5 E- d+ P; L
$ t. \( [" z9 ]8 V
该 tx 广播到网络上,B 节点收到该 tx。
$ T( G) d3 V- Q. y0 \( r7 L, k1 D! z" {! L) |
B 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。. O& l1 D1 ]/ _5 I  ~$ _4 z

; Q/ G6 f% }% r, j8 y1 s对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。+ g; t7 ?% \0 b

$ r* ?) s6 v; c合约部署
/ }* Y2 f$ }8 B+ S& W+ r' U3 P0 V
: ?' \1 \  ~. J4 o0 ]$ \3 f6 ^我们加入矿工B和C。
; @# s% ^% z5 [7 M2 J# L2 C7 q( c+ I; {" q  V
-部署与挖矿过程-
; M4 O. c. N4 h2 B
+ T# O. o0 J0 H) cB 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。. M  M0 m& R9 T6 I: d, H

- A5 j" ?) ~! A1 \: c5 }9 X- M. v假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A( v( E4 e. B. b
7 n4 Y2 E: W# G8 P% a1 n
B 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。
$ s8 J& N" }) r% R. z* Q8 h5 H% \  R
C 接收到该区块,验证区块,如果区块通过验证:
6 `8 E) n3 }/ m' m- K8 P$ z* G' K& Q" a; U' K
a. C 从内存池中删除 A 创建的智能合约交易请求
; A% Y: p, k3 }( e, v8 W$ a/ ^5 u, T1 {' u+ S- k
b. C 将区块链接到本地最长链上(同步区块)
2 H1 O) h/ o$ O
8 o. s( x; G+ Xc. C 将 A 的智能合约部署在本地区块链中。* {+ n; |: S# L* R

7 v2 Q" o" C* D$ g! \2 G  M5 ]-区块验证过程-
. u7 V+ ?3 k2 }& q6 J6 ]
) N! m& u: Y8 x, E/ i5 E7 ?' V0 f合约执行( b) x  B+ o+ ^# o
3 f3 _/ C( k" b- T  b9 B
-合约执行过程-
9 Q7 Z; W, `8 X$ `' m) ?* d7 b( h+ n9 d2 `  i* E" {' f- U- c
用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。
4 C, X) x1 [0 V* I! A
7 I8 @* K: e/ f5 \( i5 PB 同步到此交易,检查交易是否有效、格式是否正确。4 n' f3 Q' Q, G, d
& m9 z/ s+ N) d* `3 P
符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.
0 ]0 @: b" w5 q: o4 r+ S9 |1 _
+ e# U$ j( f, k& B7 p, iB 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。
& D0 O3 Y, i' o# z/ A+ N5 p! `: W6 Q0 Q" \9 H1 b
C 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。
" ?3 v2 k. Q$ E6 b
: i2 p- F$ B  T网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码
1 i7 c  j- q% m1 m/ M5 V$ r( j
" l2 V# v8 a# p7 f合约升级# E2 K- B2 u4 `2 Y! z: N. Q
3 Q3 w- u; `, r3 M( q9 e
部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)
: [2 I# G' n: |
$ y! p! e/ `* ?2 w4 Z/ e智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。
/ S+ W! R: G0 [2 p" B5 U! \
1 u4 y, S0 k( |  G' a7 ^hacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。
( {  N+ H9 Y# w$ ?2 `' y" c9 U+ w: G
合约销毁
" g- C6 n7 |, G, q9 T7 @/ |: t& H. B! _' o( C$ l- a% n
合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2