Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Yul 语言说明

一夜雨十年灯潞
298 0 0
Yul (先前被也被称为 JULIA 或 IULIA)是一种可以编译到各种不同后端的中间语言( |evm| 1.0,|evm| 1.5,而 eWASM 也在计划中)。& l# `1 p3 a" U, o" ?) E
正因为如此,它被设计成为这三种平台的可用的共同标准。
& t' n) J/ ?; I" t4 ]& g) d它已经可以用于 Solidity 内部的“内联汇编”,并且未来版本的 Solidity 编译器甚至会将 Yul 用作中间语言。 为 Yul 构建高级的优化器阶段也将会很容易。& A* z2 [" d( b( s: Q
… note::) p: _1 T( o* @+ z
请注意,用于“内联汇编”的书写风格是不带类型的(所有的都是 ``u256``),内置函数与 |evm| 操作码相同。
0 U* E8 w& o! y9 y有关详细信息,请参阅内联汇编文档。
' z4 M) J) f9 r! f* l2 mYul 的核心组件是函数,代码块,变量,字面量,for 循环,if 条件语句,switch 条件语句,表达式和变量赋值。
3 C( Q, ~0 ^+ ?7 h: LYul 是强类型的,变量和字面量都需要通过前缀符号来指明类型。支持的类型有:bool, u8, s8, u32, s32,
! J: c! K) ]8 X& qu64, s64, u128, s128, u256 和 s256。: ]+ K( H0 W, f6 d
Yul 本身甚至不提供操作符。如果目标平台是 |evm|,则操作码将作为内置函数提供,但如果后端平台发生了变化,则可以重新实现它们。! I, E" p+ n. \" ]% a, O& K
有关强制性的内置函数的列表,请参阅下面的章节。
% J2 \- l( P& I# N以下示例程序假定 |evm| 操作码 mul,div 和 mo 是原生支持或可以作为函数用以计算指数的。
2 {( B  L" \7 J8 e/ q8 }. [… code::
7 N* k! a1 N, E. s. ]8 R# A{9 L8 H  P$ }: {- r6 q, d
    function power(base:u256, exponent:u256) -> result:u256: d9 g! J6 [3 ^) p1 ^
    {5 q) d$ Y4 p% {% k( @$ \# Y7 e
        switch exponent' u4 ^% R! j' v( @
        case 0:u256 { result := 1:u256 }
) ~1 x, A) D. a# m; e        case 1:u256 { result := base }
/ k( y  [  z. `" d+ C1 c. L$ v: N        default:
6 z/ j* P% m* D* N6 k) v& H7 j        {
- j( W  r5 k) {' _            result := power(mul(base, base), div(exponent, 2:u256))! z9 u5 v, J' a& ~# Q# w( j/ ?' |, d- l, S
            switch mod(exponent, 2:u256)2 B  s' q# k: ?0 `+ v
                case 1:u256 { result := mul(base, result) }  {8 D7 t! W4 s) x5 ~  Z
        }5 m+ L# `* ?- ~, C: l
    }+ R& z* \- f" K9 y+ b- N
}2 y2 l" }$ x/ F! o1 K: C% t/ C3 l+ i" n
也可用 for 循环代替递归来实现相同的功能。这里,我们需要 |evm| 操作码 lt (小于)和 add 可用。
, i1 d  a  X5 I… code::
2 m$ A7 I$ J9 c6 \{6 @) X' P; S; d0 k6 u
    function power(base:u256, exponent:u256) -> result:u256/ w/ _# U7 g8 L$ b
    {4 ~& [$ T6 O: @  C
        result := 1:u256
7 a1 _6 D& T+ N+ `' k6 v3 z        for { let i := 0:u256 } lt(i, exponent) { i := add(i, 1:u256) }1 L+ I* ?% F0 b3 {3 r9 h6 Q  o
        {
% |3 N5 J; B+ A* m            result := mul(result, base)" d4 A1 q; x7 S" N! N6 T
        }" U+ c- Q/ |% J* S
    }9 r6 @+ _- e& r( `+ d2 ?
}; z" K1 I& k$ x
Yul 语言说明
7 j% A& H" v! `+ S本章介绍 Yul 代码。Yul 代码通常放置在一个 Yul 对象中,它将在下一节中介绍。+ q4 M7 \& I  Q. P7 G
语法::* r1 o' f& y# b" h4 V
代码块 = '{' 语句* '}'
5 Z! ^5 R' U3 _! M3 x# K+ k" s1 G语句 =
5 {: Z/ Q& t# p+ Z" v! a) a    代码块 |
+ G0 a: e) E; n5 P9 X- r: m    函数定义 |% V! X0 Y; z6 L0 J. B( X/ Z" u
    变量声明 |9 E' U. d, ?# n1 ]5 Y# K  R
    赋值 |
8 n& ]3 `* W4 k+ D" Z3 E    表达式 |1 S# u, x! b. \5 _9 i  x( P
    Switch |
; G2 |3 u" J: q7 g/ `    For 循环 |7 E0 q4 j1 o, Z
    循环中断4 T6 d! M# s/ ]* W: A4 l
函数定义 =3 x1 J! i1 p0 z+ \& B
    'function' 标识符 '(' 带类型的标识符列表? ')'
: Z0 C  \! S' ]' N1 m1 Q' J    ( '->' 带类型的标识符列表 )? 代码块% J8 G$ ]8 G: D, D4 m7 J
变量声明 =# O0 _% A" J9 s8 q0 ~! F/ H; S
    'let' 带类型的标识符列表 ( ':=' 表达式 )?
& R) Z0 s1 \" w/ K- U# n赋值 =0 u/ {8 _0 m, K  x* b/ E
    标识符列表 ':=' 表达式
. B, u" s0 L2 Y: i3 y7 J表达式 =: j; L* g5 l2 N  \6 q
    函数调用 | 标识符 | 字面量
+ Q5 z: _  T0 _* x' jIf 条件语句 =
2 q' `6 _% u+ k1 t; O6 }    'if' 表达式 代码块
6 G( q3 ]: b; K, F: R& pSwitch 条件语句 =1 P. v5 F4 i3 L: o3 ~! m# \
    'switch' 表达式 Case* ( 'default' 代码块 )?
8 n. l, Z" j6 x" Y  ECase =
5 y- h4 K1 A9 x) F2 z    'case' 字面量 代码块
8 _- C/ ~+ h- V% ^6 B8 vFor 循环 =; E( V* T$ y& t  }% X
    'for' 代码块 表达式 代码块 代码块# O7 g/ [: n" @8 ?7 n8 z; v1 @! i
循环中断 =+ u7 b3 u2 t: w  \/ K8 ~- h
    'break' | 'continue'4 w2 ~- d! X9 ]1 J! H- ^9 u
函数调用 =) u* \2 G/ j, {: i2 b
    标识符 '(' ( 表达式 ( ',' 表达式 )* )? ')'5 o4 O3 y8 O9 x% k
标识符 = [a-zA-Z_$] [a-zA-Z_0-9]*6 c' u! g/ G7 d( Z
标识符列表 = 标识符 ( ',' 标识符)*' P$ B" ]  {2 f1 D: g( Z% M; S
类型名 = 标识符 | 内置的类型名
) Y; M& M+ B: j8 Z内置的类型名 = 'bool' | [us] ( '8' | '32' | '64' | '128' | '256' )6 t# B- ~5 R) c2 t) o, ]
带类型的标识符列表 = 标识符 ':' 类型名 ( ',' 标识符 ':' 类型名 )*( U% o7 v+ E! d  }
字面量 =7 j% v3 P: \8 q! N' v# @
    (数字字面量 | 字符串字面量 | 十六进制字面量 | True字面量 | False字面量) ':' 类型名
