Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

只铃识
84 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-- M3 g8 e; P) l
, [( [, U! a9 r  j
首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。
6 Z/ H$ h, _4 D
6 i- y! v. K' b其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。
8 D0 L% L1 N: |( I. c1 T3 A6 }% J  }2 O- j! f1 @9 y
再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。9 f0 r9 g9 }. M

, t5 _- Y3 c6 X最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。
) S: x4 q! E' Q3 }, R
2 t* o! o# |. M- x8 @合约创建
3 d3 u3 t% {* }6 {. Z$ B6 n. n& \7 v8 y
这里我们用用户 A 的例子做说明。, v: W" {/ [( Z7 {6 j' B
, ^) J3 ?2 o( J. k
用户 A 使用 solidity 等语言创建一份合约代码9 y0 \4 P; Q9 k3 K" A: D
( ?- \# m8 h- o% S5 O0 T
A 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction). O' X3 H' U' J5 d% a- x
! E* e6 l( w) i7 `7 H+ n0 K& _
客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。) F( I8 q- ]5 N/ z4 E# F
, e" `: L7 h- ~9 s
该 tx 广播到网络上,B 节点收到该 tx。# e' R# P- F) E: @

2 O. ]. R. k. ?; ^% AB 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。; r7 Y: M  a& Q  O: |9 ~! l

# [1 c% `# f- s3 G对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。
  E  s& c" D  ~8 _! R  n7 o9 I3 b# Y2 O) D4 I4 V
合约部署7 O) @7 U  M4 ^5 ^; E9 N

5 r4 k3 n3 k, j. f& q我们加入矿工B和C。
! {% |( _; f; y3 y4 K# f6 u
7 k1 m2 u' ?! W$ C" O: g-部署与挖矿过程-
( i1 ~* S5 z9 g3 s, q0 m) F9 N1 d
' u+ @: W9 [3 R& \B 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。' P6 w/ v' n; J  B2 X
8 }& Y1 [) U3 `
假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A, _3 |$ j5 x% k. ^. ~3 o7 c

! Y8 N+ {2 L) Z( o8 v9 a9 {) gB 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。
. i- _5 W" U, U( `( b% _# ]" c$ I3 k( e* y2 n
C 接收到该区块,验证区块,如果区块通过验证:
# ]9 S/ B" K6 `* b' q! K+ R6 k, j6 U$ F& u
a. C 从内存池中删除 A 创建的智能合约交易请求
: Q0 T9 C) ?* J/ j# m5 U# _5 A7 f+ d6 |  c0 l6 Z
b. C 将区块链接到本地最长链上(同步区块)
- {5 S0 i! j! `+ M
0 j% v7 Z0 ?9 V# f3 n" p- R" `c. C 将 A 的智能合约部署在本地区块链中。
, |1 S. f$ O5 |% `" @3 ], |" K4 B
3 j, ]) v% m+ x: w/ M7 ~+ x-区块验证过程-3 M3 Q: h5 K6 [7 S6 r7 O9 C
$ M. c, O8 G! U' [, v
合约执行' A' }" u# s$ x2 h8 C
, k/ w: g+ d5 F6 z( q" b& L( s
-合约执行过程-
8 m' q! b: i$ c# e3 @' B" `$ B: V; u' q( Q7 d
用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。  b9 r, ?% O4 s
. }  |$ f2 F4 u- z3 l* l! F6 ^( m
B 同步到此交易,检查交易是否有效、格式是否正确。
) _4 b1 y. ~) ?" v6 _: @, p
. h; A  x- P2 y( R3 B- U/ q符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程." l4 N  v) x0 A: `

+ n' C' f) B. u- V, f& C  A$ m4 K7 _B 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。: |3 e; a* Q9 C+ N# m6 L: f/ ]

+ z- j  Q0 l8 }1 g: OC 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。! U1 e& @) p1 k3 u

5 g; @7 s! f! C网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码
. l7 `& w  L0 p- j. b. ^" B/ p( A
8 [9 R, |5 G/ A+ y+ }合约升级
* Z/ _& o" P% P. T- y7 T  x2 @+ ?7 o# Q6 f* x
部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)
2 b) P) E' p' L$ W. J2 o1 ~; K8 y% n" @  n/ x2 H
智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。
3 x* r; ?/ N6 u: E( g5 _% a$ d- k: X; U) L0 U
hacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。' b6 }6 d& q9 W9 R( D; ~; T5 u

2 M' p5 O  M& c4 T" f合约销毁1 e6 d% E3 G, S7 {5 j% H5 l" j
; T" Q% Q! W! {8 [5 A' ~
合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2