Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

只铃识
279 0 0
-以太坊上两种账户类型:a) 个人账户 b)合约账户-
& S; Z" z, Z/ F% N/ S( z' R  J7 Z( p0 u$ D3 @  T. I
首先,以太坊智能合约有两种类型的账户:外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。. |% n6 ^9 |% ~% I
- w+ j# G- _! q+ ?" m0 g. M2 F! _% O8 C
其次,合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户 codehash 指向的存储区域;codeHash 是代码的 hash 值,创建后不可更改。& i$ A8 H7 i' s

, f: ~/ s) D  ]再次, 数据主要存储在账户 storageRoot 指向的存储区域;storageRoot 对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。
$ G* Z6 W2 w2 q* U( m' P5 F! x% z) I) |( G
最后, 所有的基础存储目前都基于 leveldb, 一种 kv 数据库。1 U* R9 i3 i& a6 `) c
) @7 G  D2 p: j9 X
合约创建
3 E9 z% t  {3 W7 c, q! i
4 p  N5 e8 H. P+ r. P+ F  o这里我们用用户 A 的例子做说明。0 i8 S4 D: y9 {# N! Y8 j9 k

0 ~9 i1 Y) U/ Y  M/ z用户 A 使用 solidity 等语言创建一份合约代码- E* D( k: y$ o& t5 s

8 d( ?7 {( B# q/ qA 在 IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice…)填写 data,然后确认(即发起一次transaction)) I  O" o! o* \  m( K6 \# r& ~0 ^" f
. M! Y% ]( [- n5 W: B6 u
客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将 to 字段置零(代表合约创建)。
( ]1 x  j$ j! E) b5 v/ |
+ Q9 k6 Z9 w* x7 ]该 tx 广播到网络上,B 节点收到该 tx。
* z, B, F4 r; w! g/ |0 k1 B/ N
B 节点检查 tx 是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。" X. @; p+ c8 E5 C

1 E0 @2 A% N1 B% ~对于符合要求的交易请求,B 将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C 收到交易请求的节点重复用户 B 的处理过程。3 G5 n4 E% m* j9 b9 W
& c0 {% I4 {- F3 j
合约部署
: U. v" s* L) o9 t( ?; k# ~# f1 ?1 r8 z8 P2 e; ^! M7 H- F
我们加入矿工B和C。/ P. N) O7 v3 h5 p. T$ `+ V

' @* Q7 A0 V; A0 u  b, q0 \-部署与挖矿过程-
4 ^& w$ t! O# J
0 N9 F# M1 E& [3 K* o) I( kB 和 C 各自从本地的交易存储池中拿到一批 TX,然后打包进行 hash 计算(挖矿)。
2 A) K: w4 W9 V) K, Q/ S" ]/ E* K6 w- k  r5 \$ `
假设 B 挖矿成功(获得了记账权),B 会根据 A 提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的 tx 确认后返回给 A
; N, R$ q: T* f! w) m7 S$ ~" t
7 f& h+ r5 e9 p2 k, qB 打包好的区块(包含 A 创建的智能合约)发送至对等节点,并在全网传播。
# d# q+ m; F/ E# e& ~0 J9 e3 \7 I  v+ H" {
C 接收到该区块,验证区块,如果区块通过验证:6 v6 U% L8 t0 T

3 u2 _' l7 K1 m$ ua. C 从内存池中删除 A 创建的智能合约交易请求$ N0 s/ `" x& w; [; p9 l
) p& U+ w9 U$ k
b. C 将区块链接到本地最长链上(同步区块)5 `3 J* \$ q& f: O

% q- A0 Q% E2 l5 jc. C 将 A 的智能合约部署在本地区块链中。; G# x& N8 e6 R2 j& X) E# p: x

/ G% H  b, A$ }0 K) f) f9 p-区块验证过程-3 h/ s0 n# G) K2 j0 M! h
) @+ y3 j6 c# B* U# f1 v3 T
合约执行
1 K  m$ x8 R6 P9 s5 Q  |3 }( c( V9 n9 c- ^8 b7 n
-合约执行过程-, c2 }2 s/ t- G3 m3 ]2 n4 F+ w
  s3 g; N! Z( m: J3 e0 R( k
用户 A 按照一定格式在网络中发起一个 tx 请求;该请求被网络中节点 B 收到: i. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用 ii. 如果账户余额不足,则返回错误,这条交易被直接丢弃。, b$ I8 L1 s$ h0 |/ P4 z! r  e3 {

& F4 M* l; }" Y/ WB 同步到此交易,检查交易是否有效、格式是否正确。" l6 ~- m" I7 P0 L8 D! L- v  A

* P( b; P7 {; _( v$ W0 Q符合要求的交易请求,用户 B 将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.
/ n. w, G/ U1 E" W% ^
  P$ H! k- d7 F2 Z3 y) ?B 挖矿成功。 a. 对于转账交易,B 将该交易和其他交易一起打包到区块。 b. 对于合约调用交易,B 将该交易和其他交易一起打包到区块中,并在本地的 EVM 上运行合约代码: i. 如果代码并未结束而 Gas 已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。 ii. 如果代码运行结束 Gas 还有剩余,那么B只会获得消耗 的Gas×GasPrice 作为手续费,不会收取剩余 Gas 对应的手续费。 c. B 将包含 A 交易请求的区块传播到对等节点,在网络中广播。: O# i' G# e% a, i. H: w+ W

9 T/ s) g: C3 L4 z1 H; o  v4 uC 节点收到该区块后: a. 验证区块(用户A的交易的合法性也被再次验证) i. 验证通过,C 将内存池中 A 的交易请求删掉,同时将B的区块添加到本地的区块链中 ii. 验证不通过,C 丢弃该区块。 b. 执行区块中的智能合约交易 i. C 在本地的 EVM 上运行该智能合约,并与 B 的执行结果互相验证。
/ @6 t! ^+ K1 l2 }0 Z/ n
' r9 R. q6 c* T. n' B' T* V网络上其他矿工节点重复 C 的执行过程:通过 EVM 在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。 a. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码! |6 p2 b- r# k/ O* x, N1 ]

7 r7 b& Y/ o7 G/ b8 n合约升级7 U5 K$ f+ }* m" J7 {

' v) o; _  M' n* S: J9 C) M5 b6 @部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。(编者注:实际上是可以改变的。但需要)% \0 B$ p8 ?( ^0 Q

6 y2 e+ M1 t2 c+ i5 J( k智能合约升级较为困难,务必需要一次性将合约写"完美"(测试/验证要求极高)。3 t. e/ B9 {0 `) D) P$ u4 I! \
/ D/ c$ J+ c. j1 Q& s& w
hacking 办法: a. 部署一个拥有调用转发功能的智能合约 b. 将收到的调用转发到另外一个包含逻辑功能的合约地址 c. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。+ \: e/ n9 T: y! t# l2 F
1 Z- g9 \$ _  ]9 c# g6 ?2 _
合约销毁
9 E* a: _1 C. g% |  X9 n1 M: A9 Y, c* T# a0 G
合约发起者可以调用 selfdestruct() 方法即可销毁合约。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

只铃识 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    2