Entry 函数
entry
修饰符允许从可编程事务块中直接调用函数,作为模块的“入口点”。
以这种方式调用时,传递给 entry
函数的参数必须是事务块的输入,不能是该块中先前事务的结果,也不能被该块中的先前事务修改。入口函数也只允许返回具有 drop
的类型。
这些限制防止第三方使用可编程事务块的脚本化性质来绕过 entry
函数不能从其他模块中调用的事实。
public
与 entry
函数
public
修饰符还允许从可编程事务块中调用函数。它还允许从其他模块中调用该函数,并且不对函数的参数来源以及返回值施加相同的限制,因此在许多情况下,public
是将函数暴露给外界的正确方式。如果:
- 你想要确保你的函数不会与第三方模块函数结合在可编程事务块中。这方面的典型例子是不希望交换协议与闪电贷提供者进行交互:如果交换协议仅公开了
entry
函数以执行交换,那么将无法传递作为先前交易输出的闪电贷出的Coin
。 - 你不希望函数的签名出现在你模块的 ABI 中。
public
函数签名必须在升级时进行维护,而entry
函数签名不需要。
也可以创建一个 public entry
函数,该函数既可以由其他模块调用,也可以由可编程事务块调用,但在后一种情况下受到与 entry
函数相似的限制。这很少有用--你可能只需要 public
或 entry
中的一个。
例子
module entry_functions::example {
use sui::object::{Self, UID};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
struct Foo has key {
id: UID,
bar: u64,
}
/// Entry functions can accept a reference to the `TxContext`
/// (mutable or immutable) as their last parameter.
entry fun share(bar: u64, ctx: &mut TxContext) {
transfer::share_object(Foo {
id: object::new(ctx),
bar,
})
}
/// Parameters passed to entry functions called in a programmable
/// transaction block (like `foo`, below) must be inputs to the
/// transaction block, and not results of previous transactions.
entry fun update(foo: &mut Foo, ctx: &TxContext) {
foo.bar = tx_context::epoch(ctx);
}
/// Entry functions can return types that have `drop`.
entry fun bar(foo: &Foo): u64 {
foo.bar
}
/// This function cannot be `entry` because it returns a value
/// that does not have `drop`.
public fun foo(ctx: &mut TxContext): Foo {
Foo { id: object::new(ctx), bar: 0 }
}
}