Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[book] transfer to object #106

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

[book] transfer to object #106

wants to merge 2 commits into from

Conversation

damirka
Copy link
Collaborator

@damirka damirka commented Dec 8, 2024

Adds missing Transfer to Object chapter

@damirka damirka added the book Changes something in the book label Dec 8, 2024
@damirka damirka self-assigned this Dec 8, 2024
@damirka damirka changed the title [draft] transfer to object [book] transfer to object Dec 8, 2024

Transfer to Object is not the only way to create a relationship between objects. There are more
flexible and feature-rich ways, such as the
[Dynamic Fields](./../programmability/dynamic-fields.md), which we explore in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know if this is the place for this comment, however as dynamic fields are referenced here, here it is:
Something that comes up a lot:

Should I use dynamic fields or TTO?

One major difference is that one does not need to have ownership of the owner-object in order to transfer an object to it.
Dynamic fields on the other hand can be seen as having more "control" on what is added "below" the owner object.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Been thinking about it a lot and still don't have an answer. Technically, in the book, it is too early to mention dynamic fields (they come mid next chapter), yet dynamic fields are too far from transfer to object. Very good point, and very much worth discussing!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind it's not really an either/or of TTO vs dynamic fields. TTO is about transfer, dynamic fields are about ownership -- i.e. it's perfectly valid to have a protocol where you use TTO to transfer something to an object, and then when it is received, it is turned into a dynamic field on the object it was received on.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amnn I agree that they're not replacing each other (though, in some situations they do), but more of a guide which one is suited for which purpose.

@@ -31,21 +31,27 @@ Transactions consist of:

## Inputs

Transaction inputs are the arguments for the transaction and are split between 2 types:
Transaction inputs are the arguments for the transaction and are split between 3 types:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically they are split into four types:

  • Pure arguments
  • Owned or Immutable Object arguments
  • Shared Object Arguments
  • Receiving Object Arguments

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, will expand!

Comment on lines +18 to +19
Every object in Sui has its own `UID` which is represented by the
[address type](./../move-basics/address.md). This address can be used to query the object's data,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be a bit confusing to folks, because depending on context, an object's ID can be represented by a UID, ID, or address type. On this page the address representation is the most interesting/novel one, but in other circumstances (e.g. for dynamic fields) UID is more interesting, and in other circumstances (e.g. ID pointer) ID is more interesting.

Here seems like the wrong place to discuss this concept in detail, but it seems like something we should document somewhere.

Comment on lines +42 to +43
through their owner. The owner object needs to implement a custom function that will call the
`receive` function from the `transfer` module.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so-so on the phrase "the owner object needs to implement..." because it sounds like interface implementation which is not a concept we have in Move. It also puts the focus on the custom receive function, and I'm not sure that's the focus for the object doing the receiving (the only thing that matters for the receiving object is that it exposes its &mut UID, but it's probably a good idea for that to be done in a limited way that means you can only use it for specific purposes). A custom receive function is more important for dealing with the object being transferred -- because if that object does not have store, it needs a custom function to call receive on it.

Copy link
Collaborator Author

@damirka damirka Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I also had this feeling, and I don't like it. The biggest blocker I faced on every attempt to write this page.

Comment on lines +101 to +105
/// For objects without `store` (though, they would require special handling), we
/// can implement the non-public version of the `receive` function.
public fun receive<T: key>(po: &mut PostOffice, to_receive: Receiving<T>): T {
transfer::receive(&mut po.id, to_receive)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work? I would expect it to fail because of custom transfer rules (the non-public_ receive is being called on type T from a module that does not define T).

book/src/storage/transfer-to-object.md Outdated Show resolved Hide resolved

Transfer to Object is not the only way to create a relationship between objects. There are more
flexible and feature-rich ways, such as the
[Dynamic Fields](./../programmability/dynamic-fields.md), which we explore in the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind it's not really an either/or of TTO vs dynamic fields. TTO is about transfer, dynamic fields are about ownership -- i.e. it's perfectly valid to have a protocol where you use TTO to transfer something to an object, and then when it is received, it is turned into a dynamic field on the object it was received on.

@damirka damirka requested a review from mdgeorge4153 December 9, 2024 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
book Changes something in the book
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants