Zilliqa / ZRC

Zilliqa Reference Contracts
MIT License
40 stars 57 forks source link

[ZRC-6 proposal] Redesigned NFT Standard #98

Closed ghost closed 2 years ago

ghost commented 2 years ago

Description

ZRC-6 defines a new minimum interface of an NFT smart contract while improving upon ZRC-1.

The main advantages of this standard are:

  1. ZRC-6 standardizes royalty information retrieval with a percentage-based royalty fee model and unit-less royalty payments to a single address. Funds will be paid for secondary sales only if a marketplace chooses to implement royalty payments. Marketplace contracts should transfer the actual funds.

  2. ZRC-6 standardizes token URI with the concatenation of base token URI and token ID. A token URI is an HTTP or IPFS URL. This URL must return a JSON blob of data with the metadata for the NFT when queried.

  3. ZRC-6 is designed for remote state read (x <- & c.f) such that logic to get data from a ZRC-6 contract is straightforward. ZRC-6 exposes immutable parameters via mutable fields and includes only transitions that mutate the state of the contract.

  4. ZRC-6 is designed for failure. Therefore minting, burning, and token transfers are pausable.

  5. ZRC-6 features batch operations for minting, burning and token transfers such that only a single transaction is required.

  6. ZRC-6 features a single transition for token transfer with destination validation. The transition can be called by a token owner, a spender, or an operator. ZRC-6 prevents transferring tokens to the zero address or the address of a ZRC-6 contract.

  7. ZRC-6 is compatible with ZRC-X since every callback name is prefixed with ZRC6_.

Motivation

  1. Many of the largest NFT marketplaces have implemented incompatible royalty payment solutions.

  2. The marketplace builders had to handle inconsistent token URIs.

  3. Using callbacks to get data can complicate the logic easily. Unlike immutable parameters, mutable fields are available for remote state read.

  4. Without an emergency stop mechanism, it's hard to respond to bugs and vulnerabilities gracefully.

  5. Without batch operations, it can be very inefficient to transfer or mint multiple tokens with multiple transactions.

  6. ZRC-1 includes Transfer and TransferFrom for the token transfer. The two transitions have the same type signature and the only difference is the access control. This has added unnecessary complexity. ZRC-1 does not validate the destination for token transfer and it is not safe.

  7. The ZRC-1 and ZRC-2 contracts can share the same callback names. Contracts must have unique names for callback transitions.

How to run contract tests

Zilliqa Isolated Server Container

The Isolated Server container image is available from Docker Hub since Oct 6, 2021. I asked for it to be public so that developers can easily use it for contract testing.

To run Isolated Server Container, use this command:

docker run -d -p 5555:5555 \
  --name isolated-server \
  isolated-server:1.0

For more details, visit here

Tests in Parallel

To run contract tests in parallel with Jest, you can set maxWorkers and use genesis account per worker.

This can reduce the test duration significantly when you are running a large test suite.

References

ghost commented 2 years ago

@renlulu Good question.

In favor of the Remote Fetch, I will only keep the read-only transitions that contain important logic (e.g. calculate royalty amount):

Also, to retrieve the immutable parameters I've added token_name and token_symbol fields for remote fetch. With this approach, the transitions that provide the immutable parameter, are removed:

teye commented 2 years ago

One thing I am curious about is the standardization of TransferFrom. So for existing wallet developers such as ZilPay, would it be difficult for them to support both ZRC-1 and ZRC-6 NFT since ZRC-6 transfer is not backward compatible with ZRC-1?

ghost commented 2 years ago

For ZRC-6 the great design is the highest value. We redesigned the contract and backward compatibility is not expected.

Transfer of ZRC-1 is unnecessary and only complicates things. Therefore, we should not support it.

ghost commented 2 years ago

After internal discussion, we decide to drop RoyaltyInfo and TokenURI transitions. callback is the only way to get the result from the transition and using callbacks can complicate logic easily in other contracts. e.g. marketplace contracts.

Although we can have a stricter standard by using the transitions, we value simplicity more. Therefore we use remote fetch for the royalty information and token URI retrieval.

bb111189 commented 2 years ago

Do you think we should add BatchTransfer as optional transition?

ghost commented 2 years ago

Yes, I think we should add BatchTransferFrom since we decided to include BatchMint