Git Product home page Git Product logo

cep-78-enhanced-nft's Introduction

CEP-78: Enhanced NFT standard

Design Goals

  • DApp developers attempting to create an NFT contract should be able to install the contract as is configured for the specific built-in behavior they want their NFT contract instance to have. Must work out of the box.
  • Reference implementation must be straightforward, clear, and obvious.
  • Externally observable association between Accounts and/or Contracts and NFTs they "own".
  • Should be well documented with exhaustive tests that prove all possible combinations of defined behavior work as intended.
  • Must be entirely self-contained within a singular repo; this includes all code, all tests, all relevant CasperLabs provided SDKs and all relevant documentation.
  • Must support mainstream expectations about common NFT conventions.
  • A given NFT contract instance must be able to choose when created if it is using a Metadata schema conformant with existing community standards or a specific custom schema that they provide.
  • A NFT contract instance must validate provided metadata against the specified metadata schema for that contract.
  • Standardized session code to interact with an NFT contract instance must be usable as is, so that a given DApp developer doesn't have to write any Wasm producing logic for normal usage of NFT contract instances produced by this contract.

New in Version 1.5

Please refer to the release notes

Table of Contents

  1. Usage

  2. Installing and Interacting with CEP-78 Contracts using the Rust Casper Client

  3. Test Suite and Specification

  4. Error Codes

Usage

Building the Contract

The main.rs file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the make build-contract command from the Makefile provided.

The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the make build-contract command provided in the Makefile. Please note, however, that you must install wasm-strip to build the contract.

The call method will install the contract with the necessary entrypoints and call the init() entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation.

Required Runtime Arguments

The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the Modalities documentation.

  • "collection_name": The name of the NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
  • "collection_symbol": The symbol representing a given NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
  • "total_token_supply": The total number of NFTs that a specific instance of a contract will mint passed in as a U64 value. This parameter is required.
  • "ownership_mode": The OwnershipMode modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
  • "json_schema": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a String. This parameter is required if the metadata kind is set to CustomValidated(3) and cannot be changed post installation.
  • "nft_metadata_kind": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
  • "identifier_mode": The NFTIdentifierMode modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a u8 value and is required at the time of installation.
  • "metadata_mutability": The MetadataMutability modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a u8 value and is required at the time of installation.

The following are the optional parameters that can be passed in at the time of installation.

  • "minting_mode": The MintingMode modality that dictates the access to the mint() entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed.
  • "allow_minting": The "allow_minting" flag allows the installer of the contract to pause the minting of new NFTs. The allow_minting is a boolean toggle that allows minting when true. If not provided at install the toggle will default to true. This value can be changed by the installer by calling the set_variables() entrypoint.
  • "nft_kind": The NFTKind modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a u8 value and is optional at the time of installation. If not provided at install the toggle will default to Virtual This parameter cannot be changed once the contract has been installed.
  • "whitelist_mode": The WhitelistMode modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed.
  • "holder_mode": The NFTHolderMode modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either Accounts or Contracts to hold NFTs. This parameter cannot be changed once the contract has been installed.
  • "acl_whitelist": The ACL whitelist is a list of accounts and/or contract/package hashes that specifies which accounts and/or contracts can call the mint() entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the set_variables post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail.
  • "burn_mode": The BurnMode modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.
  • "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.
  • "events_mode": The EventsMode modality selects the event schema used to record any changes that occur to tokens issued by the contract instance.
  • "additional_required_metdata": An additional metadata schema that must be included. This argument is passed in as a u8 value.
  • "optional_metdata": An optional metadata schema that may be included. This argument is passed in as a u8 value.

Example deploy

The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

casper-client put-deploy -n https://rpc.testnet.casperlabs.io/ --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
--session-arg "collection_name:string='enhanced-nft-1'" \
--session-arg "collection_symbol:string='ENFT-1'" \
--session-arg "total_token_supply:u64='10'" \
--session-arg "ownership_mode:u8='0'" \
--session-arg "nft_kind:u8='1'" \
--session-arg "json_schema:string='nft-schema'" \
--session-arg "allow_minting:bool='true'" \
--session-arg "owner_reverse_lookup_mode:u8='0'" \
--session-arg "nft_metadata_kind:u8='2'" \
--session-arg "identifier_mode:u8='0'" \
--session-arg "metadata_mutability:u8='1'"

Utility Session Code

Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary. In order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that users and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the client folder within the project folder.

Entrypoint name Session code
"mint" client/mint_session
"balance_of" client/balance_of_session
"get_approved client/get_approved_session
"owner_of" client/owner_of_session
"transfer" client/transfer_session

Checking Token Ownership

Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

Upgrading to Version 1.1.1

Upgrade to v1.1.1 using a Standard NamedKey Convention or a Custom NamedKey Convention.

Installing and Interacting with the Contract using the Rust Casper Client

You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

Test Suite and Specification

