This exact definition does not match a large segment of standards in existence. If I used this definition (in context) I could easily argue that ERC20 and ERC1155 are not standards since they specify the interface but not the behavior of the operation.
This is less a definition of standards and more of an actual standard in itself for extending the functionality. It makes sense and it’s a powerful concept worth exploring, not just for this standard, but for any future standard.
There is an inherent incentive for developers to create code that isn’t incompatible with the systems they are trying to interface with. I can point to the existing NFT marketplaces on Ethereum as an example of this. Their NFT standards make no guarantee of compatibility, yet the marketplaces still exist and continue to grow.
Sandboxing is a more ideal solution, but it just isn’t an option. We can’t control what an extension does once it executes because it operates in the exact same context as the caller. Only when the extension is executed can be controlled.
The current implementation already utilizes a few different rules for when the extension is executed based on the detected operation. Your suggestion is to take this further by using more granular operations and adding restrictions with some of them. I was unable to come up with any scenario where an operative restriction could be put in place without impeding some kind of potentially desired behavior.
However, I believe the tradeoff is worth it since we can guarantee certain operations for this particular opt-in asset class. A transfer operation, in particular, would be the most obvious. This design feature is something that should be named for future reference.
Below is an incomplete list of the operations that exist in the current implementation. Transfer, update, and burn operations can all occur at the same time, which can make classification difficult.
Looking at what can be isolated, a Pure Transfer and Burn operation can probably be isolated without issue. A Transfer Split and Transfer Combine get trickier because of the support for a zero quantity token instance.
Generate
Single
Multiple
Bare (Condensed form; no quantity, token logic, or custom data.)
With Quantity
With Quantity Zero
With Token Logic
With Token Logic Null
With Custom Data
Transfer
Pure (Does not modify any field values.)
To Self
To Other
Split
Standard
Zero Quantity
Combine
Standard
Zero Quantity (Burn)
+ Update
+ Burn
Update
Change Quantity
Split
Combine
Burn
Change Token Logic (Owner mode required.)
Set Token Logic
Set Null
Change Custom Data (Regulated by token logic.)
Shapeshift (Switch between condensed and expanded quantity and token logic.)
I believe it is worth the trade-off of losing some potential avenues of desirable behavior to guarantee the success of certain operations. eg: It is worth the trade-off of restricting the capability of a token logic extension to control the outcome of a transfer operation because this guarantees that transfers can occur in an expected manner.
Which operations should be guaranteed operations is still an open question. Whatever is decided on needs to be absolutely enforceable in the implementation, and I haven’t been able to dedicate enough time to thinking it through yet.
I’ve updated the implementation to include guaranteed operations for transfers and burns.
Because of this change, the token logic no longer can restrict:
Transfers
Burns
Splits (one cell into two)
Combines (two cells into one)
Zero quantity cell creation
The ability to control the latter three could be reintroduced by adding a permission system for more specific operations. However, this is adding a lot more complexity with limited benefits. I’m unsure if it’s needed for this standard.
It is referring to any dapp that uses NFTs. This could be something like a marketplace or auction house. It could also be something like different games that share the same underlying NFTs.
Not exactly. The Instance ID field must contain a value at all times. The quantity and Token Logic fields are optional under specific conditions. This allows for smaller capacity requirements in some cases.
If the quantity value is not present, then it should be assumed to be equal to a value of 1.
If the Token Logic value is not included, then it should be assumed to be equal to all zeros.
Yes, a Token Logic value of all zeros, (0x0000000000000000000000000000000000000000000000000000000000000000), means that there is no extra token logic to execute. Having all zeros is also the same as having no value at all, which reduces the amount of capacity needed.
Could you give me some example about that?
Like today if a NFT instance gun could be used with a NFT bullet to kill one enemy, its script could be verified to generate some other NFT?
I am anticipating that when Token Logic executes, most of the time the logic will only be concerned with the cells that are using the same code hash. I often refer to this as the minimal concern principle. An example of this is in the SUDT type script. When SUDT is examining the transaction, it only cares about cells that are the same SUDT. Everything else is ignored. It may end up being similar with token logic.
An example of token logic that does not use the minimal concern principle would be an NFT gun that will shoot stronger if it is paired with NFT power ups in the same transaction. In this case the token logic in the gun NFT cell needs to examine the entire transaction and check all of the cells to see which NFT power ups are present so it can calculate the total power of the gun.
The example you give where an NFT is generated by some kind of an event is possible, but there are special considerations. Since this standard has trait of guaranteed scarcity, a new NFT instance is more difficult to create from within Token Logic. An item drop describes it better. For example, an NFT sword could be used to slay the NFT dragon, which is protecting an NFT magic item that is secured by the treasure chest lock script.
Thanks for your detailed explanation. Have learned a lot from you.
Actually, such complicated logic should be verified by a custom rule so that it could prevent the limitation of the general guideline. But there is one more question here: how do we identify the common condition and complex interaction of NFT instances?
btw your example is more suitable.
生成模式允许所有者能在同一个 token class 中创建无限个新的 token instance。指派给每个 token 的 instance ID 是使用seed cell 设计模型生成的,这意味着它是随机分配的,并且保证全局唯一。新的 token instance 中的 token 数量在创建时定义,在生成后就不能增加。
Instance ID 按照下列规则去生成
For any new token instance being created, the Instance ID is a hash of the
outpoint of the first input, combined with the output index of the token
instance cell being created.
hash(seed_cell.tx_hash, seed_cell.index, instance_output_index)
Instance ID and Quantity Restrictions/ Instance ID 和数量限制
这个标准对控制 instance ID 和 Quantity 数值设置了一些无法被 token class 所有者攻破的限制。
这个 NFT 标准允许在任何时候**无限地创建新的 Token instance **。但是,和 SUDT 有所不同的是,任何 token instance 的数量在创建时都是固定的,以后不能再增加了。
为了确保 instance ID 是惟一的,它的创建使用 seed cell 的模式。这有效地从所有者手中夺走了对 instance ID 的控制权。所有者控制何时创建 Token instance ,但他们不能控制 instance ID 是什么。这时候如果数量完全不受限制,那么这实际上就是否定了前面提到的模式。通过同时限制 instance ID 和数量,这个标准保证了 token instance 是惟一的且不可伪造的,即使是 token class 的所有者。
为什么这个特征是重要的,有个真实世界的案例是可收集的游戏卡《Magic The Gathering》。某些稀有卡片的第一版,对收藏者来说是极其珍贵的。然而,这些稀有卡的伪造品存在,原卡发行者的再版印品也存在。限制 instance ID 和数量可以消除任何恶意伪造的可能性,并确保发行者以后的重新印制版不会被误认为是初始版。
If you are asking how the NFT type script can distinguish between simple or complex transaction inspection used in token logic, I believe the answer is you cannot. There is valid justification for using either in specific conditions.
I was describing another possible variation for handling cells. In CryptoKitties to cats breed to create a third cat. The original two cats are still alive after breeding. This creates a little more complexity in cell management because it is two inputs and three outputs.
As an example, I mention CryptoSpiders as another game. Spiders mate at the end of their lifecycle, and die soon after. It is more simple in cell management because it is two inputs that are consumed, and one output.
This example uses a third NFT egg cell to hatch a new cat. The egg must come from somewhere. A user cannot create it by themselves. When users are playing the game, the website that generates the transactions would automatically give out eggs when needed. This works fine, but this is a centralized solution since all the eggs are under control of the website. Eggs could also be distributed on-chain using a special lock script that has no need for the website. I was indicating that a full decentralized solution is possible under this model, even though I think the more simple centralized solution is sufficient for most.
Very sorry for missing this reply.
First of all, thanks for answering.
Ib those days, I also keep considering such scenarios for NFT also discussing with some community members. Cell management like create new NFT through breeding would be an issue.
Case 1 : I have 100 arrows NFT (the same instance ID ) and want to send 30 arrows to three different players without knowing if they have enough ckbytes or not. Maybe here the Approve cell with the ckb indexer could help.
Case 2 : 2 Cats breed one more kitty.
Well,got aspired by regulation byte,not sure whether it is a solution or not :
regulation_byte: 0b 0 0 0 0 0 0 0 0
| | | └- Global control
| | └--- first generation
| └----- second generation
|
└--------------- 1: Definition / 0: Usage
I know this is a very rough idea for a mother(female) cat which may not be considered very well.
But tbh, spending a little capacity to get a new kitty asset must be a desirable behavior that most player is willing to do. See the timing when gas fees rise up, numerous DeFi players still pay, and fortunately, the ckbyte for NFT occupation still could be redeemed theoretically.
Got it, and if such kinds of demand present in the future,I believe there would be specified NFT spec released based on this RFC like regulation sudt .
Something like the Approve Cell, Anyone Can Pay, or Open Transaction Lock, should be able to help with this.
Using a system like a regulation byte may be beneficial to specify how an NFT Token Class behaves. It could also be used at the application level, which you indicated in your example, but that is up to the developer of the application to define.
I thought up another way the breeding could be handled which is quite simple. In my examples, I always used the Instance ID for the purpose of identifying a specific cat. That doesn’t have to be the case. An Instance ID could represent a generation of cats, a specific series of cats or the developer could choose to ignore the meaning of the Instance ID completely. If they ignore it, then they would need to specify their own identifier in the custom data, but this also gives them the ability to change it any way they need to.
For developers who do not need guaranteed scarcity trait, the ability to change the Instance ID may be beneficial. I think there should be an option for this, but I’m not sure if that should be part of this standard or a separate standard. I will be doing a second NFT standard regardless. There needs to be a second more simple standard that can be more directly compatible with ERC1155.
got it, just realize that instance_id could represent a couple of kitties. That’s cool.
But what it will be if I transfer a baby kitty out of such the series of kitties below to a specific instance ID?
Actually, such kinds of cell capacity management of sUDT or NFT would be an issue deserving to discuss.