Skip to main content

Aptos 核心

alt text

alt text

https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/move-examples/move-tutorial/diagrams/solidity_state.png

Object、ObjectCore、ObjectGroup

在您提供的 Aptos 框架上下文中,ObjectCoreObjectObjectGroup 之间的关系可以用以下文本图表示:

ObjectGroup (资源组)

├── ObjectCore (资源组成员)
│ ├── guid_creation_num: u64
│ ├── owner: address
│ ├── allow_ungated_transfer: bool
│ └── transfer_events: event::EventHandle<TransferEvent>

└── [其他资源组成员,如 LiquidityPool]
├── token_a: Object<FungibleAsset>
├── token_b: Object<FungibleAsset>
├── reserves_a: u128
└── reserves_b: u128

在这个结构中:

  • ObjectGroup 是一个存储在特定地址的资源组,它是一个容器,可以包含多个资源。
  • ObjectCoreObjectGroup 中的一个成员(资源),它包含对象的基本属性,如唯一标识符、所有者地址、转移权限等。
  • 其他资源(如 LiquidityPool)也可以是 ObjectGroup 的成员,它们与 ObjectCore 存储在同一个地址,共享相同的存储槽,以提高数据访问效率。

这意味着 ObjectCoreObjectGroup 的一部分,同时 ObjectGroup 可以包含 ObjectCore 以及其他扩展资源,如 LiquidityPool。这种设计允许将相关资源组织在一起,以优化存储和访问效率。

ObjectCore 类似 gorm 的 gorm.Model

是的,您可以把 ObjectCore 比作 Golang ORM 库 GORM 中的 gorm.Model。在 GORM 中,gorm.Model 是一个包含了一些基础字段的结构体,如 ID, CreatedAt, UpdatedAt, DeletedAt,它们是大多数数据库表都会有的字段。当你在你的模型中嵌入 gorm.Model 时,你的模型就自动继承了这些基础字段。

类似地,在 Aptos 的 Move 语言中,ObjectCore 是一个包含了一些基础属性的资源,这些属性对于区块链上的对象来说是通用的。当你在自定义资源中包含 ObjectCore 时,这个资源就自动拥有了这些属性,如全局唯一标识符、所有者地址、转移权限标志等。

这两种情况下,都是为了减少代码重复,提高开发效率,并保持数据结构的一致性。不过,要注意的是,尽管这两个概念在某些方面相似,但它们工作在完全不同的环境和上下文中:ObjectCore 在 Aptos 区块链平台的 Move 语言环境中,而 gorm.Model 在 Golang 的 ORM 环境中。此外,Move 语言的资源模型与 Golang 中的结构体模型在语义上有很大的不同,尤其是在所有权和可变性方面。

Aptos 数据模型

Aptos 的 Object 模型和它与传统账户资源模型的区别

https://aptos.dev/standards/aptos-object#comparison-with-the-account-resources-model

让我们用更通俗的语言来解释一下 Aptos 的 Object 模型和它与传统账户资源模型的区别。

Object 模型

想象一下,你有一个玩具箱(Object 模型),你可以在里面放各种各样的玩具(资源),比如小汽车、积木、玩偶等。每种玩具都有自己的小盒子(资源类型),这样它们就不会混在一起。你还有一把特别的钥匙(能力模型),可以决定谁能打开玩具箱,谁能玩哪些玩具,甚至谁能把玩具带走。

比如,你有一个特别的积木(NFT),它放在自己的盒子里(Token 资源),还有一个说明它是谁的(ObjectCore 资源),以及一些特别的积木块(其他资源),这样你就可以根据自己的想法来组合它们。

传统账户资源模型

现在,想象一下你有一个大房间(账户资源模型),里面到处都是玩具,没有放在玩具箱里。这样虽然看起来你有很多自由度,可以随便放玩具,但实际上会很乱。有时候你想找一个特定的玩具(数据访问),可能会找不到;有时候你想确保某个玩具只能你玩(类型混合),但因为它们都混在一起,别人也可能拿去玩。

而且,如果你想告诉别人你有一个新的玩具(事件发射),你得先清理一下房间,找到那个玩具,然后才能告诉大家。如果你想把一个玩具给别人(转移逻辑),你可能需要先找到玩具,然后还得确保对方也有地方放这个玩具,这样做起来就很麻烦。

总结

所以,Object 模型就像一个有组织的玩具箱,让你可以更好地管理和控制你的玩具(资源)。它让你知道每个玩具在哪里,谁可以玩它们,以及如何安全地分享它们。而传统的账户资源模型就像一个大房间,虽然自由度高,但管理起来很混乱,而且有时候会很不方便。

Object vs ObjectGroup

这段描述了 Aptos 的 Object 模型中对象(Object)的结构和如何使用它来创建和管理资源。下面是一个简化的解释:

