Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

只铃识
346 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-3 O, @& m/ @2 K8 Y0 ]+ P/ G7 M3 A
# w) ?2 x7 S; a  B
首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。' P- Q  J) f  f. R

4 y, u, f* b+ D* k+ J, X  }; U其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。# x$ x6 ]# A# I* @' R# ^$ i8 K1 C8 T) g% h
$ v! \: P8 n" I& b
再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。$ |: ]4 m+ h6 R' J+ t& R) X6 `

, C  F4 x; N. ?8 _5 J; Z7 ^最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。# ?+ r$ t) W$ v/ b- H: S

1 @# s0 Z2 _% U- m3 a合约创建2 F* f  n3 r, ~4 Q, a

4 @8 h3 ^1 F. e; p+ h7 B5 F这里我们用用户 A 的例子做说明。5 h/ @7 y; l# {6 ?

5 q4 W" \, ~2 m  V: ?7 K用户 A 使用 solidity 等语言创建一份合约代码
* o3 X" ~' z/ F5 s  @: E1 C5 E# n7 U! J' D1 x2 O$ K
A 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction)- V: k6 v' u( ]

7 h6 [3 L* G. w, ?% W客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。
# ]. f" O2 @: x
/ C* m* S7 @8 [8 t: }' L; t9 q该 tx 广播到网络上,B 节点收到该 tx。3 [0 |! Q/ Y: @2 G
# P1 e9 ?- e: M9 ]
B 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。$ H0 a* o- J6 C

" ^4 O+ d% x+ c对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。7 j/ ]1 l# S% r& R# Y
9 G* j; I8 N5 O2 S4 e1 b- H
合约部署* n' e; [2 k0 I; F

7 w# a/ s4 U/ X2 B5 B1 g" b6 P; c我们加入矿工B和C。
2 r% k5 Z  ~! E! y% F' w: k) v5 H! c4 M: C
-部署与挖矿过程-
1 u) U+ P5 _$ o8 `& C" U
  X/ `: f' q- T+ dB 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。0 U+ P( ?+ w% M5 H; l1 o% X1 Z6 o* o
. B9 T$ f) n* Z2 I
假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A
! i: V. R" y, Y( X; x
8 H) |; c; a& E* W1 dB 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。
) X8 l5 K3 V1 `6 @3 l, s5 v7 y% M* V% e' C
C 接收到该区块,验证区块,如果区块通过验证:/ e. h+ w$ w6 ^$ X
/ B( J2 `6 n3 {: v
a. C 从内存池中删除 A 创建的智能合约交易请求" h1 G$ x8 m7 H* |+ [
; x6 z/ |. G, f* B; r. n7 d
b. C 将区块链接到本地最长链上(同步区块)
% _+ G% y, Z+ _( N* \" W3 p. v8 w- h! A' O9 V
c. C 将 A 的智能合约部署在本地区块链中。
, k/ }" \2 f% H! `' H& \3 n) U- c
-区块验证过程-
, r8 h" H- E+ a' O
" x8 N5 D' w8 d合约执行$ N& i% c- n  N+ t5 V
5 a+ U1 A# h* C* N2 a+ N
-合约执行过程-
3 x& f7 |& m& @' L3 c% v
# u9 L! V/ R; a& F+ O1 f5 i用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。+ b& v: Z$ x( D; F% u4 B
1 s& c; o+ F0 D  L
B 同步到此交易,检查交易是否有效、格式是否正确。3 Z6 ?% J( M+ B8 z8 J2 F4 a5 @: H
# i9 v  v( o2 H  n7 v* m2 L
符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.4 X  L5 J' l3 X' O$ I9 s  y
1 _; P1 s5 }7 _
B 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。* L  Q- H2 i8 C$ e# f

2 x' w0 b" k2 L7 T# {7 E: P; wC 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。
9 l  ~5 Y( B* Z. V9 e5 }" F- }5 A
" N8 H" Y9 u+ N( C网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码/ N; l# q( p, y
+ z& {' u7 _7 [( X+ f
合约升级
+ ^/ u- G7 n' Z  M9 e: q/ Q5 `- H' k- G: Q, L8 f5 _/ t
部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)
" V" B( p. E  d5 h( [# L6 c4 O2 P, H% M; p" D4 v: X
智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。
) G6 Y. g+ r3 P( j
% g' a4 P% l5 C. I0 phacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。' ^9 o3 F0 j  C7 ^; s) n, H
1 J) u6 l0 B* G/ |
合约销毁
5 C  R  I% J& D
7 [8 W' r/ r6 ^4 h3 |合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2