Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

只铃识
232 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-0 c9 y& _0 p* r+ B
/ O; L, `% |! e
首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。. b. g2 d9 V6 o2 c# y; F

+ \3 I- z: v! W/ O, }' I" h0 T其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。8 h7 a5 g* B; u: w* m; ^* \4 B
; V* G2 |+ a) J0 ?, E
再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。6 f( x4 g; U: J- S# y
! ?; a' }* O) W  O  H
最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。
: q  r5 @5 z/ ^+ v# Q
) T5 B9 z3 \; X. B合约创建
! y: c: y4 o% M4 U
# l9 M7 s/ j8 ]- U- p& W这里我们用用户 A 的例子做说明。! Y* A; E8 @$ p7 |$ I

& o. ?/ p7 ]# u. v" N用户 A 使用 solidity 等语言创建一份合约代码8 A. v- a. I9 b( D$ Q3 }& Q
' d( Q( b& x7 E; `0 o9 H
A 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction)
( ]8 @( n) v, z! ]* {5 w7 @- h6 `9 @7 v% d
客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。
9 w! K9 L/ q, F$ U% m/ W
" Z) b2 u3 u+ r% ^# u# Q/ S该 tx 广播到网络上,B 节点收到该 tx。
  }' ]( h& B7 v: e! P% d+ M. N. c, ^+ ^* x+ O
B 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。
5 u3 m4 p) r* U5 {6 a- b5 F
: n- j- ?' Q$ z5 c对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。
4 E" Y9 n7 d# d' b; ~* B: U! A" [5 e/ N& @: |
合约部署  \1 H7 j+ z6 X# G8 x! N
# C( n5 P. x  L" {" @1 w
我们加入矿工B和C。5 N' S& Y; R2 O# Y9 x
4 Q4 j$ s. X& l. j1 ]( `
-部署与挖矿过程-( d- A) w$ r% v+ {$ k# X
# l$ m; _% I+ e9 `
B 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。
' y+ C3 k) t: T" i0 p
" p+ j/ v0 O2 h  s: S假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A
+ Z. N0 k, P& w, x: G6 u8 j0 C6 {6 u" S
B 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。' C- z4 ^" @: j2 _
( w' w- q0 f7 u) M! |0 g  x' ?
C 接收到该区块,验证区块,如果区块通过验证:' K' t0 I4 P9 J* Q" y/ {

7 d2 x5 g" c: n9 |  S$ ea. C 从内存池中删除 A 创建的智能合约交易请求
  W# ]2 ~1 j( [' ^$ {3 o2 ~
; k* c# O% w0 n3 t, V1 D9 e. ]2 I; Tb. C 将区块链接到本地最长链上(同步区块)/ p; C* |, m9 Q% h( D
" [$ i/ `* t  ]5 T" p4 A
c. C 将 A 的智能合约部署在本地区块链中。
+ F+ d1 F+ Z/ `% I; L
6 e1 C# ^. g7 V/ k) k, ^' {4 ]* R5 ^-区块验证过程-
# H& h+ U5 Y' ?4 X" v
9 T" I9 b/ N5 W: l合约执行
3 Q9 X5 z# {: Q" r8 Q! m5 Q2 R1 d7 a3 ~) o0 w
-合约执行过程-2 x8 Z" V4 g3 B, d. F" f3 D

) M! U! L& k* m用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。0 w: T7 L6 K' N7 T1 \/ d
+ Q7 d/ Q, y5 {5 m' O! j
B 同步到此交易,检查交易是否有效、格式是否正确。
, M+ U4 r8 y' s! Z5 b$ J& v+ [. |; \3 ?) ?3 w3 m" Y2 [6 ?
符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.
, h. w! Q0 M( @* k$ o2 H
7 w' {5 x2 H) V  tB 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。# P+ ^3 T0 T) [! X( g( e
! k. ]1 e. R; `% u( `$ T) l. W
C 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。% `# |: f" A2 Z, L, f0 [

3 E$ n" p6 u5 _) z+ P, i网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码' A5 q( _: D3 ~& O' P
& v9 W7 Y, k- k  I7 i2 O/ F% J
合约升级& v8 Q- @7 p4 a# Q5 i
4 R7 Y6 b& i7 R2 _% h
部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)2 Z6 S; X: J1 h: e, @/ B
5 b& N0 [: m) n; N- a: l/ e
智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。
5 g* _% ~- F* ]7 N, P3 O! I& G$ L% V1 T* |1 }
hacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。
) {& U1 c( v3 x* x$ C1 L. p: r9 p' x8 y* O9 a
合约销毁: R1 ~9 K9 `* w3 G3 x) N
4 Q- x, b; D; C: o
合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2