ObjectGroup 资源组

  • 资源组定位:一个对象(Object)被存储在一个名为 ObjectGroup 的资源组中。这样做的目的是为了让对象内的相关资源能够被放在一起,从而优化数据访问效率和节省数据存储成本。

  • 灵活的数据布局:开发者可以自行决定哪些资源需要放在 ObjectGroup 中,以获得数据局部性的好处。

    ObjectCore 资源

  • 基础属性:每个对象都有一个核心资源 ObjectCore,它包含了一些基本属性,如全局唯一标识符(用于创建事件流)、所有者地址、是否允许无门槛转移,以及转移事件的事件句柄。

  • 关键代码ObjectCore 中的代码定义了这些属性,并且标记了它是 ObjectGroup 的一部分。

    扩展对象

  • 自定义资源:创建对象后,开发者可以向对象中添加额外的资源。例如,一个交易所可以为每个流动性池创建一个对象,并添加一个资源来追踪池的流动性。

  • 示例代码:在代码示例中,LiquidityPool 结构体代表了流动性池,它包含了代表资产的对象引用和储备量。这个资源也是 ObjectGroup 的一部分,意味着它与 ObjectCore 存储在同一个位置,这样做可以提高存储和数据操作的效率。

    创建流动性池

  • 构造函数:示例中的 create_liquidity_pool 函数展示了如何创建一个流动性池对象。它使用了一系列的 Move 语言操作来初始化一个新的 LiquidityPool 资源,并将它与创建者的账户关联起来。

  • 交易所签名者:函数中使用了 exchange_signer 来代表交易所的权限,它是创建流动性池对象的必要条件。

  • 对象构造和注册:通过 object::create_object_from_accountobject::generate_signer 函数创建对象,并使用 move_toLiquidityPool 资源放入正确的存储位置。

    后续扩展

  • 扩展引用:如果交易所模块存储了 ExtendRef,它可以在对象创建后继续添加更多资源。ExtendRef 是一种能力,允许对象在创建后进行扩展。

    总结

这里描述的是如何在 Aptos 平台上使用 Move 语言构建和管理复杂的对象,它们可以包含多个相关资源,并且可以在创建后进行扩展。这种模型旨在提高数据操作的效率和减少存储成本,同时提供灵活的数据管理方式。

这段的意思是,Object 都要放到 ObjectGroup 来组织?ObjectCore 也要放到 ObjectGroup 来组织?

是的,你的理解是正确的。在 Aptos 的 Object 模型中,Object是资源的容器,这些资源被存储在一个单一的地址内。通常情况下,这些相关联的资源会被频繁地一起访问,因此把它们存储在一个地址内是为了数据局部性和节省成本。

ObjectGroup是默认的资源组,当你创建一个 Object 时,它会自动包含一个ObjectGroup。这是一个全局作用域的结构体,用来组织和存储 Object 内的资源。

ObjectCore是每个 Object 都有的核心资源,它包含了 Object 的基本属性,如唯一标识符、所有者地址、转移权限设置和转移事件句柄等。ObjectCore也是ObjectGroup的一部分,这意味着它和其他的资源一起存储在同一地址的存储槽中。

简而言之,ObjectGroup是用来组织一个 Object 内的所有资源的,而ObjectCore是这个组织内的一个核心成员,包含了一些基本的属性信息。这种设计使得相关资源的存储和访问更加高效,同时也便于管理。

Object 操作

https://aptos.dev/standards/aptos-object#object-capabilities-refs

在 Aptos 框架中,对象(Object)的创建和管理依赖于一系列称为“引用”(refs)的能力。当一个对象被创建时,创建函数返回一个临时的ConstructorRef。这个引用是短暂的,意味着它不能被存储在链上的持久存储中。ConstructorRef用于在对象创建过程中添加资源,正如前面节中的例子所展示的。除此之外,ConstructorRef还可以用来生成其他几种管理对象的能力或引用:

  • DeleteRef:通过generate_delete_ref函数生成,可以用来从全局存储中删除对象。
  • ExtendRef:通过generate_extend_ref函数生成,可以用来向对象添加新的事件和资源。
  • TransferRef:通过generate_transfer_ref函数生成,可以用来管理对象的转移。
  • Signer:通过generate_signer函数生成,这是一个代表对象创建者的签名者,用于在对象创建过程中授权操作。

这些引用代表了对对象的不同管理能力,可以被存储起来以便于后续使用。例如,如果一个模块想要在未来向对象添加新的资源,它可以在对象创建时获取一个ExtendRef并将其存储。之后,该模块可以使用这个ExtendRef来扩展对象,即使在对象创建过程已经结束之后。

简单来说,这些引用是管理对象生命周期和功能的工具。它们允许对象的创建者或拥有者在对象创建后继续对其进行操作,如添加资源、转移所有权,甚至删除对象。这些操作都是通过相应的引用来实现的,确保了对象的安全和灵活性。

info

看起来没有 Rust 方便,这里需要先添加引用,在未来某个时候通过 Object API 来操作这个对象

确实,Aptos 的 Move 语言在对象管理方面采用了一种不同于 Rust 的方法。在 Rust 中,所有权和借用是编程语言的核心概念,允许你直接通过变量和引用来管理资源。而 Aptos 的 Move 语言通过显式的能力(capability)系统来管理对象。

在 Move 中,当你创建一个对象时,你必须显式地生成和使用不同的引用(refs)来管理该对象。这些引用是特殊的能力,它们提供了对对象进行特定操作的权限。这种设计模式使得对象的管理更加安全,因为每个操作都需要相应的能力,从而减少了错误或恶意行为的风险。

虽然这种方法可能不如 Rust 的所有权模型直观,但它提供了一种细粒度的权限控制,这在智能合约和区块链环境中是非常重要的。在区块链上,对资源的严格控制可以防止未授权的访问和修改,保证了智能合约的安全性和确定性。

总的来说,Aptos 的 Move 语言通过引用和能力系统提供了一种灵活而安全的方式来管理链上对象,虽然这可能需要开发者适应一种新的编程范式。