FunC 开发手册
创建 FunC 开发手册的核心原因是将所有 FunC 开发者的经验汇集在一个地方,以便未来的开发者们使用!
与 FunC 文档相比,本文更侧重于 FunC 开发者在智能合约开发过程中每天都要解决的任务。
基础知识
如何编写 if 语句
假设我们想检查某个事件是否相关。为此,我们使用标志变量。记住在 FunC 中 true
是 -1
而 false
是 0
。
int flag = 0; ;; false
if (flag) {
;; do something
}
else {
;; reject the transaction
}
💡 注意
我们不需要使用
==
操作符,因为0
的值是false
,所以任何其他值都将是true
。
💡 有用的链接
如何编写 repeat 循环
以指数运算为例
int number = 2;
int multiplier = number;
int degree = 5;
repeat(degree - 1) {
number *= multiplier;
}
💡 有用的链接
如何编写 while 循环
当我们不知道要执行特定操作多少次时,while 循环很有用。例如,取一个 cell
,我们知道它可以存储最多四个对其他 cell 的引用。
cell inner_cell = begin_cell() ;; create a new empty builder
.store_uint(123, 16) ;; store uint with value 123 and length 16 bits
.end_cell(); ;; convert builder to a cell
cell message = begin_cell()
.store_ref(inner_cell) ;; store cell as reference
.store_ref(inner_cell)
.end_cell();
slice msg = message.begin_parse(); ;; convert cell to slice
while (msg.slice_refs_empty?() != -1) { ;; we should remind that -1 is true
cell inner_cell = msg~load_ref(); ;; load cell from slice msg
;; do something
}
💡 有用的链接
如何编写 do until 循环
当我们需要循环至少运行一次时,我们使用 do until
。
int flag = 0;
do {
;; do something even flag is false (0)
} until (flag == -1); ;; -1 is true
💡 有用的链接
如何确定 slice 是否为空
在处理 slice
之前,需要检查它是否有数据以便正确处理。我们可以使用 slice_empty?()
来做到这一点,但我们必须考虑到,如果有至少一个 bit
的数据或一个 ref
,它将返回 -1
(true
)。
;; creating empty slice
slice empty_slice = "";
;; `slice_empty?()` returns `true`, because slice doesn't have any `bits` and `refs`
empty_slice.slice_empty?();
;; creating slice which contains bits only
slice slice_with_bits_only = "Hello, world!";
;; `slice_empty?()` returns `false`, because slice have any `bits`
slice_with_bits_only.slice_empty?();
;; creating slice which contains refs only
slice slice_with_refs_only = begin_cell()
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_empty?()` returns `false`, because slice have any `refs`
slice_with_refs_only.slice_empty?();
;; creating slice which contains bits and refs
slice slice_with_bits_and_refs = begin_cell()
.store_slice("Hello, world!")
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_empty?()` returns `false`, because slice have any `bits` and `refs`
slice_with_bits_and_refs.slice_empty?();
💡 有用的链接
如何确定 slice 是否为空(不含任何 bits,但可能包含 refs)
如果我们只需要检查 bits
,不关心 slice
中是否有任何 refs
,那么我们应该使用 slice_data_empty?()
。
;; creating empty slice
slice empty_slice = "";
;; `slice_data_empty?()` returns `true`, because slice doesn't have any `bits`
empty_slice.slice_data_empty?();
;; creating slice which contains bits only
slice slice_with_bits_only = "Hello, world!";
;; `slice_data_empty?()` returns `false`, because slice have any `bits`
slice_with_bits_only.slice_data_empty?();
;; creating slice which contains refs only
slice slice_with_refs_only = begin_cell()
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_data_empty?()` returns `true`, because slice doesn't have any `bits`
slice_with_refs_only.slice_data_empty?();
;; creating slice which contains bits and refs
slice slice_with_bits_and_refs = begin_cell()
.store_slice("Hello, world!")
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_data_empty?()` returns `false`, because slice have any `bits`
slice_with_bits_and_refs.slice_data_empty?();
💡 有用的链接
如何确定 slice 是否为空(没有任何 refs,但可能有 bits)
如果我们只对 refs
感兴趣,我们应该使用 slice_refs_empty?()
来检查它们的存在。
;; creating empty slice
slice empty_slice = "";
;; `slice_refs_empty?()` returns `true`, because slice doesn't have any `refs`
empty_slice.slice_refs_empty?();
;; creating slice which contains bits only
slice slice_with_bits_only = "Hello, world!";
;; `slice_refs_empty?()` returns `true`, because slice doesn't have any `refs`
slice_with_bits_only.slice_refs_empty?();
;; creating slice which contains refs only
slice slice_with_refs_only = begin_cell()
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_refs_empty?()` returns `false`, because slice have any `refs`
slice_with_refs_only.slice_refs_empty?();
;; creating slice which contains bits and refs
slice slice_with_bits_and_refs = begin_cell()
.store_slice("Hello, world!")
.store_ref(null())
.end_cell()
.begin_parse();
;; `slice_refs_empty?()` returns `false`, because slice have any `refs`
slice_with_bits_and_refs.slice_refs_empty?();
💡 有用的链接
如何确定 cell 是否为空
要检查 cell
中是否有任何数据,我们应首先将其转换为 slice
。如果我们只对 bits
感兴趣,应使用 slice_data_empty?()
;如果只对 refs
感兴趣,则使用 slice_refs_empty?()
。如果我们想检查是否有任何数据,无论是 bit
还是 ref
,我们需要使用 slice_empty?()
。
cell cell_with_bits_and_refs = begin_cell()
.store_uint(1337, 16)
.store_ref(null())
.end_cell();
;; Change `cell` type to slice with `begin_parse()`
slice cs = cell_with_bits_and_refs.begin_parse();
;; determine if slice is empty
if (cs.slice_empty?()) {
;; cell is empty
}
else {
;; cell is not empty
}
💡 有用的链接
如何确定 dict 是否为空
有一个 dict_empty?()
方法可以检查 dict 中是否有数据。这个方法相当于 cell_null?()
,因为通常一个空的 cell 就是一个空字典。
cell d = new_dict();
d~udict_set(256, 0, "hello");
d~udict_set(256, 1, "world");
if (d.dict_empty?()) { ;; Determine if dict is empty
;; dict is empty
}
else {
;; dict is not empty
}
💡 有用的链接
文档中的“new_dict()” 创建空字典
[文档中的“dict_set()”](/develop/