Skip to main content

Address-Owned Objects

地址拥有的对象是由特定的 32 字节地址拥有的,这个地址可以是一个账户地址(由特定的签名方案衍生)或一个对象 ID。地址拥有的对象只能被它的所有者访问,其他人无法访问。

作为地址拥有者(拥有地址的人)可以将对象转移到不同的地址。由于只有单个所有者可以访问这些对象,你可以执行仅使用拥有的对象的事务,而不需要与不共享任何对象的其他事务进行共识。

创建地址拥有的对象

你可以使用以下函数之一(定义在传输模块中)来创建地址拥有的对象。

public fun transfer<T: key>(obj: T, recipient: address)
public fun public_transfer<T: key + store>(obj: T, recipient: address)

你应该使用 sui::transfer::transfer 函数来定义对象的自定义转移策略。如果对象具有 store 能力,则使用 sui::transfer::public_transfer 函数来创建地址拥有的对象。

在将对象声明为地址拥有之后,对象的所有权可以在其生命周期内发生变化 - 通过将其添加为动态对象字段、将其转移到不同的地址或使其不可变。但重要的是,在创建对象并设置其所有权后,它不能被共享。

访问地址拥有的对象

你可以以两种不同的方式访问地址拥有的对象,这取决于对象的地址所有者是否对应于对象 ID。

如果对象的地址所有者对应于对象 ID,则在事务执行期间,你必须使用 传输到对象 中定义的机制访问并动态验证它。

如果对象的地址所有者是一个由签名衍生的地址(账户地址),则在事务执行期间,你可以直接将其用作拥有的对象,该地址进行签名。其他地址无法以任何方式在事务中访问拥有的对象 - 即使只是读取对象。

何时使用地址拥有的对象

在只在任何时刻都希望或需要一个对象的单个所有者的情况下使用地址拥有的对象。在设计时,通常应在合理或可能的情况下优先选择地址拥有的对象,而不是共享对象。拥有的对象不需要通过共识进行排序,因此如果对象被广泛使用,它们更不容易出现吞吐量瓶颈。

示例

一个经常被地址拥有的对象的示例是Coin 对象。如果地址 0xA11CE 拥有一个币 C,其中有 100 SUI,并且想要支付地址 0xB0B 100 SUI,0xA11CE 可以通过将 C 转移到 0xB0B 来实现。

sui::transfer::public_transfer(C, @0xB0B);

这导致 C 具有新的地址所有者 0xB0B,并且 0xB0B 以后可以使用这 100 个 SUI 币。