The expected behavior of the NFT contract implementation is asserted by its test suite found in the tests folder. The test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors of the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite ensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced. The test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run by using the provided Makefile and running the make test command.

Error Codes

Code Error
1 InvalidAccount
2 MissingInstaller
3 InvalidInstaller
4 UnexpectedKeyVariant
5 MissingTokenOwner
6 InvalidTokenOwner
7 FailedToGetArgBytes
8 FailedToCreateDictionary
9 MissingStorageUref
10 InvalidStorageUref
11 MissingOwnerUref
12 InvalidOwnersUref
13 FailedToAccessStorageDictionary
14 FailedToAccessOwnershipDictionary
15 DuplicateMinted
16 FailedToConvertCLValue
17 MissingCollectionName
18 InvalidCollectionName
19 FailedToSerializeMetaData
20 MissingAccount
21 MissingMintingStatus
22 InvalidMintingStatus
23 MissingCollectionSymbol
24 InvalidCollectionSymbol
25 MissingTotalTokenSupply
26 InvalidTotalTokenSupply
27 MissingTokenID
28 InvalidTokenIdentifier
29 MissingTokenOwners
30 MissingAccountHash
31 InvalidAccountHash
32 TokenSupplyDepleted
33 MissingOwnedTokensDictionary
34 TokenAlreadyBelongsToMinterFatal
35 FatalTokenIdDuplication
36 InvalidMinter
37 MissingMintingMode
38 InvalidMintingMode
39 MissingInstallerKey
40 FailedToConvertToAccountHash
41 InvalidBurner
42 PreviouslyBurntToken
43 MissingAllowMinting
44 InvalidAllowMinting
45 MissingNumberOfMintedTokens
46 InvalidNumberOfMintedTokens
47 MissingTokenMetaData
48 InvalidTokenMetaData
49 MissingApprovedAccountHash
50 InvalidApprovedAccountHash
51 MissingApprovedTokensDictionary
52 TokenAlreadyApproved
53 MissingApproveAll
54 InvalidApproveAll
55 MissingOperator
56 InvalidOperator
57 Phantom
58 ContractAlreadyInitialized
59 MintingIsPaused
60 FailureToParseAccountHash
61 VacantValueInDictionary
62 MissingOwnershipMode
63 InvalidOwnershipMode
64 InvalidTokenMinter
65 MissingOwnedTokens
66 InvalidAccountKeyInDictionary
67 MissingJsonSchema
68 InvalidJsonSchema
69 InvalidKey
70 InvalidOwnedTokens
71 MissingTokenURI
72 InvalidTokenURI
73 MissingNftKind
74 InvalidNftKind
75 MissingHolderMode
76 InvalidHolderMode
77 MissingWhitelistMode
78 InvalidWhitelistMode
79 MissingContractWhiteList
80 InvalidContractWhitelist
81 UnlistedContractHash
82 InvalidContract
83 EmptyContractWhitelist
84 MissingReceiptName
85 InvalidReceiptName
86 InvalidJsonMetadata
87 InvalidJsonFormat
88 FailedToParseCep78Metadata
89 FailedToParse721Metadata
90 FailedToParseCustomMetadata
91 InvalidCEP78Metadata
92 FailedToJsonifyCEP78Metadata
93 InvalidNFT721Metadata
94 FailedToJsonifyNFT721Metadata
95 InvalidCustomMetadata
96 MissingNFTMetadataKind
97 InvalidNFTMetadataKind
98 MissingIdentifierMode
99 InvalidIdentifierMode
100 FailedToParseTokenId
101 MissingMetadataMutability
102 InvalidMetadataMutability
103 FailedToJsonifyCustomMetadata
104 ForbiddenMetadataUpdate
105 MissingBurnMode
106 InvalidBurnMode
107 MissingHashByIndex
108 InvalidHashByIndex
109 MissingIndexByHash
110 InvalidIndexByHash
111 MissingPageTableURef
112 InvalidPageTableURef
113 MissingPageLimit
114 InvalidPageLimit
115 InvalidPageNumber
116 InvalidPageIndex
117 MissingUnmatchedHashCount
118 InvalidUnmatchedHashCount
119 MissingPackageHashForUpgrade
120 MissingPageUref
121 InvalidPageUref
122 CannotUpgradeWithZeroSupply
123 CannotInstallWithZeroSupply
124 MissingMigrationFlag
125 InvalidMigrationFlag
126 ContractAlreadyMigrated
127 UnregisteredOwnerInMint
128 UnregisteredOwnerInTransfer
129 MissingReportingMode
130 InvalidReportingMode
131 MissingPage
132 UnregisteredOwnerFromMigration
133 ExceededMaxTotalSupply
134 MissingCep78PackageHash
135 InvalidCep78InvalidHash
136 InvalidPackageHashName
137 InvalidAccessKeyName
138 InvalidCheckForUpgrade
139 InvalidNamedKeyConvention
140 OwnerReverseLookupModeNotTransferable
141 InvalidAdditionalRequiredMetadata
142 InvalidOptionalMetadata
143 MissingOptionalNFTMetadataKind
144 InvalidOptionalNFTMetadataKind
145 MissingAdditionalNFTMetadataKind
146 InvalidAdditionalNFTMetadataKind
147 InvalidRequirement
148 MissingEventsMode
149 InvalidEventsMode
150 CannotUpgradeToMoreSupply
151 MissingOperatorDict
152 MissingApprovedDict
153 MissingSpenderAccountHash
154 InvalidSpenderAccountHash
155 MissingOwnerTokenIdentifierKey
156 InvalidTransferFilterContract
157 MissingTransferFilterContract
158 TransferFilterContractNeedsTransferableMode
159 TransferFilterContractDenied
160 MissingACLWhiteList
161 InvalidACLWhitelist
162 EmptyACLWhitelist
163 InvalidACLPackageMode
164 MissingACLPackageMode
165 InvalidPackageOperatorMode
166 MissingPackageOperatorMode
167 InvalidOperatorBurnMode
168 MissingOperatorBurnMode
169 InvalidIdentifier
170 DuplicateIdentifier