- ~' A1 f& D6 L% d2 P数字字面量 = 十六进制数字 | 十进制数字
; ]4 H+ d0 k3 \4 v5 z0 M, v十六进制字面量 = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'')$ O; x; K5 m0 q
字符串字面量 = '"' ([^"\r\n\\] | '\\' .)* '"'$ T  U: j" |. J  {) D
True字面量 = 'true'
. P5 Z1 f5 R* n+ e, w9 e0 CFalse字面量 = 'false'
- d9 H8 q8 A- ?9 O' q& b6 S十六进制数字 = '0x' [0-9a-fA-F]+
. @( ^' `" Z7 |十进制数字 = [0-9]+
% B5 V- A4 t+ H+ P7 p" l2 X语法层面的限制
. @5 a- R+ D. z+ o8 t# \Switches 必须至少有一个 case(包括 default )。$ S6 E/ M3 X6 f5 r2 K; F; d/ X
如果表达式的所有可能值都被覆盖了,那么不应该允许使用 default
1 W6 N" S& b' f" T% x$ W) ~; m1 `" n(即带 bool 表达式的 switch 语句同时具有 true case 和 false case 的情况下不应再有 default 语句)。  h! E) P0 Y9 v5 A  b; \& X
每个表达式都求值为零个或多个值。 标识符和字面量求值为一个值,函数调用求值为所调用函数的返回值。
( `2 F3 ^2 \. T. m1 Q在变量声明和赋值中,右侧表达式(如果存在)求值后,必须得出与左侧变量数量相等的值。# ~$ o) e2 ^5 h+ J6 t; e
这是唯一允许求值出多个值的表达式。
9 V5 q6 Y. U% `那种同时又是语句的表达式(即在代码块的层次)求值结果必须只有零个值。
) o' L4 K0 p+ o在其他所有情况中,表达式求值后必须仅有一个值。
, a5 Q$ F9 G  F0 L+ N! T0 A8 fcontinue 和 break 语句只能用在循环体中,并且必须与循环处于同一个函数中(或者两者都必须在顶层)。* h1 e# P$ {" |' ]$ o
for 循环的条件部分的求值结果只能为一个值。  n, D- z0 I1 `
字面量不可以大于它们本身的类型。已定义的最大类型宽度为 256 比特。
+ e# m* s6 K- y# H作用域规则
* @& |5 N  o( D( k3 R% Y# `7 RYul 中的作用域是与块(除了函数和 for 循环,如下所述)和所有引入新的标识符到作用域中的声明! |/ y+ V1 L$ ~8 K
( FunctionDefinition ,VariableDeclaration )紧密绑定的。; F" Q& i7 b6 g
标识符在将其定义的块中可见(包括所有子节点和子块)。3 G4 |. c9 q$ o% H! q
作为例外,for 循环的 “init” 部分中(第一个块)定义的标识符在 for 循环的所有其他部分(但不在循环之外)中都是可见的。( y& r- G' b+ s; |" S  C1 K% M
在 for 循环的其他部分声明的标识符遵守常规的作用域语法规则。4 h4 E$ L' B4 u7 x
函数的参数和返回参数在函数体中可见,并且它们的名称不能相同。
) Q( M4 e0 }+ @! ?  R变量只能在声明后引用。 尤其是,变量不能在它们自己的变量声明的右边被引用。
: T0 \* F$ V* P2 D% _- M函数可以在声明之前被引用(如果它们是可见的)。
' y+ i, @  p% _1 r3 TShadowing 是不被允许的,即是说,你不能在同名标识符已经可见的情况下又定义该标识符,即使它是不可访问的。( n9 K8 q* u0 h
在函数内,不可能访问声明在函数外的变量。
7 ^' R2 d! X0 f* S9 M形式规范+ ^3 O0 f% L% J: Q2 K
我们通过在 AST 的各个节点上提供重载的求值函数 E 来正式指定 Yul。
' |3 L1 h$ p6 Y. l/ i任何函数都可能有副作用,所以 E 接受两个状态对象和 AST 节点作为它的参数,并返回两个新的状态对象和数量可变的其他值。
3 [5 z% q5 {" @" M& F这两个状态对象是全局状态对象(在 |evm| 的上下文中是 |memory|,|storage| 和区块链的状态)和本地状态对象(局部变量的状态,即 |evm| 中堆栈的某个段)。
9 I6 o3 n7 c2 I) |9 [. k6 u如果 AST 节点是一个语句,E 将返回两个状态对象和一个用于 break 和 continue 语句的 “mode”。+ [+ P# w3 U0 I2 q) P
如果 AST 节点是表达式,则 E 返回两个状态对象,并返回与表达式求值结果相同数量的值。
- M1 Y4 B; N0 D) F% |3 `" e& _; D0 {在这份高层次的描述中,并没有对全局状态的确切本质进行说明。
. P, O6 k9 d4 [6 {( K* P/ l本地状态 L 是标识符 i 到值 v 的映射,表示为 L = v。
2 S5 |8 h7 {1 r0 @% ^1 H对于标识符 v, 我们用 $v 作为标识符的名字。
+ q) S* ^& R1 o# W  D我们将为 AST 节点使用解构符号。9 d4 P" N: A1 O7 h' j5 Q) ?& l
… code::& U- w- u0 r! y$ d% C
E(G, L, : Block) =
# W) d5 ~8 Y* A7 ^* [8 A& \    let G1, L1, mode = E(G, L, St1, ..., Stn)( }( Y, X" U0 E" ^/ n/ X0 V
    let L2 be a restriction of L1 to the identifiers of L5 E# K& D% G8 k" K* z
    G1, L2, mode+ j) x7 \2 X/ u5 f8 T* {- h+ b
E(G, L, St1, ..., Stn: Statement) =2 t. _" G+ S/ q$ N: X9 }
    if n is zero:
  M" w: y  [2 _  c4 H        G, L, regular
4 m3 D: ~; |! w7 S& k1 U    else:6 k, L) _6 z/ n# S- G
        let G1, L1, mode = E(G, L, St1)5 U+ H4 L9 ~9 X
        if mode is regular then
/ W8 Y  Q3 Q1 w6 O; F            E(G1, L1, St2, ..., Stn)
3 a9 a5 w8 F% }( A; r        otherwise
0 p0 B3 k% |1 ^4 t% a4 ]- V4 C  {            G1, L1, mode  @4 b2 F; Z1 Z2 F  k) }
E(G, L, FunctionDefinition) =
2 k0 T) I- \. n5 F    G, L, regular
+ ]* m# `+ f" d/ ^& wE(G, L, : VariableDeclaration) =
  C. _8 S5 g! z0 C( K2 q! O0 @" @    E(G, L, : Assignment)
2 l$ A  z& T+ w: DE(G, L, : VariableDeclaration) =: V2 ^( q% N: N9 h
    let L1 be a copy of L where L1[$vari] = 0 for i = 1, ..., n
4 }. G) a, Z! C3 L; u* ~    G, L1, regular
* c/ c% |" K1 [2 K7 e$ rE(G, L, : Assignment) =$ ]1 o4 p6 w1 o7 p" g: Y7 S! f! w
    let G1, L1, v1, ..., vn = E(G, L, rhs)9 Q3 r" K9 o' v+ Y! r3 R# I. ~5 p
    let L2 be a copy of L1 where L2[$vari] = vi for i = 1, ..., n. Q$ m! h) O- K  @' f' T. t
    G, L2, regular: n& T$ X1 p2 s6 o
E(G, L, : ForLoop) =
) ]7 w* `; t/ Q9 ?2 I1 |  ?    if n >= 1:" P5 L9 H" J; u  Q2 h- _
        let G1, L1, mode = E(G, L, i1, ..., in)) M& d/ J, r! b8 h7 X  n& z
        // 由于语法限制,mode 必须是规则的4 J$ ?2 ^( W' ~% F' a$ ?
        let G2, L2, mode = E(G1, L1, for {} condition post body)
8 u. G, H) z9 d        // 由于语法限制,mode 必须是规则的- A$ x3 M" s/ J2 C
        let L3 be the restriction of L2 to only variables of L
$ T: \# w( k, V5 E6 V        G2, L3, regular
2 K1 j% i# z. f    else:$ H0 N- I% `3 V7 Y: a2 p0 t: W
        let G1, L1, v = E(G, L, condition)( y0 a- m# q' ]- r. @1 m) X
        if v is false:
% |. ~' E0 ?2 ~- f9 v            G1, L1, regular
7 J5 a3 p; c+ f8 P        else:$ @$ c2 k! A" X) P+ D9 m
            let G2, L2, mode = E(G1, L, body)4 R) |9 }$ g. T2 c3 A4 Z3 w
            if mode is break:
6 X9 h4 H2 A; z+ R( `$ o                G2, L2, regular
& N0 r7 C6 m" q            else:5 ~* O" |: a# e. a; c9 G
                G3, L3, mode = E(G2, L2, post)
. L1 L# [" L- ]                E(G3, L3, for {} condition post body)& e- P! W: H# ?' i( a$ f
E(G, L, break: BreakContinue) =
4 L- |5 }# I, Z) t' F7 s    G, L, break$ a$ Y$ b, y* X$ {7 r
E(G, L, continue: BreakContinue) =$ ]- o+ J' r# j5 Z1 j' @
    G, L, continue
; V9 B1 d% T+ L, N3 JE(G, L, : If) =2 x0 ~5 s$ Q, c1 Q3 X& S
    let G0, L0, v = E(G, L, condition)
7 h" i$ |" O( Z6 W" f    if v is true:. w$ G( \% |8 ~6 W: i4 `4 _  C
        E(G0, L0, body)9 q* m- a: m" P* R9 Z
    else:, X4 q+ N) P" `5 t+ u5 U+ T; r
        G0, L0, regular
0 Y5 y* O/ \( G4 q% p3 ^E(G, L, : Switch) =' h) G/ @5 P! S9 B% l
    E(G, L, switch condition case l1:t1 st1 ... case ln:tn stn default {})
- s+ c$ m4 a& H5 f2 B( n- B* ^( ~$ lE(G, L, : Switch) =
3 N% o0 t# ?  Y    let G0, L0, v = E(G, L, condition); O% O8 K" u3 d. i* K9 k$ F
    // i = 1 .. n
* [2 O7 O9 z+ y5 h2 M    // 对字面量求值,上下文无关
( f) i  |) E5 ?( u% [# ?5 C    let _, _, v1 = E(G0, L0, l1)5 B/ p. S  ?( ~7 M
    ...+ r8 x' ~! _1 J- b
    let _, _, vn = E(G0, L0, ln)
0 P+ o. m" a2 W! K9 }# Y    if there exists smallest i such that vi = v:2 Y" O$ n  a! M  A+ m. k
        E(G0, L0, sti)9 P8 X& W& l& R1 o5 S
    else:- R  h1 R# x+ d
        E(G0, L0, st')
& R& H4 T/ b4 x8 K+ B6 X5 A9 fE(G, L, : Identifier) =0 m$ m; `& N7 Y
    G, L, L[$name]
8 o1 Y- o$ O# a* \& o" l  x5 |- _3 AE(G, L, : FunctionCall) =
3 Q" Z/ l( G6 n* b' U- q' |    G1, L1, vn = E(G, L, argn)
& u' F8 t: S+ J5 I( ~- l    ...
; i' H1 f6 \6 a# u7 D: y7 ?9 k    G(n-1), L(n-1), v2 = E(G(n-2), L(n-2), arg2)2 g* s6 t  Z2 n' u- Y% u
    Gn, Ln, v1 = E(G(n-1), L(n-1), arg1)9 e& a+ M$ M# L) G/ C4 f8 u
    Let  ret1, ..., retm block>
' v' F5 i  }: x/ j    be the function of name $fname visible at the point of the call., J. l6 ~4 o2 c$ q1 d
    Let L' be a new local state such that
  p; K. {1 o& F6 r0 E    L'[$parami] = vi and L'[$reti] = 0 for all i.1 g9 n6 L/ r! d) C: {. u
    Let G'', L'', mode = E(Gn, L', block)
; ~: d# @5 R' B. Z( ]: e8 B( z    G'', Ln, L''[$ret1], ..., L''[$retm]$ c( ^3 T. s. Y& ^
E(G, L, l: HexLiteral) = G, L, hexString(l),+ i/ w5 S0 q; N7 i3 J4 m2 H1 Q
    where hexString decodes l from hex and left-aligns it into 32 bytes
' w7 W7 J- U. i/ [; B  ]E(G, L, l: StringLiteral) = G, L, utf8EncodeLeftAligned(l),
3 g' F  K4 P/ [& U: ]- p! C    where utf8EncodeLeftAligned performs a utf8 encoding of l
, Q6 ~5 C; @% d    and aligns it left into 32 bytes
/ E  N' [0 ?: w  B$ K7 i# cE(G, L, n: HexNumber) = G, L, hex(n)$ N# `1 h% a# o/ `3 c
    where hex is the hexadecimal decoding function
7 l5 E+ S2 @/ c$ `, k+ @5 h  fE(G, L, n: DecimalNumber) = G, L, dec(n),
, f) a4 F: Q) ~' T7 k    where dec is the decimal decoding function7 i1 i: B4 a$ h% J# \' m( I
类型转换函数& b) |# |. S. `, Q; t% W9 `
Yul 不支持隐式类型转换,因此存在提供显式转换的函数。
( w$ Y' R7 y- C在将较大类型转换为较短类型时,如果发生溢出,则可能会发生运行时异常。" Z3 G% |# N9 E( X5 ?
下列类型的“截取式”转换是允许的:8 B* \- R3 T3 i  b' t  r$ T
  • bool
  • u32
  • u64
  • u256
  • s256% \7 d. y; F# D" G( t
    5 C/ X- Z' g; W  b0 z: F/ @( J* K. K
    这里的每种类型的转换函数都有一个格式为 to(x:) -> y: 的原型,& N) o3 t8 h, b$ s/ h: A% y5 _! |7 G
    比如 u32tobool(x:u32) -> y:bool、u256tou32(x:u256) -> y:u32 或 s256tou256(x:s256) -> y:u256。
    7 T" m* i( u9 }* ]; i1 v  q… note::
    $ Y/ @  H7 G( p* ]``u32tobool(x:u32) -> y:bool`` 可以由 ``y := not(iszerou256(x))`` 实现,并且0 T* K6 i% ]; P1 T
    ``booltou32(x:bool) -> y:u32`` 可以由 ``switch x case true:bool { y := 1:u32 } case false:bool { y := 0:u32 }`` 实现7 f& p0 o1 H; h. S6 E! C
    低级函数
    7 B6 y' Y, c8 X) G, v* }4 N以下函数必须可用:
    4 l; _) r- K0 ^& U±--------------------------------------------------------------------------------------------------------------+
    + W& A* K: F9 O, `  S! }| 逻辑操作                                                                                                    |
    7 d, B( m- l, y4 ^8 |8 j±--------------------------------------------±----------------------------------------------------------------+
    & y; H3 I# ]* I; Q| not(x:bool) -> z:bool                       | 逻辑非                                                          |% v# U- h+ k9 H2 l
    ±--------------------------------------------±----------------------------------------------------------------+
    8 T8 f5 v8 p8 F" g! R8 H| and(x:bool, y:bool) -> z:bool               | 逻辑与                                                          |3 k6 z3 p5 {3 L) Z. ?% ^
    ±--------------------------------------------±----------------------------------------------------------------+- a/ _# e8 @+ |2 U" A
    | or(x:bool, y:bool) -> z:bool                | 逻辑或                                                          |
    & Y# M! n2 O' P, ~3 M& L±--------------------------------------------±----------------------------------------------------------------+
    1 h6 ~. H1 z/ a* w2 e5 w6 E( I| xor(x:bool, y:bool) -> z:bool               | 异或                                                            |+ G4 g9 a% _3 }: _9 _' n9 K5 t* \/ ^
    ±--------------------------------------------±----------------------------------------------------------------+
    * Z  P: O, `  L* g4 S: ~0 ~9 t! S| 算术操作                                                                                                    |) Z' ~1 h8 |, ?# x6 z
    ±--------------------------------------------±----------------------------------------------------------------+* Z2 N  @. O) l
    | addu256(x:u256, y:u256) -> z:u256           | x + y                                                           |
    - j* |- E  C1 z$ \. E! p5 P' ~±--------------------------------------------±----------------------------------------------------------------+
    # d, Q  f! `9 v6 N" ^| subu256(x:u256, y:u256) -> z:u256           | x - y                                                           |
    6 g  X1 }5 Y# c+ {6 U±--------------------------------------------±----------------------------------------------------------------+: g" M( L2 y: E  c6 P8 q2 W! @# }1 M; |4 Y
    | mulu256(x:u256, y:u256) -> z:u256           | x * y                                                           |3 I$ ^  m0 N* t6 N5 t9 D, u9 r
    ±--------------------------------------------±----------------------------------------------------------------+$ ^% [% @4 I! g; O% p+ E( z6 l9 F% _3 G
    | divu256(x:u256, y:u256) -> z:u256           | x / y                                                           |6 o$ S; v  ^9 D6 t8 `) {
    ±--------------------------------------------±----------------------------------------------------------------+
    ( G5 z8 U, w0 ?: _0 t% E| divs256(x:s256, y:s256) -> z:s256           | x / y, 有符号数用补码形式                                       |/ G4 `* c! W& z+ _: H
    ±--------------------------------------------±----------------------------------------------------------------+
    1 ?! e, m( g2 p5 Z/ A| modu256(x:u256, y:u256) -> z:u256           | x % y                                                           |! V7 @! z3 K2 V% m# ^5 G3 ?5 k
    ±--------------------------------------------±----------------------------------------------------------------+
      y& N' N" v5 U4 u( f* v7 V| mods256(x:s256, y:s256) -> z:s256           | x % y, 有符号数用补码形式                                       |
    4 S2 }7 t7 X# u. j2 E. j8 K±--------------------------------------------±----------------------------------------------------------------+
    3 g* |( k& T$ O! G6 Q# V| signextendu256(i:u256, x:u256) -> z:u256    | 从第 (i*8+7) 位开始进行符号扩展,从最低符号位开始计算           |
    % k( p( ~, L: H" k, w±--------------------------------------------±----------------------------------------------------------------+
    $ B, s2 n5 V7 G& ^, y2 R| expu256(x:u256, y:u256) -> z:u256           | x 的 y 次方                                                     |
    1 H2 X: U9 a( p±--------------------------------------------±----------------------------------------------------------------+
    6 D7 ]0 U. y$ y4 ~5 r" ~| addmodu256(x:u256, y:u256, m:u256) -> z:u256| 任意精度的数学模运算 (x + y) % m                                |1 t' r$ k; N- t0 l
    ±--------------------------------------------±----------------------------------------------------------------+
    ' o/ E9 @$ ^& x* Y0 o' n1 v( P" Y| mulmodu256(x:u256, y:u256, m:u256) -> z:u256| 任意精度的数学模运算 (x * y) % m                                |4 \' H% Z- n' s
    ±--------------------------------------------±----------------------------------------------------------------+
    ) f) q- ]+ o: w| ltu256(x:u256, y:u256) -> z:bool            | 若 x  z:bool            | 若 x > y 为 true, 否则为 false                                  |
    1 E( I- ?% ?4 q& i1 M±--------------------------------------------±----------------------------------------------------------------+
    ) g7 A' t, j( n# X4 }, z% ~: N| sltu256(x:s256, y:s256) -> z:bool           | 若 x  z:bool           | 若 x > y 为 true, 否则为 false                                  |" u! A6 A9 g$ F3 b% |' k/ ^9 ?; ^9 W. }
    |                                             | 有符号数用补码形式                                              |1 A) B6 O7 A' F$ H  x
    ±--------------------------------------------±----------------------------------------------------------------+7 i( z$ s5 Z5 J! J' D( }  c
    | equ256(x:u256, y:u256) -> z:bool            | 若 x == y 为 true, 否则为 false                                 |% j4 |* `2 x+ c8 w! z
    ±--------------------------------------------±----------------------------------------------------------------+" e* E4 T- J' w' e
    | iszerou256(x:u256) -> z:bool                | 若 x == 0 为 true, 否则为 false                                 |
    7 q; [+ a: J) Z' U- j( @±--------------------------------------------±----------------------------------------------------------------+5 k6 |7 L; t2 K5 r, A/ h, c: t
    | notu256(x:u256) -> z:u256                   | ~x, 对 x 按位非                                                 |
    : E: [2 }7 V$ S$ {2 P5 h±--------------------------------------------±----------------------------------------------------------------+9 j6 P$ [. [& A3 b9 R+ w$ \0 N
    | andu256(x:u256, y:u256) -> z:u256           | x 和 y 按位与                                                   |% ?3 J# u7 d! Z* E( v" i" ?; s5 R6 w: B. V
    ±--------------------------------------------±----------------------------------------------------------------+
    0 w5 ^$ `7 X, N4 c1 p| oru256(x:u256, y:u256) -> z:u256            | x 和 y 按位或                                                   |9 \7 D& Y% v/ ^5 V$ R, J
    ±--------------------------------------------±----------------------------------------------------------------+
    * Q; K: s. q2 ]| xoru256(x:u256, y:u256) -> z:u256           | x 和 y 按位异或                                                 |9 x% W- C# Z# l& c  V1 p
    ±--------------------------------------------±----------------------------------------------------------------+; @5 Y' P2 D" z& F
    | shlu256(x:u256, y:u256) -> z:u256           | 将 x 逻辑左移 y 位                                              |
      A- C5 E' ~: p1 G3 x0 X±--------------------------------------------±----------------------------------------------------------------+
    : o: m2 n0 q8 z. j& Q! R| shru256(x:u256, y:u256) -> z:u256           | 将 x 逻辑右移 y 位                                              |) @% H7 F7 r$ t
    ±--------------------------------------------±----------------------------------------------------------------+
    ! O" W0 ]0 {! L5 g5 U/ T| saru256(x:u256, y:u256) -> z:u256           | 将 x 算术右移 y 位                                              |/ q+ {  E$ g2 W( A- B) C: y7 D& ?
    ±--------------------------------------------±----------------------------------------------------------------+& P* Z7 g/ f9 M, W0 L% b* s: }( b5 ?
    | byte(n:u256, x:u256) -> v:u256              | x 的第 n 字节,这里的索引位置是从 0 开始的;                    |, a5 p% s( h' y, n6 d* [
    |                                             | 能否用 and256(shr256(n, x), 0xff) 来替换它,                    |: o* B4 A  `2 ]5 r( k" i
    |                                             | 并使它在 EVM 后端之外被优化呢?                                 |& r, {. |0 `* J% \
    ±--------------------------------------------±----------------------------------------------------------------+  O5 [) u) B5 V: h, f; n6 y
    | 内存和存储                                                                                                  |8 @/ l1 w& ?) E' ?! P$ l( g) @8 R
    ±--------------------------------------------±----------------------------------------------------------------+: S- Q( w! @* e' u2 ?6 }
    | mload(p:u256) -> v:u256                     | mem[p…(p+32))                                                  |0 C6 m" Y8 ^2 u: e
    ±--------------------------------------------±----------------------------------------------------------------+
    2 f+ W4 y, u3 q6 W( G| mstore(p:u256, v:u256)                      | mem[p…(p+32)) := v                                             |
    6 O9 |! C' W" f4 H# `±--------------------------------------------±----------------------------------------------------------------+
    " @$ z/ A9 J6 x; M: n$ r| mstore8(p:u256, v:u256)                     | mem := v & 0xff    - 仅修改单个字节                          |
    4 Y: B) O# ^! v$ d9 ~) @2 H5 f±--------------------------------------------±----------------------------------------------------------------+
    . s3 }2 D( E7 @: _- f; J| sload(p:u256) -> v:u256                     | storage                                                      |/ B9 m$ y0 x% Q4 @( F3 n1 z- ^
    ±--------------------------------------------±----------------------------------------------------------------+
    3 i8 Y# [% ?$ H/ n4 h/ d| sstore(p:u256, v:u256)                      | storage := v                                                 |( L. }; \. v- T" E) z
    ±--------------------------------------------±----------------------------------------------------------------+6 |9 a  J% ]0 f# [  }8 H5 q" H$ m* l
    | msize() -> size:u256                        | 内存的大小, 即已访问过的内存的最大下标,                        |
    9 C* d6 L, |8 X8 ^* F/ G: ||                                             | 因为内存扩展的限制(只能按字进行扩展)                          |0 n6 O+ r' J: g2 G% \- s6 f
    |                                             | 返回值永远都是 32 字节的倍数                                    |
    ; ^5 ?! _1 z) p' }1 N±--------------------------------------------±----------------------------------------------------------------+
    * |- P1 j5 z7 @' d5 `* P| 执行控制                                                                                                    |
    & v% r! Y: m) ~2 c  M6 x±--------------------------------------------±----------------------------------------------------------------+
      [2 V7 c; W6 J3 L* w" E% \| create(v:u256, p:u256, s:u256)              | 以 mem[p…(p+s)) 上的代码创建一个新合约,发送                   |
    + {# W2 P' Z6 X2 p|                                             | v 个 wei,并返回一个新的地址                                    |* B2 L1 [+ N+ _5 F! f( ^7 v9 r1 z
    ±--------------------------------------------±----------------------------------------------------------------+
    % }, T: w) p1 Q+ x6 T| call(g:u256, a:u256, v:u256, in:u256,       | 调用地址 a 上的合约,以 mem[in…(in+insize)) 作为输入           |
    8 x9 f( k. I: S| insize:u256, out:u256,                      | 一并发送 g gas 和 v wei ,以 mem[out…(out+outsize))            |
    + S5 q+ c% b! I| outsize:u256)                               | 作为输出空间。若错误,返回 0 (比如,gas 用光                   |7 }! S( N' i# M
    | -> r:u256                                   | 成功,返回 1                                                    |
    ' t$ @( M4 k) E$ I. [2 j±--------------------------------------------±----------------------------------------------------------------+
    - Y9 v1 b6 m9 ?3 a| callcode(g:u256, a:u256, v:u256, in:u256,   | 相当于 call 但仅仅使用地址 a 上的代码,                     |
    6 z3 a; r  D& q9 D5 }' `| insize:u256, out:u256,                      | 而留在当前合约的上下文当中                                      |
      H7 M; U' b% R2 G3 }, J+ P# v6 h0 e| outsize:u256) -> r:u256                     |                                                                 |
    $ q, y/ w( y9 l& N1 ~±--------------------------------------------±----------------------------------------------------------------+( a. g3 V2 b2 N* F* E5 g! ], n
    | delegatecall(g:u256, a:u256, in:u256,       | 相当于 callcode,                                           |. Z+ ^. w  d) {( b. i# J0 i2 ?
    | insize:u256, out:u256,                      | 但同时保留 caller                                           |7 S2 t7 q& \* I+ p- Q# K9 `9 |
    | outsize:u256) -> r:u256                     | 和 callvalue                                                |
    8 H/ R% A* Z, [4 F0 `+ n  ~0 w4 [±--------------------------------------------±----------------------------------------------------------------+9 K7 ]8 Q( V: Q* A! v( W
    | abort()                                     | 终止 (相当于EVM上的非法指令)                                    |# i! b- I' c! C7 R/ H
    ±--------------------------------------------±----------------------------------------------------------------+% i. m- y2 t) S. X
    | return(p:u256, s:u256)                      | 终止执行,返回 mem[p…(p+s)) 上的数据                           |
    - A$ Y& w/ s4 x$ g/ W: o4 x±--------------------------------------------±----------------------------------------------------------------+" ]% l! B" o" u! B" ], E. @- O
    | revert(p:u256, s:u256)                      | 终止执行,恢复状态变更,返回 mem[p…(p+s)) 上的数据             |7 k; B7 n( a" a) d: L' I8 A  s
    ±--------------------------------------------±----------------------------------------------------------------+
    ' u5 A5 H% X4 Y3 t' Y| selfdestruct(a:u256)                        | 终止执行,销毁当前合约,并且将余额发送到地址 a                  |
    5 D; _* W( X7 C  D& l±--------------------------------------------±----------------------------------------------------------------+
    & I" |: H  z1 n( r# ]" D| log0(p:u256, s:u256)                        | 用 mem[p…(p+s)] 上的数据产生日志,但没有 topic                 |
    9 |- g! E" \1 `$ A! c±--------------------------------------------±----------------------------------------------------------------+
    & Z# o) Z& u6 T% Y: T| log1(p:u256, s:u256, t1:u256)               | 用 mem[p…(p+s)] 上的数据和 topic t1 产生日志                   |9 p5 k+ C5 Z9 Y) F' q8 O
    ±--------------------------------------------±----------------------------------------------------------------+  C# p0 d6 g8 }" \, B# @& B) f
    | log2(p:u256, s:u256, t1:u256, t2:u256)      | 用 mem[p…(p+s)] 上的数据和 topic t1,t2 产生日志               |+ Z% M! D8 u% |* R2 n
    ±--------------------------------------------±----------------------------------------------------------------+
    . R  w, V8 {; N7 ^" s, f: y. u# u| log3(p:u256, s:u256, t1:u256, t2:u256,      | 用 mem[p…(p+s)] 上的数据和 topic t1,t2,t3 产生日志           |/ Y% D/ c8 [( S# C! ?. k
    | t3:u256)                                    |                                                                 |
    ) C7 r: \4 Y& Z- n4 W  F6 O, Z& b- N7 T±--------------------------------------------±----------------------------------------------------------------+9 E  S" c5 b( W+ h3 g
    | log4(p:u256, s:u256, t1:u256, t2:u256,      | 用 mem[p…(p+s)] 上的数据和 topic t1,t2,t3,t4                |8 c1 u4 F8 C  G
    | t3:u256, t4:u256)                           | 产生日志                                                        |0 o: L" n( @* H( ~
    ±--------------------------------------------±----------------------------------------------------------------+5 P' ~, l. C& w" C! j3 l
    | 状态查询                                                                                                    |
    " b) N- y0 K  s0 E9 Z±--------------------------------------------±----------------------------------------------------------------+
    1 P$ ~4 ^3 |8 f, T, P1 b  S. S| blockcoinbase() -> address:u256             | 当前的矿工                                                      |
    . r8 k! ]5 f/ r3 I( |' y4 {±--------------------------------------------±----------------------------------------------------------------+
    7 ~+ ^$ r' p* w, c5 N4 w. b2 Y| blockdifficulty() -> difficulty:u256        | 当前区块的难度                                                  |
    $ ?# ]5 F0 O) A' G. F/ v±--------------------------------------------±----------------------------------------------------------------+; _% N7 Y3 e; l& y$ K
    | blockgaslimit() -> limit:u256               | 当前区块的区块 gas 限制                                         |% t' T# B* F" B) P' R) N: x
    ±--------------------------------------------±----------------------------------------------------------------+
      n8 L0 ?8 y  E' ]! L# b- s| blockhash(b:u256) -> hash:u256              | 区块号为 b 的区块的哈希,                                       |
    # x- n* f5 H2 D3 G: i) X& W6 O|                                             | 仅可用于最近的 256 个区块,不包含当前区块                       |6 ]4 h( b. ~# v! t+ R! Z1 K( w; m
    ±--------------------------------------------±----------------------------------------------------------------+
    * \! Q( V5 S! d9 x1 z5 A. L| blocknumber() -> block:u256                 | 当前区块号                                                      |
    : _$ J- X( a7 k±--------------------------------------------±----------------------------------------------------------------+
    ( [! V' g  p* [7 d/ i+ o( q! Y# o| blocktimestamp() -> timestamp:u256          | 自 epoch 开始的,当前块的时间戳,以秒为单位                     |
    # {1 J! k2 z1 f( s; @7 w±--------------------------------------------±----------------------------------------------------------------+
    / m8 A8 q# g  {* Y( D4 k7 ]! o| txorigin() -> address:u256                  | 交易的发送方                                                    |& Y0 x; ]4 ]$ x; j* x# W
    ±--------------------------------------------±----------------------------------------------------------------+
    : t  [# O* _  g" H| txgasprice() -> price:u256                  | 交易中的 gas 价格                                               |! y# j2 S. z: f  ^) P& m
    ±--------------------------------------------±----------------------------------------------------------------+. s2 x9 [: N- x- s+ z: e  O+ T
    | gasleft() -> gas:u256                       | 还可用于执行的 gas                                              |
    + z/ F* V' s! {' ^1 B9 `: [±--------------------------------------------±----------------------------------------------------------------+
    6 C, n3 U. S& v3 m# f' |3 q1 [3 F& B| balance(a:u256) -> v:u256                   | 地址 a 上的 wei 余额                                            |
    * Y! }+ M4 N- ]' U# U4 H±--------------------------------------------±----------------------------------------------------------------+( T: O  o+ W) h" a6 f
    | this() -> address:u256                      | 当前合约/执行上下文的地址                                      |7 T# M3 d# s/ f6 A5 X& W4 P
    ±--------------------------------------------±----------------------------------------------------------------+
    9 R. q  f" a7 D/ m3 ^0 K' {| caller() -> address:u256                    | 调用的发送方 (不包含委托调用)                                   |
    9 B' j: h; c2 c0 L+ K. E4 I±--------------------------------------------±----------------------------------------------------------------+, m9 W! D- A1 L; P2 x
    | callvalue() -> v:u256                       | 与当前调用一起发送的 wei                                        |
      d5 C, A% d: |* f8 T, `% C8 M±--------------------------------------------±----------------------------------------------------------------+! k$ l) Y! f" a3 m! `& a% E0 k
    | calldataload(p:u256) -> v:u256              | 从 position p 开始的 calldata (32 字节)                         |
    5 `/ A6 k+ O+ q±--------------------------------------------±----------------------------------------------------------------+  X/ G' b  ~& U* x1 C
    | calldatasize() -> v:u256                    | 以字节为单位的 calldata 的大小                                  |* m; L" E/ i# q+ S* a& l- I
    ±--------------------------------------------±----------------------------------------------------------------+
    . R% w+ ~- z5 }& T| calldatacopy(t:u256, f:u256, s:u256)        | 从位置为 f 的 calldata 中,拷贝 s 字节到内存位置 t              |# k% @  v' S, N3 f1 |( T. F
    ±--------------------------------------------±----------------------------------------------------------------+% Q1 v. U7 G" ~2 t/ C
    | codesize() -> size:u256                     | 当前合约/执行上下文的代码大小                                  |5 P4 h+ ]9 {8 i" ]# E7 k2 F% a( A
    ±--------------------------------------------±----------------------------------------------------------------+
    2 K7 a7 x  R% L' y| codecopy(t:u256, f:u256, s:u256)            | 从 code 位置 f 拷贝 s 字节到内存位置 t                          |. j4 s) S: ~5 \; H) A8 D
    ±--------------------------------------------±----------------------------------------------------------------+% N+ c# w1 l! O& D
    | extcodesize(a:u256) -> size:u256            | 地址 a 上的代码大小                                             |( ?: R5 z( i) c2 i0 H* f2 L
    ±--------------------------------------------±----------------------------------------------------------------+
    8 K+ T* Z* X% I| extcodecopy(a:u256, t:u256, f:u256, s:u256) | 相当于 codecopy(t, f, s),但从地址 a 获取代码                   |& f7 M* [8 j6 p6 K; ^
    ±--------------------------------------------±----------------------------------------------------------------+" R0 s2 ?# L5 j! M
    | 其他                                                                                                        |
    % r/ e- D; d. q" h8 l" v±--------------------------------------------±----------------------------------------------------------------+
    5 v  l: _- x) |; i. u0 R7 W0 Y. U+ D| discard(unused:bool)                        | 丢弃值                                                          |
    # P, c- q. n3 n* S/ N5 ?% _( ?±--------------------------------------------±----------------------------------------------------------------+" f( Y+ U1 H) z8 ~
    | discardu256(unused:u256)                    | 丢弃值                                                          |& K9 |% L+ R! g- M3 A
    ±--------------------------------------------±----------------------------------------------------------------+- G8 D0 U' {/ p$ k" m4 ^
    | splitu256tou64(x:u256) -> (x1:u64, x2:u64,  | 将一个 u256 拆分为四个 u64                                      |
    . X' P2 I6 f! e7 {) y8 D|                            x3:u64, x4:u64)  |                                                                 |
    , B6 Y, y# U2 U4 V  p- o4 T6 J  w±--------------------------------------------±----------------------------------------------------------------+9 {6 @  ?5 f% g6 H- X+ K; \
    | combineu64tou256(x1:u64, x2:u64, x3:u64,    | 将四个 u64 组合为一个 u256                                      |
    6 b& q" k" @3 v4 N1 l0 S|                  x4:u64) -> (x:u256)        |                                                                 |8 ^9 H5 [  V( Y  Z! y, e0 o% {
    ±--------------------------------------------±----------------------------------------------------------------+
    # b4 y! O  |. b& D) || keccak256(p:u256, s:u256) -> v:u256         | keccak(mem[p…(p+s)))                                          |
    % d, s4 D  G: ~- Y±--------------------------------------------±----------------------------------------------------------------+
    7 K% U5 ^! n1 Y+ R" L* W后端
    7 D3 K% u% G" {+ O后端或目标负责将 Yul 翻译到特定字节码。 每个后端都可以暴露以后端名称为前缀的函数。 我们为两个建议的后端保留 evm_ 和 ewasm_ 前缀。
    ( v( i/ Z/ m! k. q0 P. i后端: EVM
    3 o, C% ~' J/ ~; J: U. ]目标 |evm| 将具有所有用 evm_ 前缀暴露的 |evm| 底层操作码。$ p! I0 x/ H0 X5 i- F) L  O
    后端: “EVM 1.5”/ b, d) N4 N5 W0 D( Z! F1 D
    TBD
    , t# f- M) M, K/ _后端: eWASM
    8 V2 v9 c* w- f+ }+ I. VTBD9 w) T' \/ t# h" |
    Yul 对象说明: }6 z" H! L% W# v
    语法::
    $ Y0 N& v  y7 k# Z: G顶层对象 = 'object' '{' 代码? ( 对象 | 数据 )* '}'# p5 e. k& M" t( q
    对象 = 'object' 字符串字面量 '{' 代码? ( 对象 | 数据 )* '}'
    9 Y5 F; F2 t1 ?$ I1 y9 Z) x/ x* C代码 = 'code' 代码块
    1 B+ C& j+ A! l数据 = 'data' 字符串字面量 十六进制字面量
    0 Z* E5 z/ O* x十六进制字面量 = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'')( ^: S0 \9 R' i- w/ Z
    字符串字面量 = '"' ([^"\r\n\\] | '\\' .)* '"'& N# `: M3 B8 B) @3 p
    在上面,代码块 指的是前一章中解释的 Yul 代码语法中的 代码块。# ~" x6 c7 b0 i3 a; T& x( Y; c
    Yul 对象示例如下:5 _% S* \& J; B7 Q& ]( |8 y
    …code::! M  @; I+ ]2 `) `6 x0 T% p9 g2 |% v
    // 代码由单个对象组成。 单个 “code” 节点是对象的代码。
    ) F1 w4 M' v# f& }" }" k. S- b9 A// 每个(其他)命名的对象或数据部分都被序列化
    3 S- A2 X  `! y  F, v// 并可供特殊内置函数:datacopy / dataoffset / datasize 用于访问
    2 e" a( U" C* ^* i  m8 w$ V4 Uobject {
    2 [( J; @+ ?% ], L' _    code {- k4 M2 @: }2 E3 x0 ^
            let size = datasize("runtime")8 d; v7 M, n( q/ T/ Z/ r& q) V; W- L
            let offset = allocate(size)* R/ \# W. u+ c" q, }6 ~
            // 这里,对于 eWASM 变为一个内存到内存的拷贝,对于 EVM 则相当于 codecopy7 e2 z$ ~5 D  z' ?0 S/ J
            datacopy(dataoffset("runtime"), offset, size)
    , u3 j2 j, c1 h& i* V# p        // 这是一个构造函数,并且运行时代码会被返回
    , j5 i% ~3 }, \! ^6 H        return(offset, size)
    , K( E# f" g; r* ]( i3 R- A3 N    }0 [+ x0 t7 l2 t+ [8 y0 T# _
        data "Table2" hex"4123"" f/ N3 @8 e  y' Q3 b7 e5 k
        object "runtime" {' h/ y3 _; t4 s; W$ H/ }8 H
            code {
    % c7 a+ W# ]. h$ v6 [            // 运行时代码+ |# K, \' V$ ^/ o* n# a8 L
                let size = datasize("Contract2")
    ! E7 R1 C1 K$ a% D' |            let offset = allocate(size)0 U' b) P2 l+ {2 Z9 Q8 _
                // 这里,对于 eWASM 变为一个内存到内存的拷贝,对于 EVM 则相当于 codecopy6 A' K5 ]; ~( w
                datacopy(dataoffset("Contract2"), offset, size)* K; Z" i& n+ |. f6 [" K( D
                // 构造函数参数是一个数字 0x12343 k3 k8 ?1 C; u! X$ P* }
                mstore(add(offset, size), 0x1234)
    $ G( M0 U/ S$ b. r! @9 K$ n- k4 v            create(offset, add(size, 32))
    " U# _: _3 S. \8 g3 P3 i        }) A, w* v& W( X  q9 }6 |# @
            // 内嵌对象。使用场景是,外层是一个工厂合约,而 Contract2 将是由工厂生成的代码
    , M' M4 H' \& ~0 \9 {( G        object "Contract2" {
    - B% ^8 o2 C$ W+ ?            code {. y$ Q/ z! P& P3 s- }9 x& ~
                    // 代码在这 ...
    : y! P8 v5 B, b8 r            }
    3 P1 Z& X  H% M6 N            object "runtime" {
    ( @& s) j5 K5 `4 D                code {3 p: h: ^0 L# h
                        // 代码在这 ...1 Z( ^3 b! j- t+ ?
                    }5 N. D! t0 u/ i& \
                 }* f3 h9 D% s+ t0 U# G, ~8 I
                 data "Table1" hex"4123"; d* D; |& I  ~3 c
            }
    0 s+ e% e5 X% P& {7 n  d: ^    }
    ( v3 t1 {4 `- s  o4 D: Q* ?9 ^}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人