dapperlabs / nba-smart-contracts

Smart contracts and transactions for Topshot, the official NBA digital collectibles game on the Flow Blockchain
https://www.nbatopshot.com
The Unlicense
333 stars 105 forks source link

User stories for smart contract MVP #3

Closed zhangchiqing closed 4 years ago

zhangchiqing commented 4 years ago

This is a list of stories or core features for the NBA Smart contract. We need to understand how to implement them in Flow.

  1. I want to authenticate a certain Account to mint tokens, i.e. only COO can mint tokens. Where should the authenticated account address to be stored? Is there any structured logs that can be stored onchain and queried back? Ethereum has Transaction Receipt
  2. I want to emit an event when a token gets minted. How to emit an event with data?
  3. I want the minted token to contain structured data
  4. I want to query the structured data of a minted token
  5. I want to query the owner of a minted token
  6. I want the token to be transferred by the owner to a new owner
  7. I want the owner to give approval to a certain account for transferring their tokens.
  8. I want the NFT to refer to storage data in another contract instead of duplicating data

@chrisaxiom @stevemynett

zhangchiqing commented 4 years ago

1. I want to authenticate a certain Account to mint tokens

In solidity, I can store a COO account address, and implement modifier like onlyCOO to authenticate certain accounts to mint token.

In Flow, can I store a COO account address in the contract storage? The document says only Resouce can be stored in the Account. The question is that is a contract also an "Account"? Does the COO account address have to be stored as a Resource?

zhangchiqing commented 4 years ago

4. I want to query the structured data of a minted token

In solidity, the contract allows you to query the structured data of a token by the token ID. For example, you can query a wizard's power and affinity by exposing the public wizardsById.

Given the fact the wizards (NFT tokens) are Resources stored in owner account's storage, how to query these structured data with only token ID.

zhangchiqing commented 4 years ago

5. I want to query the owner of a minted token

Similar to 4, this is around the discussion of how to implement the ownerOf function

rachelbarclay commented 4 years ago

@zhangchiqing this is great, thanks for starting! if you let me know when you add to this, I can produce user stories and then we will close this out

zhangchiqing commented 4 years ago

Thanks @rachelbarclay . This list is mainly for the discussion with dete.

Since I'm not sure if we have captured all the scope of the smart contract MVP in this list, I don't think we need to create separate user stories issues for them yet before our discussioin with dete.

But will let you know when we have a complete list of it.

rachelbarclay commented 4 years ago

Thanks @zhangchiqing - please let me know when you've talked with Dete.

rachelbarclay commented 4 years ago

@zhangchiqing pls could you assign this task to yourself if you're the one working on it? Thank you!!

zhangchiqing commented 4 years ago

Notes about the meeting with Dete

  1. I want to authenticate a certain Account to mint tokens, i.e. only COO can mint tokens.

One option is to do Ethereum way which stores the COO account address in contract's storage. Another option is to do Resource-model way: Making a Factory class as a Resource, which has a mint function to mint token, the COO account will own that Factory Resource. The Resource ownership ensures only the owner of the Resource have the access to the mint method, which comes with the Resource, to mint token.

Since Flow is deterministic, once a block is sealed, the logs are determined no matter who runs it. With finality supported by Flow, you will have 100% certainty after 10 seconds!!

Follow up question: what if a contract code, which defines the Resource type, gets modified? Answer: we might not allow update in the first release. Or we allow update contract code, but disallow changing Resource type definition. Or if you want to change Resource type definition, you need to explicitly define Resource migrations, just like defining DB migrations.

  1. I want to emit an event when a token gets minted. How to emit an event with data? There will be built-in log functions, which allows developers to log data, and the node will have flag to ignore or to store the logs. The production nodes will have this flag to ignore by default. But developers can turn that flag to store all logs, and run transactions on their own nodes and get all the event logs.

  2. I want the minted token to contain structured data Use struct

  3. I want to query the structured data of a minted token by ID Well, you can't. But a workaround is you can use logs to capture all the fields when a token is minted.

  4. I want to query the owner of a minted token Same as 4, just keep track of all the logs of token movements

  5. I want the token to be transferred by the owner to a new owner Log whenever the ownership changes, in order to do that, you need to: (1) log the initial owner when the token is minted. (2) create a “Collection” Resource that holds all the token Resource, so that the ownership changes can be logged with the code that lives in the code that defines the “Collection” Resource.

Follow up question: How to capture the movement of the “Collection” itself. Dete’s Respond: Good question, let me note it down, and think more on it.

  1. I want the owner to give approval to a certain account for transferring their tokens. Approval can hold a “Provider” Resource, which allows the approver to temporarily hold (own) the Resource. Holding the “Provider” Resource doesn’t mean you 100% have the chance to own the Resource, if the owner no longer has that token Resource, then the getToken call will fail.

  2. I want the NFT to refer to storage data in another contract instead of duplicating data We can have some internal data to be share, Dete needs more time to think about it

zhangchiqing commented 4 years ago

cc @joshuahannan

joshuahannan commented 4 years ago

1. I want to authenticate a certain Account to mint tokens

In solidity, I can store a COO account address, and implement modifier like onlyCOO to authenticate certain accounts to mint token.

In Flow, can I store a COO account address in the contract storage? The document says only Resouce can be stored in the Account. The question is that is a contract also an "Account"? Does the COO account address have to be stored as a Resource?

joshuahannan commented 4 years ago

I am moving these stories to a document where I can more formally add details to them and add new ones: https://docs.google.com/document/d/1C992nE5OYeN1jdqxgUEfxoskLXE-xsrXHBlZbZCPF08/edit#