cep-78-enhanced-nft's People

Contributors

acstonecl avatar cryofracture avatar darthsiroftardis avatar davidatwhiletrue avatar deuszex avatar dylanireland avatar edhastingscasperassociation avatar euanmcf-cl avatar groussac avatar gskerry avatar hanswestman74 avatar hoffmannjan avatar ipopescu avatar jekennedy avatar jonas089 avatar mssteuer avatar tomvasile avatar zhmakas avatar zie1ony avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cep-78-enhanced-nft's Issues

Whitelisting Support

Update the CEP 78 contract: Create a new modality for minting called "limited". This can be used to support whitelisting capabilities in either the contract or account.

Update CI/CD to publish npm package

To support the updated SDK for CEP-78, we need to include npm - possibly other libraries. Please work with the engineers to ensure the pipeline is updated to include all dependencies.

Check for burnt tokens in set_approve_all

Currently the only problem we identify is that set_approve_all function has missing entry point parameters, and also it does not check if a token is burnt or not, but we didn't see any high security issue with this.

init() entry point lacks 2 parameters. Only 14/16 are defined => error when calling metadata() and other.

When calling the metadata() function an error is raised that says the NFT_METADATA_KIND is not set.
METADATA_MUTABILITY is also not found in storage.
I think I have identified the reason for this issue and will try to resolve it.
The attached screenshots show that the 2 missing parameters are passed to the init() function, but are not defined as parameters for the init() entry point => this explains why they are not set.
I test my fix tomorrow and propose a commit.

1662415712953
1662415694775

CEP47 => CEP78

Objective - The objective of this epic is to analyse, and create example code and scripts for teams to migrate from cep-47-nft to cep-78-enhanced-nft.

Following are the related tickets created and will be tracked as part of this epic.
Note - There are two possible migration strategies that require a detailed feasibility study as part of this epic/plan.

  1. Vanilla cep-47-nft to Vanilla(Enhanced) cep-78-enhanced-nft migration
  2. Custom cep-47-nft to Enhanced cep-78-enhanced-nft

V1.1 - CEP-78 Gas Cost Stabilization

gas cost of minting tokens should be consistent regardless of how many have previously been minted; currently the costs can be cumulative due to ownership tracking implementation details.

Produce a design specification for `cep-78`

Objective - Solution Architect(s) to produce a design specification for the implementation of cep-78

Definition of Done - Create a design specification that can be referred and used by developers and other teams to build their NFT solution using the cep-78 standard.

Amend transfer function in the NFT contract to provide a read only reference

Problem Statement - Currently, there is a gap in the Assigned and Transfer mode, where the owner of an NFT token doesn't obtain the read-only reference they would if they minted it themselves.
Solution - The transfer function should additionally send the read-only reference allowing users to "claim" their NFT.

CEP78 -NFTIdentifierMode - 'UserDefined'

ordinal, hash - add another "let me decide".

use case: token already has an id in production that does not conform to ordinal or hash.

NEEDS FURTHER IDEATION

Multiple Metadata (Contract Modality)

Provide contract compatibility for multiple, simultaneous consumers - via a modality for multiple metadata schemas at once (for the same contract).

i.e. extension of nftmetadatakind to support multiple schemas.

TBD:
Configuration settings around Required, Optional, Default.

Add metadata and schema enforcement to the enhanced NFT standard

Update the NFT contract to allow users to specify a schema and provide the functionality to enforce that a minted token's metadata conforms to the schema. Additionally, introduce and implement the MetadataMutability modality that allows users to modify (or prevent) the metadata.

Multiple Metadata (Contract Modality)

Provide contract compatibility for multiple, simultaneous consumers - via a modality for multiple metadata schemas at once (for the same contract).

i.e. extension of nftmetadatakind to support multiple schemas.

TBD:
Configuration settings around Required, Optional, Default.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.