本系列文檔翻譯版權(quán)歸FireStack團(tuán)隊(duì)所有,轉(zhuǎn)載請(qǐng)注明來(lái)源播急。
Scilla合約架構(gòu)
Scilla合約的一般結(jié)構(gòu)如下代碼所示燎含。開(kāi)頭是引用純數(shù)學(xué)函數(shù)的library
的聲明饶囚,例如計(jì)算兩個(gè)比特?cái)?shù)據(jù)的AND
布爾值伏伐,或計(jì)算某個(gè)自然數(shù)的階乘。在庫(kù)聲明代碼塊后面晕拆,是使用contract
聲明的合約內(nèi)容藐翎。合約有三個(gè)部分,第一部分聲明合約的不可變參數(shù)实幕,第二部分聲明可變字段吝镣,第三部分為所有transition
定義。
(* Scilla contract structure *)
(***************************************************)
(* Associated library *)
(***************************************************)
library MyContractLib
(* Library code block follows *)
(***************************************************)
(* Contract definition *)
(***************************************************)
contract MyContract
(* Immutable fields declaration *)
(vname_1 : vtype_1,
vname_2 : vtype_2)
(* Mutable fields declaration *)
field vname_1 : vtype_1 = init_val_1
field vname_2 : vtype_2 = init_val_2
(* Transitions *)
(* Transition signature *)
transition firstTransition (param_1 : type_1, param_2 : type_2)
(* Transition body *)
end
transition secondTransition (param_1: type_1)
(* Transition body *)
end
不可變變量
不可變變量昆庇,或稱為合約參數(shù)末贾,在創(chuàng)建合約時(shí)就定義了值,并且不能被修改整吆。合約中的不可變變量組需在合約開(kāi)頭的合約名稱定義之后聲明拱撵。
不可變變量聲明格式如下:
(vname1 : type1,
vname2 : type2,
... )
每個(gè)聲明都包含一個(gè)變量名(標(biāo)識(shí)符)及其類(lèi)型,用:
分隔表蝙。多個(gè)變量聲明用,
分隔拴测。變量的初始值在合約創(chuàng)建時(shí)就要指定。
可變變量
可變變量代表著合約的可變狀態(tài)府蛇。它們也被稱為字段集索。它們會(huì)在不可變變量之后聲明,每個(gè)聲明都以field
為前綴。
field name1 : type1 = expr1
field name2 : type2 = expr2
...
這里的每個(gè)表達(dá)式都是相應(yīng)字段的初始值务荆。變量的定義在創(chuàng)建就完成了初始化妆距。隨著合約履行transition,這些字段的值會(huì)被修改函匕。
轉(zhuǎn)換(Transitions)
Transitions決定了合約狀態(tài)的變化娱据。這些是使用transition
定義的,后面寫(xiě)要傳遞的名稱和參數(shù)浦箱,以end
結(jié)尾吸耿。
transition foo (name1 : type1, name2 : type2, ...)
...
end
name : type
指定參數(shù)名和類(lèi)型,多個(gè)參數(shù)時(shí)用,
分隔酷窥。除了顯式聲明的參數(shù)之外咽安,還可以使用以下transition
隱式參數(shù)。
-
_sender : Address
:觸發(fā)此transition的帳戶(消息發(fā)送人)蓬推。 -
_amount : Uint128
:入庫(kù)金額(ZILs)妆棒。必須使用accept
語(yǔ)句明確接收過(guò)程。如果transition沒(méi)有執(zhí)行沸伏,則不會(huì)執(zhí)行accept
糕珊。
表達(dá)式(Expressions)
表達(dá)式處理純操作。Scilla中支持的表達(dá)式是:
-
let x = f in e
:在表達(dá)式e
中給出名稱x
毅糟。 這里e
與f
的結(jié)合是局部的红选,因此限于e
。 下面的示例將表達(dá)式builitin add one Int32 5
中的one
綁定為1
姆另,它將5添加到1喇肋,因此計(jì)算結(jié)果為6。let one = 1 in builtin add one Int32 5
-
let x = f
:在合約中注明f
名稱x
迹辐。x
to 的綁定f
是全局的蝶防,并延伸到合約的末尾。請(qǐng)注意缺失in
明吩,這意味著綁定適用于整個(gè)合約而不是特定表達(dá)式间学。以下代碼片段定義了一個(gè)常量,one
其值1
貫穿整個(gè)契約印荔。let one = 1
-
{<entry> _1; <entry> _2 ...}
:消息表達(dá)式(請(qǐng)參閱下面的Message
類(lèi)型)低葫,其中每個(gè)條目具有以下形式:b:x
。這里b
是標(biāo)識(shí)符躏鱼,x
是變量氮采,其值綁定到消息中的標(biāo)識(shí)符。以下代碼定義了一個(gè)帶有四個(gè)條目_tag
染苛,_recipient
鹊漠,_amount
和code的msg
主到。msg = { _tag : "Main"; _recipient : sender; _amount : Uint128 0; code : Uint32 0 };
fun (x : T) => e
:一個(gè)接受x
類(lèi)型輸入T
并返回表達(dá)式e
求值的值的函數(shù)。tfun T => e
:一種類(lèi)型函數(shù)躯概,它T
作為參數(shù)類(lèi)型并返回表達(dá)式e
求值的值登钥。有關(guān)Pair
示例,請(qǐng)參閱下面的部分 娶靡。@x T
:x
使用類(lèi)型實(shí)例化變量T
牧牢。f x
:應(yīng)用f
上x
。builtin f x
:應(yīng)用builtin
功能f
上x
姿锭。match
expression:將綁定變量與模式匹配并執(zhí)行該子句中的語(yǔ)句塔鳍。該match
表達(dá)式類(lèi)似于match
OCaml中的表達(dá)式 。要匹配的模式可以是變量綁定呻此,ADT構(gòu)造函數(shù)(請(qǐng)參閱ADT)或通配符_
以匹配任何內(nèi)容轮纫。
match x with
| pattern1 =>
statements ...
| pattern2 =>
statements ...
end
聲明(Statements)
Scilla中的聲明是實(shí)際生效的操作,即這些操作不是純數(shù)學(xué)意義上的焚鲜。此類(lèi)操作包括從可變智能合約變量讀取或向其寫(xiě)入掌唾。
-
x <- f
:x
從可變字段f
讀取值。 -
f := x
:可變字段f
的值更新為x
忿磅。
還可以從區(qū)塊鏈狀態(tài)中讀取糯彬。區(qū)塊鏈狀態(tài)由與區(qū)塊相關(guān)聯(lián)的某些值組成,如BLOCKNUMBER
葱她。
-
x <- &B
:x
從區(qū)塊鏈狀態(tài)變量B
讀取值撩扒。
每當(dāng)通過(guò)transition發(fā)送ZIL令牌時(shí),轉(zhuǎn)換必須明確接收這筆轉(zhuǎn)賬吨些,可通過(guò)accept
聲明完成却舀。
-
accept
:接收來(lái)款。
通信(Communication)
合約可以通過(guò)send
聲明與其他合約(或非合約)賬戶進(jìn)行通信:
-
send ms
:發(fā)送消息列表ms
锤灿。